summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorTom Rini <[email protected]>2023-10-12 08:15:31 -0400
committerTom Rini <[email protected]>2023-10-12 08:15:31 -0400
commitf9a47ac8d97da2b3aaf463f268a9a872a8d921df (patch)
tree0a67c8aa5bd018d376f8073147cea33c6772861b /include
parent429d59c3e5e6a3d3d6cd9f3c59c075e9037459c0 (diff)
parent7e5b637483e03ce303ce84ec6b24156c6658ef46 (diff)
Merge branch '2023-10-12-expo-add-support-for-edting-lines-of-text'
To quote the author: So far expo only supports menus. These are quite flexible for various kinds of settings, but cannot deal with free-form input, such as a serial number or a machine name. This series adds support for a textline object, which is a single line of text. It has a maximum length and its value is stored within the expo structure. U-Boot already has a command-line editor which provides most of the features needed by expo. But the code runs in its own loop and only returns when the line is finished. This is not suitable for expo, which must handle a keypress at a time, returning to its caller after each one. In order to use the CLI code, some significant refactoring is included here. This mostly involves moving the internal loop of the CLI to a separate function and recording its state in a struct, just as was done for single keypresses some time back. A minor addition is support for Ctrl-W to delete a word, since strangely this is currently only present in the simple version. The video-console system provides most of the features needed by testline, but a few things are missing. This series provides: - primitive cursor support so the user can see where he is typing - saving and restoring of the text-entry context, so that expo can allow the user to continue where he left off, including deleting previously entered characters correctly (for Truetype) - obtaining the nominal width of a string of n characters, so that a suitable width can be chosen for the textline object Note that no support is provided for clearing the cursor. This was addressed in a previous series[1] which could perhaps be rebased. For this implementation, the cursor is therefore not enabled for the normal command line, only for expo. Reading and writing textline objects is supported for FDT and environment, but not for CMOS RAM, since it would likely use too much RAM to store a string. In terms of code size, the overall size increase is 180 bytes for Thumb02 boards, 160 of whcih is the addition of Ctrl-W to delete a word. [1] https://patchwork.ozlabs.org/project/uboot/list/?series=280178&state=*
Diffstat (limited to 'include')
-rw-r--r--include/cli.h51
-rw-r--r--include/command.h6
-rw-r--r--include/expo.h60
-rw-r--r--include/menu.h7
-rw-r--r--include/test/cedit-test.h5
-rw-r--r--include/video_console.h123
6 files changed, 249 insertions, 3 deletions
diff --git a/include/cli.h b/include/cli.h
index 094a6602d70..e183d561369 100644
--- a/include/cli.h
+++ b/include/cli.h
@@ -8,6 +8,7 @@
#define __CLI_H
#include <stdbool.h>
+#include <linux/types.h>
/**
* struct cli_ch_state - state information for reading cmdline characters
@@ -25,6 +26,29 @@ struct cli_ch_state {
};
/**
+ * struct cli_line_state - state of the line editor
+ *
+ * @num: Current cursor position, where 0 is the start
+ * @eol_num: Number of characters in the buffer
+ * @insert: true if in 'insert' mode
+ * @history: true if history should be accessible
+ * @cmd_complete: true if tab completion should be enabled (requires @prompt to
+ * be set)
+ * @buf: Buffer containing line
+ * @prompt: Prompt for the line
+ */
+struct cli_line_state {
+ uint num;
+ uint eol_num;
+ uint len;
+ bool insert;
+ bool history;
+ bool cmd_complete;
+ char *buf;
+ const char *prompt;
+};
+
+/**
* Go into the command loop
*
* This will return if we get a timeout waiting for a command. See
@@ -229,4 +253,31 @@ void cli_ch_init(struct cli_ch_state *cch);
*/
int cli_ch_process(struct cli_ch_state *cch, int ichar);
+/**
+ * cread_line_process_ch() - Process a character for line input
+ *
+ * @cls: CLI line state
+ * @ichar: Character to process
+ * Return: 0 if input is complete, with line in cls->buf, -EINTR if input was
+ * cancelled with Ctrl-C, -EAGAIN if more characters are needed
+ */
+int cread_line_process_ch(struct cli_line_state *cls, char ichar);
+
+/**
+ * cli_cread_init() - Set up a new cread struct
+ *
+ * Sets up a new cread state, with history and cmd_complete set to false
+ *
+ * After calling this, you can use cread_line_process_ch() to process characters
+ * received from the user.
+ *
+ * @cls: CLI line state
+ * @buf: Text buffer containing the initial text
+ * @buf_size: Buffer size, including nul terminator
+ */
+void cli_cread_init(struct cli_line_state *cls, char *buf, uint buf_size);
+
+/** cread_print_hist_list() - Print the command-line history list */
+void cread_print_hist_list(void);
+
#endif
diff --git a/include/command.h b/include/command.h
index 34ea989b39b..1c4ec4257a5 100644
--- a/include/command.h
+++ b/include/command.h
@@ -95,6 +95,12 @@ int var_complete(int argc, char *const argv[], char last_char, int maxv,
char *cmdv[]);
int cmd_auto_complete(const char *const prompt, char *buf, int *np,
int *colp);
+#else
+static inline int cmd_auto_complete(const char *const prompt, char *buf,
+ int *np, int *colp)
+{
+ return 0;
+}
#endif
/**
diff --git a/include/expo.h b/include/expo.h
index 9d2e817eb97..264745f7f01 100644
--- a/include/expo.h
+++ b/include/expo.h
@@ -7,11 +7,14 @@
#ifndef __EXPO_H
#define __EXPO_H
+#include <abuf.h>
#include <dm/ofnode_decl.h>
#include <linux/list.h>
struct udevice;
+#include <cli.h>
+
/**
* enum expoact_type - types of actions reported by the expo
*
@@ -121,6 +124,9 @@ struct expo_string {
* @id: ID number of the scene
* @title_id: String ID of title of the scene (allocated)
* @highlight_id: ID of highlighted object, if any
+ * @cls: cread state to use for input
+ * @buf: Buffer for input
+ * @entry_save: Buffer to hold vidconsole text-entry information
* @sibling: Node to link this scene to its siblings
* @obj_head: List of objects in the scene
*/
@@ -130,6 +136,9 @@ struct scene {
uint id;
uint title_id;
uint highlight_id;
+ struct cli_line_state cls;
+ struct abuf buf;
+ struct abuf entry_save;
struct list_head sibling;
struct list_head obj_head;
};
@@ -141,12 +150,16 @@ struct scene {
* @SCENEOBJT_IMAGE: Image data to render
* @SCENEOBJT_TEXT: Text line to render
* @SCENEOBJT_MENU: Menu containing items the user can select
+ * @SCENEOBJT_TEXTLINE: Line of text the user can edit
*/
enum scene_obj_t {
SCENEOBJT_NONE = 0,
SCENEOBJT_IMAGE,
SCENEOBJT_TEXT,
+
+ /* types from here on can be highlighted */
SCENEOBJT_MENU,
+ SCENEOBJT_TEXTLINE,
};
/**
@@ -178,6 +191,11 @@ enum scene_obj_flags_t {
SCENEOF_OPEN = 1 << 2,
};
+enum {
+ /* Maximum number of characters allowed in an line editor */
+ EXPO_MAX_CHARS = 250,
+};
+
/**
* struct scene_obj - information about an object in a scene
*
@@ -203,6 +221,12 @@ struct scene_obj {
struct list_head sibling;
};
+/* object can be highlighted when moving around expo */
+static inline bool scene_obj_can_highlight(const struct scene_obj *obj)
+{
+ return obj->type >= SCENEOBJT_MENU;
+}
+
/**
* struct scene_obj_img - information about an image object in a scene
*
@@ -297,6 +321,27 @@ struct scene_menitem {
};
/**
+ * struct scene_obj_textline - information about a textline in a scene
+ *
+ * A textline has a prompt and a line of editable text
+ *
+ * @obj: Basic object information
+ * @label_id: ID of the label text, or 0 if none
+ * @edit_id: ID of the editable text
+ * @max_chars: Maximum number of characters allowed
+ * @buf: Text buffer containing current text
+ * @pos: Cursor position
+ */
+struct scene_obj_textline {
+ struct scene_obj obj;
+ uint label_id;
+ uint edit_id;
+ uint max_chars;
+ struct abuf buf;
+ uint pos;
+};
+
+/**
* expo_new() - create a new expo
*
* Allocates a new expo
@@ -505,7 +550,7 @@ int scene_txt(struct scene *scn, const char *name, uint id, uint str_id,
struct scene_obj_txt **txtp);
/**
- * scene_txt_str() - add a new string to expr and text object to a scene
+ * scene_txt_str() - add a new string to expo and text object to a scene
*
* @scn: Scene to update
* @name: Name to use (this is allocated by this call)
@@ -531,6 +576,19 @@ int scene_menu(struct scene *scn, const char *name, uint id,
struct scene_obj_menu **menup);
/**
+ * scene_textline() - create a textline
+ *
+ * @scn: Scene to update
+ * @name: Name to use (this is allocated by this call)
+ * @id: ID to use for the new object (0 to allocate one)
+ * @max_chars: Maximum length of the textline in characters
+ * @tlinep: If non-NULL, returns the new object
+ * Returns: ID number for the object (typically @id), or -ve on error
+ */
+int scene_textline(struct scene *scn, const char *name, uint id, uint max_chars,
+ struct scene_obj_textline **tlinep);
+
+/**
* scene_txt_set_font() - Set the font for an object
*
* @scn: Scene to update
diff --git a/include/menu.h b/include/menu.h
index 64ce89b7d26..6571c39b143 100644
--- a/include/menu.h
+++ b/include/menu.h
@@ -50,12 +50,17 @@ enum bootmenu_key {
BKEY_DOWN,
BKEY_SELECT,
BKEY_QUIT,
+ BKEY_SAVE,
+
+ /* 'extra' keys, which are used by menus but not cedit */
BKEY_PLUS,
BKEY_MINUS,
BKEY_SPACE,
- BKEY_SAVE,
BKEY_COUNT,
+
+ /* Keys from here on are not used by cedit */
+ BKEY_FIRST_EXTRA = BKEY_PLUS,
};
/**
diff --git a/include/test/cedit-test.h b/include/test/cedit-test.h
index 349df75b16d..475ecc9c2dc 100644
--- a/include/test/cedit-test.h
+++ b/include/test/cedit-test.h
@@ -24,6 +24,9 @@
#define ID_AC_ON 11
#define ID_AC_MEMORY 12
-#define ID_DYNAMIC_START 13
+#define ID_MACHINE_NAME 13
+#define ID_MACHINE_NAME_EDIT 14
+
+#define ID_DYNAMIC_START 15
#endif
diff --git a/include/video_console.h b/include/video_console.h
index 2694e44f6ec..bde67fa9a5a 100644
--- a/include/video_console.h
+++ b/include/video_console.h
@@ -8,6 +8,7 @@
#include <video.h>
+struct abuf;
struct video_priv;
#define VID_FRAC_DIV 256
@@ -15,6 +16,11 @@ struct video_priv;
#define VID_TO_PIXEL(x) ((x) / VID_FRAC_DIV)
#define VID_TO_POS(x) ((x) * VID_FRAC_DIV)
+enum {
+ /* cursor width in pixels */
+ VIDCONSOLE_CURSOR_WIDTH = 2,
+};
+
/**
* struct vidconsole_priv - uclass-private data about a console device
*
@@ -224,6 +230,60 @@ struct vidconsole_ops {
*/
int (*measure)(struct udevice *dev, const char *name, uint size,
const char *text, struct vidconsole_bbox *bbox);
+
+ /**
+ * nominal() - Measure the expected width of a line of text
+ *
+ * Uses an average font width and nominal height
+ *
+ * @dev: Console device to use
+ * @name: Font name, NULL for default
+ * @size: Font size, ignored if @name is NULL
+ * @num_chars: Number of characters to use
+ * @bbox: Returns nounding box of @num_chars characters
+ * Returns: 0 if OK, -ve on error
+ */
+ int (*nominal)(struct udevice *dev, const char *name, uint size,
+ uint num_chars, struct vidconsole_bbox *bbox);
+
+ /**
+ * entry_save() - Save any text-entry information for later use
+ *
+ * Saves text-entry context such as a list of positions for each
+ * character in the string.
+ *
+ * @dev: Console device to use
+ * @buf: Buffer to hold saved data
+ * Return: 0 if OK, -ENOMEM if out of memory
+ */
+ int (*entry_save)(struct udevice *dev, struct abuf *buf);
+
+ /**
+ * entry_restore() - Restore text-entry information for current use
+ *
+ * Restores text-entry context such as a list of positions for each
+ * character in the string.
+ *
+ * @dev: Console device to use
+ * @buf: Buffer containing data to restore
+ * Return: 0 if OK, -ve on error
+ */
+ int (*entry_restore)(struct udevice *dev, struct abuf *buf);
+
+ /**
+ * set_cursor_visible() - Show or hide the cursor
+ *
+ * Shows or hides a cursor at the current position
+ *
+ * @dev: Console device to use
+ * @visible: true to show the cursor, false to hide it
+ * @x: X position in pixels
+ * @y: Y position in pixels
+ * @index: Character position (0 = at start)
+ * Return: 0 if OK, -ve on error
+ */
+ int (*set_cursor_visible)(struct udevice *dev, bool visible,
+ uint x, uint y, uint index);
};
/* Get a pointer to the driver operations for a video console device */
@@ -264,6 +324,60 @@ int vidconsole_measure(struct udevice *dev, const char *name, uint size,
const char *text, struct vidconsole_bbox *bbox);
/**
+ * vidconsole_nominal() - Measure the expected width of a line of text
+ *
+ * Uses an average font width and nominal height
+ *
+ * @dev: Console device to use
+ * @name: Font name, NULL for default
+ * @size: Font size, ignored if @name is NULL
+ * @num_chars: Number of characters to use
+ * @bbox: Returns nounding box of @num_chars characters
+ * Returns: 0 if OK, -ve on error
+ */
+int vidconsole_nominal(struct udevice *dev, const char *name, uint size,
+ uint num_chars, struct vidconsole_bbox *bbox);
+
+/**
+ * vidconsole_entry_save() - Save any text-entry information for later use
+ *
+ * Saves text-entry context such as a list of positions for each
+ * character in the string.
+ *
+ * @dev: Console device to use
+ * @buf: Buffer to hold saved data
+ * Return: 0 if OK, -ENOMEM if out of memory
+ */
+int vidconsole_entry_save(struct udevice *dev, struct abuf *buf);
+
+/**
+ * entry_restore() - Restore text-entry information for current use
+ *
+ * Restores text-entry context such as a list of positions for each
+ * character in the string.
+ *
+ * @dev: Console device to use
+ * @buf: Buffer containing data to restore
+ * Return: 0 if OK, -ve on error
+ */
+int vidconsole_entry_restore(struct udevice *dev, struct abuf *buf);
+
+/**
+ * vidconsole_set_cursor_visible() - Show or hide the cursor
+ *
+ * Shows or hides a cursor at the current position
+ *
+ * @dev: Console device to use
+ * @visible: true to show the cursor, false to hide it
+ * @x: X position in pixels
+ * @y: Y position in pixels
+ * @index: Character position (0 = at start)
+ * Return: 0 if OK, -ve on error
+ */
+int vidconsole_set_cursor_visible(struct udevice *dev, bool visible,
+ uint x, uint y, uint index);
+
+/**
* vidconsole_push_colour() - Temporarily change the font colour
*
* @dev: Device to adjust
@@ -321,6 +435,15 @@ int vidconsole_move_rows(struct udevice *dev, uint rowdst, uint rowsrc,
int vidconsole_set_row(struct udevice *dev, uint row, int clr);
/**
+ * vidconsole_entry_start() - Set the start position of a vidconsole line
+ *
+ * Marks the current cursor position as the start of a line
+ *
+ * @dev: Device to adjust
+ */
+int vidconsole_entry_start(struct udevice *dev);
+
+/**
* vidconsole_put_char() - Output a character to the current console position
*
* Outputs a character to the console and advances the cursor. This function