
From: Simon Glass <sjg@chromium.org> Add a new mark_start() method for the console, which indicates that the CLI prompt has been written to the display and any following characters will be user input. There are two cases to consider, tracked by an indent flag in struct vidconsole_cursor: - normal CLI entry where new lines start at the left of the console - expo entry where new lines start at the same position as the previous line (indent=true) Record this position in the uclass info, so it is available to console drivers. Signed-off-by: Simon Glass <sjg@chromium.org> --- common/cli_readline.c | 5 ++++ drivers/video/vidconsole-uclass.c | 39 +++++++++++++++++++++++++++ include/video_console.h | 44 +++++++++++++++++++++++++++++++ 3 files changed, 88 insertions(+) diff --git a/common/cli_readline.c b/common/cli_readline.c index 2326e4b4f37..dc27a962e9d 100644 --- a/common/cli_readline.c +++ b/common/cli_readline.c @@ -16,6 +16,7 @@ #include <pager.h> #include <time.h> #include <watchdog.h> +#include <video_console.h> #include <linux/errno.h> #include <asm/global_data.h> @@ -676,6 +677,8 @@ int cli_readline_into_buffer(const char *const prompt, char *buffer, if (prompt) puts(prompt); + /* tell the vidconsole the cursor is at its start position */ + vidconsole_readline_start(false); rc = cread_line(prompt, p, &len, timeout); rc = rc < 0 ? rc : len; @@ -686,5 +689,7 @@ int cli_readline_into_buffer(const char *const prompt, char *buffer, pager_set_bypass(gd_pager(), old_bypass); pager_reset(gd_pager()); + vidconsole_readline_end(); + return rc; } diff --git a/drivers/video/vidconsole-uclass.c b/drivers/video/vidconsole-uclass.c index 830e3ca306e..0a7cf5ad81a 100644 --- a/drivers/video/vidconsole-uclass.c +++ b/drivers/video/vidconsole-uclass.c @@ -761,6 +761,25 @@ int vidconsole_set_cursor_visible(struct udevice *dev, bool visible, } #endif /* CONFIG_CURSOR */ +int vidconsole_mark_start(struct udevice *dev) +{ + struct vidconsole_priv *priv = dev_get_uclass_priv(dev); + struct vidconsole_ops *ops = vidconsole_get_ops(dev); + + priv->xmark_frac = priv->xcur_frac; + priv->ymark = priv->ycur; + priv->cli_index = 0; + if (ops->mark_start) { + int ret; + + ret = ops->mark_start(dev); + if (ret != -ENOSYS) + return ret; + } + + return 0; +} + void vidconsole_push_colour(struct udevice *dev, enum colour_idx fg, enum colour_idx bg, struct vidconsole_colour *old) { @@ -884,3 +903,23 @@ void vidconsole_set_bitmap_font(struct udevice *dev, void vidconsole_idle(struct udevice *dev) { } + +#ifdef CONFIG_CURSOR +void vidconsole_readline_start(bool indent) +{ + struct uclass *uc; + struct udevice *dev; + + uclass_id_foreach_dev(UCLASS_VIDEO_CONSOLE, dev, uc) { + struct vidconsole_priv *priv = dev_get_uclass_priv(dev); + + priv->curs.indent = indent; + vidconsole_mark_start(dev); + } +} + +void vidconsole_readline_end(void) +{ + /* TODO: mark the end */ +} +#endif /* CURSOR */ diff --git a/include/video_console.h b/include/video_console.h index 5074880c674..c5450f70c4d 100644 --- a/include/video_console.h +++ b/include/video_console.h @@ -30,6 +30,7 @@ enum { * vertical bar of width VIDCONSOLE_CURSOR_WIDTH shown in the foreground colour. * * @visible: cursor is currently visible + * @indent: indent subsequent lines to the same position as the first line * @x: cursor left X position in pixels * @y: cursor top Y position in pixels * @height: height of cursor in pixels @@ -37,6 +38,7 @@ enum { */ struct vidconsole_cursor { bool visible; + bool indent; /* filled in by get_cursor_info(): */ uint x; @@ -70,6 +72,8 @@ struct vidconsole_cursor { * @xsize_frac: Width of the display in fractional units * @xstart_frac: Left margin for the text console in fractional units * @last_ch: Last character written to the text console on this line + * @xmark_frac: X position of start of CLI text entry, in fractional units + * @ymark: Y position of start of CLI text * @cli_index: Character index into the CLI text (0=start) * @escape: TRUE if currently accumulating an ANSI escape sequence * @escape_len: Length of accumulated escape sequence so far @@ -92,6 +96,8 @@ struct vidconsole_priv { int xsize_frac; int xstart_frac; int last_ch; + int xmark_frac; + int ymark; int cli_index; /* * ANSI escape sequences are accumulated character by character, @@ -345,6 +351,17 @@ struct vidconsole_ops { */ int (*get_cursor_info)(struct udevice *dev, bool visible, uint x, uint y, uint index); + + /** + * mark_start() - Mark the current position as the state of CLI entry + * + * This indicates that a new CLI entry is starting, so the user will be + * entering characters from this point. The console can use this to set + * the beginning point for the cursor. + * + * @dev: Console device to use + */ + int (*mark_start)(struct udevice *dev); }; /* Get a pointer to the driver operations for a video console device */ @@ -461,6 +478,24 @@ int vidconsole_show_cursor(struct udevice *dev, uint x, uint y, uint index); */ int vidconsole_set_cursor_visible(struct udevice *dev, bool visible, uint x, uint y, uint index); + +/** + * vidconsole_readline_start() - Enable cursor for all video consoles + * + * Called at the start of command line input to show cursors on all + * active video consoles + * + * @indent: indent subsequent lines to the same position as the first line + */ +void vidconsole_readline_start(bool indent); + +/** + * vidconsole_readline_end() - Disable cursor for all video consoles + * + * Called at the end of command line input to hide cursors on all + * active video consoles + */ +void vidconsole_readline_end(void); #else static inline int vidconsole_show_cursor(struct udevice *dev, uint x, uint y, uint index) @@ -474,6 +509,15 @@ static inline int vidconsole_set_cursor_visible(struct udevice *dev, { return 0; } + +static inline void vidconsole_readline_start(bool indent) +{ +} + +static inline void vidconsole_readline_end(void) +{ +} + #endif /* CONFIG_CURSOR */ static inline void cli_index_adjust(struct vidconsole_priv *priv, int by) -- 2.43.0