
From: Simon Glass <sjg@chromium.org> Drawing the cursor is a destructive operation, so we must save the previous contents of the affected part of the framebuffer, so it can be restored afterwards. Add this to the cursor info and set it up when probing the console device. Signed-off-by: Simon Glass <sjg@chromium.org> --- drivers/video/console_core.c | 41 ++++++++++++++++++++++++++++- drivers/video/console_truetype.c | 4 +++ drivers/video/vidconsole_internal.h | 10 +++++++ include/video_console.h | 4 +++ 4 files changed, 58 insertions(+), 1 deletion(-) diff --git a/drivers/video/console_core.c b/drivers/video/console_core.c index 6db42e63ea9..b1688e717c9 100644 --- a/drivers/video/console_core.c +++ b/drivers/video/console_core.c @@ -9,6 +9,8 @@ #include <video.h> #include <video_console.h> #include <dm.h> +#include <malloc.h> +#include <spl.h> #include <video_font.h> #include "vidconsole_internal.h" @@ -198,9 +200,46 @@ int cursor_show(struct vidconsole_cursor *curs, struct video_priv *vid_priv, return 0; } +int console_alloc_cursor(struct udevice *dev) +{ + struct vidconsole_priv *vc_priv; + struct vidconsole_cursor *curs; + struct video_priv *vid_priv; + struct udevice *vid; + int save_count; + + if (!CONFIG_IS_ENABLED(CURSOR) || xpl_phase() < PHASE_BOARD_R) + return 0; + + vc_priv = dev_get_uclass_priv(dev); + vid = dev_get_parent(dev); + vid_priv = dev_get_uclass_priv(vid); + curs = &vc_priv->curs; + + /* Allocate cursor save buffer for maximum possible cursor height */ + save_count = vid_priv->ysize * VIDCONSOLE_CURSOR_WIDTH; + curs->save_data = malloc(save_count * sizeof(u32)); + if (!curs->save_data) + return -ENOMEM; + + return 0; +} + int console_probe(struct udevice *dev) { - return console_set_font(dev, fonts); + int ret; + + ret = console_set_font(dev, fonts); + if (ret) + return ret; + + if (CONFIG_IS_ENABLED(CURSOR) && xpl_phase() == PHASE_BOARD_R) { + ret = console_alloc_cursor(dev); + if (ret) + return ret; + } + + return 0; } const char *console_simple_get_font_size(struct udevice *dev, uint *sizep) diff --git a/drivers/video/console_truetype.c b/drivers/video/console_truetype.c index e215a3e0e54..fc2985ed92f 100644 --- a/drivers/video/console_truetype.c +++ b/drivers/video/console_truetype.c @@ -1111,6 +1111,10 @@ static int console_truetype_probe(struct udevice *dev) debug("%s: ready\n", __func__); + ret = console_alloc_cursor(dev); + if (ret) + return ret; + return 0; } diff --git a/drivers/video/vidconsole_internal.h b/drivers/video/vidconsole_internal.h index c008b9cf7d3..4cb6ba4e15f 100644 --- a/drivers/video/vidconsole_internal.h +++ b/drivers/video/vidconsole_internal.h @@ -123,6 +123,16 @@ int fill_char_horizontally(uchar *pfont, void **line, struct video_priv *vid_pri int cursor_show(struct vidconsole_cursor *curs, struct video_priv *vid_priv, bool direction); +/** + * console_alloc_cursor() - Allocate cursor save buffer + * + * Allocates memory for saving pixels under the cursor + * + * @dev: vidconsole device + * Return: 0 if success, -ENOMEM if allocation fails + */ +int console_alloc_cursor(struct udevice *dev); + /** * console probe function. * diff --git a/include/video_console.h b/include/video_console.h index b40253b218d..ffe331c5803 100644 --- a/include/video_console.h +++ b/include/video_console.h @@ -32,6 +32,8 @@ enum { * @enabled: cursor is active (e.g. during readline) * @visible: cursor is currently visible * @indent: indent subsequent lines to the same position as the first line + * @saved: true if save_data contains valid data + * @save_data: saved pixels under cursor * @x: cursor left X position in pixels * @y: cursor top Y position in pixels * @height: height of cursor in pixels @@ -41,6 +43,8 @@ struct vidconsole_cursor { bool enabled; bool visible; bool indent; + bool saved; + u32 *save_data; /* filled in by get_cursor_info(): */ uint x; -- 2.43.0