On Mon, 10 Jan 2022 10:41:14 +0100 Heinrich Schuchardt <heinrich.schucha...@canonical.com> wrote:
Hi, > On 1/10/22 01:56, Andre Przywara wrote: > > So far the DM_VIDEO console is completely lacking any cursor, which makes > > typing and correcting quite irritating. > > > > Add a simple cursor display by writing a SPACE glyph in the background > > colour to the next character position on the screen. Any typed character > > will naturally overwrite it, so we need to only explicitly clear it if > > the next character will appear somewhere else (newline, backspace). > > Does this work with (non-monospaced) Truetype fonts? > Moving backwards in Truetype is awkward. I don't know, I need to try this again. I think I tried TrueType (before adding wide character bitmap support), but ran into some issues, might well be due to the proportional fonts only. In general I think *proper* cursor support can be tricky and tedious, so this version here is deliberately made simple, to have at least *some* cursor. Shall we enable this code only for monospace fonts (both TT and bitmap)? Cheers, Andre > > Signed-off-by: Andre Przywara <andre.przyw...@arm.com> > > --- > > drivers/video/console_normal.c | 1 + > > drivers/video/vidconsole-uclass.c | 42 +++++++++++++++++++++++++++++++ > > include/video_console.h | 1 + > > 3 files changed, 44 insertions(+) > > > > diff --git a/drivers/video/console_normal.c b/drivers/video/console_normal.c > > index 04f022491e5..bfd3aab8d24 100644 > > --- a/drivers/video/console_normal.c > > +++ b/drivers/video/console_normal.c > > @@ -160,6 +160,7 @@ static int console_normal_probe(struct udevice *dev) > > vc_priv->y_charsize = VIDEO_FONT_HEIGHT; > > vc_priv->cols = vid_priv->xsize / VIDEO_FONT_WIDTH; > > vc_priv->rows = vid_priv->ysize / VIDEO_FONT_HEIGHT; > > + vc_priv->cursor_visible = true; > > > > return 0; > > } > > diff --git a/drivers/video/vidconsole-uclass.c > > b/drivers/video/vidconsole-uclass.c > > index f42db40d4cd..420fd86f9ac 100644 > > --- a/drivers/video/vidconsole-uclass.c > > +++ b/drivers/video/vidconsole-uclass.c > > @@ -70,6 +70,26 @@ static int vidconsole_entry_start(struct udevice *dev) > > return ops->entry_start(dev); > > } > > > > +static void draw_cursor(struct udevice *dev, bool state) > > +{ > > + struct vidconsole_priv *priv = dev_get_uclass_priv(dev); > > + struct video_priv *vid_priv = dev_get_uclass_priv(dev->parent); > > + u32 tmp; > > + > > + if (!priv->cursor_visible) > > + return; > > + > > + if (state) { > > + tmp = vid_priv->colour_bg; > > + vid_priv->colour_bg = vid_priv->colour_fg; > > + } > > + > > + vidconsole_putc_xy(dev, priv->xcur_frac, priv->ycur, ' '); > > + > > + if (state) > > + vid_priv->colour_bg = tmp; > > +} > > + > > /* Move backwards one space */ > > static int vidconsole_back(struct udevice *dev) > > { > > @@ -77,6 +97,8 @@ static int vidconsole_back(struct udevice *dev) > > struct vidconsole_ops *ops = vidconsole_get_ops(dev); > > int ret; > > > > + draw_cursor(dev, false); > > + > > if (ops->backspace) { > > ret = ops->backspace(dev); > > if (ret != -ENOSYS) > > @@ -103,6 +125,8 @@ static void vidconsole_newline(struct udevice *dev) > > const int rows = CONFIG_CONSOLE_SCROLL_LINES; > > int i, ret; > > > > + draw_cursor(dev, false); > > + > > priv->xcur_frac = priv->xstart_frac; > > priv->ycur += priv->y_charsize; > > > > @@ -342,6 +366,14 @@ static void vidconsole_escape_char(struct udevice > > *dev, char ch) > > > > break; > > } > > + case 'l': > > + draw_cursor(dev, false); > > + priv->cursor_visible = 0; > > + break; > > + case 'h': > > + priv->cursor_visible = 1; > > + draw_cursor(dev, true); > > + break; > > case 'J': { > > int mode; > > > > @@ -516,6 +548,11 @@ int vidconsole_put_char(struct udevice *dev, char ch) > > struct vidconsole_priv *priv = dev_get_uclass_priv(dev); > > int ret; > > > > + /* > > + * We don't need to clear the cursor since we are going to overwrite > > + * that character anyway. > > + */ > > + > > if (priv->escape) { > > vidconsole_escape_char(dev, ch); > > return 0; > > @@ -530,6 +567,7 @@ int vidconsole_put_char(struct udevice *dev, char ch) > > /* beep */ > > break; > > case '\r': > > + draw_cursor(dev, false); > > priv->xcur_frac = priv->xstart_frac; > > break; > > case '\n': > > @@ -537,6 +575,7 @@ int vidconsole_put_char(struct udevice *dev, char ch) > > vidconsole_entry_start(dev); > > break; > > case '\t': /* Tab (8 chars alignment) */ > > + draw_cursor(dev, false); > > priv->xcur_frac = ((priv->xcur_frac / priv->tab_width_frac) > > + 1) * priv->tab_width_frac; > > > > @@ -554,6 +593,8 @@ int vidconsole_put_char(struct udevice *dev, char ch) > > break; > > } > > > > + draw_cursor(dev, true); > > + > > return 0; > > } > > > > @@ -620,6 +661,7 @@ static int vidconsole_pre_probe(struct udevice *dev) > > struct video_priv *vid_priv = dev_get_uclass_priv(vid); > > > > priv->xsize_frac = VID_TO_POS(vid_priv->xsize); > > + priv->cursor_visible = false; > > > > return 0; > > } > > diff --git a/include/video_console.h b/include/video_console.h > > index 06b798ef10c..a908f1412e8 100644 > > --- a/include/video_console.h > > +++ b/include/video_console.h > > @@ -83,6 +83,7 @@ struct vidconsole_priv { > > int escape_len; > > int row_saved; > > int col_saved; > > + bool cursor_visible; > > char escape_buf[32]; > > }; > > >