diff options
author | Tom Rini <trini@konsulko.com> | 2025-05-02 13:57:26 -0600 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2025-05-02 13:57:26 -0600 |
commit | 6cc812f8cc55c132458c7da5b9fb7666315cbe8c (patch) | |
tree | 297fb9e724f252a3fdb46ee28348e66ff7c05a96 | |
parent | 4ca87fd18c1b718be423755939a6e5b1688869f5 (diff) | |
parent | 7703cfe025cbbb2277498483304b4db958521d9e (diff) |
Merge patch series "video: Enhancements related to truetype and console"
Simon Glass <sjg@chromium.org> says:
This series includes some precursor patches needed for forthcoming expo
enhancements.
- truetype support for multiple lines
- make white-on-black a runtime option
- support drawing a rectangle
-rw-r--r-- | arch/sandbox/dts/test.dts | 1 | ||||
-rw-r--r-- | boot/expo.c | 2 | ||||
-rw-r--r-- | boot/scene.c | 10 | ||||
-rw-r--r-- | common/console.c | 18 | ||||
-rw-r--r-- | drivers/video/console_truetype.c | 90 | ||||
-rw-r--r-- | drivers/video/vidconsole-uclass.c | 36 | ||||
-rw-r--r-- | drivers/video/video-uclass.c | 52 | ||||
-rw-r--r-- | include/console.h | 15 | ||||
-rw-r--r-- | include/test/video.h | 45 | ||||
-rw-r--r-- | include/video.h | 31 | ||||
-rw-r--r-- | include/video_console.h | 83 | ||||
-rw-r--r-- | test/dm/video.c | 352 |
12 files changed, 594 insertions, 141 deletions
diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts index 52e9ddbf50f..7026c73bc69 100644 --- a/arch/sandbox/dts/test.dts +++ b/arch/sandbox/dts/test.dts @@ -131,6 +131,7 @@ font-size = <30>; menu-inset = <3>; menuitem-gap-y = <1>; + white-on-black; }; cedit-theme { diff --git a/boot/expo.c b/boot/expo.c index 786f665f53c..8ce645e5a8f 100644 --- a/boot/expo.c +++ b/boot/expo.c @@ -194,7 +194,7 @@ int expo_render(struct expo *exp) u32 colour; int ret; - back = CONFIG_IS_ENABLED(SYS_WHITE_ON_BLACK) ? VID_BLACK : VID_WHITE; + back = vid_priv->white_on_black ? VID_BLACK : VID_WHITE; colour = video_index_to_colour(vid_priv, back); ret = video_fill(dev, colour); if (ret) diff --git a/boot/scene.c b/boot/scene.c index 3290a40222a..fb82ffe768c 100644 --- a/boot/scene.c +++ b/boot/scene.c @@ -298,7 +298,7 @@ int scene_obj_get_hw(struct scene *scn, uint id, int *widthp) } ret = vidconsole_measure(scn->expo->cons, txt->font_name, - txt->font_size, str, &bbox); + txt->font_size, str, -1, &bbox, NULL); if (ret) return log_msg_ret("mea", ret); if (widthp) @@ -330,8 +330,9 @@ static void scene_render_background(struct scene_obj *obj, bool box_only) enum colour_idx fore, back; uint inset = theme->menu_inset; + vid_priv = dev_get_uclass_priv(dev); /* draw a background for the object */ - if (CONFIG_IS_ENABLED(SYS_WHITE_ON_BLACK)) { + if (vid_priv->white_on_black) { fore = VID_DARK_GREY; back = VID_WHITE; } else { @@ -344,7 +345,6 @@ static void scene_render_background(struct scene_obj *obj, bool box_only) return; vidconsole_push_colour(cons, fore, back, &old); - vid_priv = dev_get_uclass_priv(dev); video_fill_part(dev, label_bbox.x0 - inset, label_bbox.y0 - inset, label_bbox.x1 + inset, label_bbox.y1 + inset, vid_priv->colour_fg); @@ -408,7 +408,8 @@ static int scene_obj_render(struct scene_obj *obj, bool text_mode) struct vidconsole_colour old; enum colour_idx fore, back; - if (CONFIG_IS_ENABLED(SYS_WHITE_ON_BLACK)) { + vid_priv = dev_get_uclass_priv(dev); + if (vid_priv->white_on_black) { fore = VID_BLACK; back = VID_WHITE; } else { @@ -416,7 +417,6 @@ static int scene_obj_render(struct scene_obj *obj, bool text_mode) back = VID_BLACK; } - vid_priv = dev_get_uclass_priv(dev); if (obj->flags & SCENEOF_POINT) { vidconsole_push_colour(cons, fore, back, &old); video_fill_part(dev, x - theme->menu_inset, y, diff --git a/common/console.c b/common/console.c index 275da2f264d..48586fd2166 100644 --- a/common/console.c +++ b/common/console.c @@ -359,6 +359,24 @@ void console_puts_select_stderr(bool serial_only, const char *s) console_puts_select(stderr, serial_only, s); } +int console_printf_select_stderr(bool serial_only, const char *fmt, ...) +{ + char buf[CONFIG_SYS_PBSIZE]; + va_list args; + int ret; + + va_start(args, fmt); + + /* For this to work, buf must be larger than anything we ever want to + * print. + */ + ret = vscnprintf(buf, sizeof(buf), fmt, args); + va_end(args); + console_puts_select_stderr(serial_only, buf); + + return ret; +} + static void console_puts(int file, const char *s) { int i; diff --git a/drivers/video/console_truetype.c b/drivers/video/console_truetype.c index 980baee83cf..6d2c2c2e177 100644 --- a/drivers/video/console_truetype.c +++ b/drivers/video/console_truetype.c @@ -3,6 +3,8 @@ * Copyright (c) 2016 Google, Inc */ +#define LOG_CATEGORY UCLASS_VIDEO + #include <abuf.h> #include <dm.h> #include <log.h> @@ -488,10 +490,12 @@ static int console_truetype_backspace(struct udevice *dev) static int console_truetype_entry_start(struct udevice *dev) { + struct vidconsole_priv *vc_priv = dev_get_uclass_priv(dev); struct console_tt_priv *priv = dev_get_priv(dev); /* A new input line has start, so clear our history */ priv->pos_ptr = 0; + vc_priv->last_ch = 0; return 0; } @@ -733,14 +737,18 @@ static int truetype_select_font(struct udevice *dev, const char *name, } static int truetype_measure(struct udevice *dev, const char *name, uint size, - const char *text, struct vidconsole_bbox *bbox) + const char *text, int pixel_limit, + struct vidconsole_bbox *bbox, struct alist *lines) { struct console_tt_metrics *met; + struct vidconsole_mline mline; + const char *s, *last_space; + int width, last_width; stbtt_fontinfo *font; int lsb, advance; - const char *s; - int width; - int last; + int start; + int limit; + int lastch; int ret; ret = get_metrics(dev, name, size, &met); @@ -751,27 +759,85 @@ static int truetype_measure(struct udevice *dev, const char *name, uint size, if (!*text) return 0; + limit = -1; + if (pixel_limit != -1) + limit = tt_ceil((double)pixel_limit / met->scale); + font = &met->font; width = 0; - for (last = 0, s = text; *s; s++) { + bbox->y1 = 0; + bbox->x1 = 0; + start = 0; + last_space = NULL; + last_width = 0; + for (lastch = 0, s = text; *s; s++) { + int neww; int ch = *s; - /* Used kerning to fine-tune the position of this character */ - if (last) - width += stbtt_GetCodepointKernAdvance(font, last, ch); + if (ch == ' ') { + /* + * store the position and width so we can use it again + * if we need to word-wrap + */ + last_space = s; + last_width = width; + } /* First get some basic metrics about this character */ stbtt_GetCodepointHMetrics(font, ch, &advance, &lsb); + neww = width + advance; + + /* Use kerning to fine-tune the position of this character */ + if (lastch) + neww += stbtt_GetCodepointKernAdvance(font, lastch, ch); + lastch = ch; + + /* see if we need to start a new line */ + if (ch == '\n' || (limit != -1 && neww >= limit)) { + if (ch != '\n' && last_space) { + s = last_space; + width = last_width; + } + last_space = NULL; + mline.bbox.x0 = 0; + mline.bbox.y0 = bbox->y1; + mline.bbox.x1 = tt_ceil((double)width * met->scale); + bbox->x1 = max(bbox->x1, mline.bbox.x1); + bbox->y1 += met->font_size; + mline.bbox.y1 = bbox->y1; + mline.bbox.valid = true; + mline.start = start; + mline.len = (s - text) - start; + if (lines && !alist_add(lines, mline)) + return log_msg_ret("ttm", -ENOMEM); + log_debug("line x1 %d y0 %d y1 %d start %d len %d text '%.*s'\n", + mline.bbox.x1, mline.bbox.y0, mline.bbox.y1, + mline.start, mline.len, mline.len, text + mline.start); + + start = s - text; + start++; + lastch = 0; + neww = 0; + } - width += advance; - last = ch; + width = neww; } + /* add the final line */ + mline.bbox.x0 = 0; + mline.bbox.y0 = bbox->y1; + mline.bbox.x1 = tt_ceil((double)width * met->scale); + bbox->y1 += met->font_size; + mline.bbox.y1 = bbox->y1; + mline.start = start; + mline.len = (s - text) - start; + if (lines && !alist_add(lines, mline)) + return log_msg_ret("ttM", -ENOMEM); + bbox->valid = true; bbox->x0 = 0; bbox->y0 = 0; - bbox->x1 = tt_ceil((double)width * met->scale); - bbox->y1 = met->font_size; + bbox->x1 = max(bbox->x1, mline.bbox.x1); return 0; } diff --git a/drivers/video/vidconsole-uclass.c b/drivers/video/vidconsole-uclass.c index a1dfd35b7b8..f1b2d61bd8f 100644 --- a/drivers/video/vidconsole-uclass.c +++ b/drivers/video/vidconsole-uclass.c @@ -127,6 +127,9 @@ void vidconsole_set_cursor_pos(struct udevice *dev, int x, int y) priv->xcur_frac = VID_TO_POS(x); priv->xstart_frac = priv->xcur_frac; priv->ycur = y; + + /* make sure not to kern against the previous character */ + priv->last_ch = 0; vidconsole_entry_start(dev); } @@ -508,12 +511,14 @@ int vidconsole_put_char(struct udevice *dev, char ch) return 0; } -int vidconsole_put_string(struct udevice *dev, const char *str) +int vidconsole_put_stringn(struct udevice *dev, const char *str, int maxlen) { - const char *s; + const char *s, *end = NULL; int ret; - for (s = str; *s; s++) { + if (maxlen != -1) + end = str + maxlen; + for (s = str; *s && (maxlen == -1 || s < end); s++) { ret = vidconsole_put_char(dev, *s); if (ret) return ret; @@ -522,11 +527,19 @@ int vidconsole_put_string(struct udevice *dev, const char *str) return 0; } +int vidconsole_put_string(struct udevice *dev, const char *str) +{ + return vidconsole_put_stringn(dev, str, -1); +} + static void vidconsole_putc(struct stdio_dev *sdev, const char ch) { struct udevice *dev = sdev->priv; + struct vidconsole_priv *priv = dev_get_uclass_priv(dev); int ret; + if (priv->quiet) + return; ret = vidconsole_put_char(dev, ch); if (ret) { #ifdef DEBUG @@ -544,8 +557,11 @@ static void vidconsole_putc(struct stdio_dev *sdev, const char ch) static void vidconsole_puts(struct stdio_dev *sdev, const char *s) { struct udevice *dev = sdev->priv; + struct vidconsole_priv *priv = dev_get_uclass_priv(dev); int ret; + if (priv->quiet) + return; ret = vidconsole_put_string(dev, s); if (ret) { #ifdef DEBUG @@ -608,14 +624,17 @@ int vidconsole_select_font(struct udevice *dev, const char *name, uint size) } int vidconsole_measure(struct udevice *dev, const char *name, uint size, - const char *text, struct vidconsole_bbox *bbox) + const char *text, int limit, + struct vidconsole_bbox *bbox, struct alist *lines) { struct vidconsole_priv *priv = dev_get_uclass_priv(dev); struct vidconsole_ops *ops = vidconsole_get_ops(dev); int ret; if (ops->measure) { - ret = ops->measure(dev, name, size, text, bbox); + if (lines) + alist_empty(lines); + ret = ops->measure(dev, name, size, text, limit, bbox, lines); if (ret != -ENOSYS) return ret; } @@ -784,3 +803,10 @@ void vidconsole_position_cursor(struct udevice *dev, unsigned col, unsigned row) y = min_t(short, row * priv->y_charsize, vid_priv->ysize - 1); vidconsole_set_cursor_pos(dev, x, y); } + +void vidconsole_set_quiet(struct udevice *dev, bool quiet) +{ + struct vidconsole_priv *priv = dev_get_uclass_priv(dev); + + priv->quiet = quiet; +} diff --git a/drivers/video/video-uclass.c b/drivers/video/video-uclass.c index 503cdb9f025..53641fc28b6 100644 --- a/drivers/video/video-uclass.c +++ b/drivers/video/video-uclass.c @@ -26,6 +26,7 @@ #ifdef CONFIG_SANDBOX #include <asm/sdl.h> #endif +#include "vidconsole_internal.h" /* * Theory of operation: @@ -216,6 +217,40 @@ int video_fill_part(struct udevice *dev, int xstart, int ystart, int xend, return 0; } +int video_draw_box(struct udevice *dev, int x0, int y0, int x1, int y1, + int width, u32 colour) +{ + struct video_priv *priv = dev_get_uclass_priv(dev); + int pbytes = VNBYTES(priv->bpix); + void *start, *line; + int pixels = x1 - x0; + int row; + + start = priv->fb + y0 * priv->line_length; + start += x0 * pbytes; + line = start; + for (row = y0; row < y1; row++) { + void *ptr = line; + int i; + + for (i = 0; i < width; i++) + fill_pixel_and_goto_next(&ptr, colour, pbytes, pbytes); + if (row < y0 + width || row >= y1 - width) { + for (i = 0; i < pixels - width * 2; i++) + fill_pixel_and_goto_next(&ptr, colour, pbytes, + pbytes); + } else { + ptr += (pixels - width * 2) * pbytes; + } + for (i = 0; i < width; i++) + fill_pixel_and_goto_next(&ptr, colour, pbytes, pbytes); + line += priv->line_length; + } + video_damage(dev, x0, y0, x1 - x0, y1 - y0); + + return 0; +} + int video_reserve_from_bloblist(struct video_handoff *ho) { if (!ho->fb || ho->size == 0) @@ -345,7 +380,7 @@ void video_set_default_colors(struct udevice *dev, bool invert) struct video_priv *priv = dev_get_uclass_priv(dev); int fore, back; - if (CONFIG_IS_ENABLED(SYS_WHITE_ON_BLACK)) { + if (priv->white_on_black) { /* White is used when switching to bold, use light gray here */ fore = VID_LIGHT_GRAY; back = VID_BLACK; @@ -481,6 +516,7 @@ int video_sync(struct udevice *vid, bool force) video_flush_dcache(vid, true); #if defined(CONFIG_VIDEO_SANDBOX_SDL) + /* to see the copy framebuffer, use priv->copy_fb */ sandbox_sdl_sync(priv->fb); #endif priv->last_sync = get_timer(0); @@ -582,6 +618,18 @@ static void video_idle(struct cyclic_info *cyc) video_sync_all(); } +void video_set_white_on_black(struct udevice *dev, bool white_on_black) +{ + struct video_priv *priv = dev_get_uclass_priv(dev); + + if (priv->white_on_black != white_on_black) { + priv->white_on_black = white_on_black; + video_set_default_colors(dev, false); + + video_clear(dev); + } +} + /* Set up the display ready for use */ static int video_post_probe(struct udevice *dev) { @@ -624,6 +672,8 @@ static int video_post_probe(struct udevice *dev) if (IS_ENABLED(CONFIG_VIDEO_COPY) && plat->copy_base) priv->copy_fb = map_sysmem(plat->copy_base, plat->size); + priv->white_on_black = CONFIG_IS_ENABLED(SYS_WHITE_ON_BLACK); + /* Set up colors */ video_set_default_colors(dev, false); diff --git a/include/console.h b/include/console.h index 57fdb0834c1..8d0d7bb8a4c 100644 --- a/include/console.h +++ b/include/console.h @@ -170,6 +170,21 @@ int console_announce_r(void); void console_puts_select_stderr(bool serial_only, const char *s); /** + * console_printf_select_stderr() - Output a formatted string to selected devs + * + * This writes to stderr only. It is useful for outputting errors. Note that it + * uses its own buffer, separate from the print buffer, to allow printing + * messages within console/stdio code + * + * @serial_only: true to output only to serial, false to output to everything + * else + * @fmt: Printf format string, followed by format arguments + * Return: number of characters written + */ +int console_printf_select_stderr(bool serial_only, const char *fmt, ...) + __attribute__ ((format (__printf__, 2, 3))); + +/** * console_clear() - Clear the console * * Uses an ANSI sequence to clear the display, failing back to clearing the diff --git a/include/test/video.h b/include/test/video.h new file mode 100644 index 00000000000..000fd708c86 --- /dev/null +++ b/include/test/video.h @@ -0,0 +1,45 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (c) 2013 Google, Inc. + */ + +#ifndef __TEST_VIDEO_H +#define __TEST_VIDEO_H + +#include <stdbool.h> + +struct udevice; +struct unit_test_state; + +/** + * video_compress_fb() - Compress the frame buffer and return its size + * + * We want to write tests which perform operations on the video console and + * check that the frame buffer ends up with the correct contents. But it is + * painful to store 'known good' images for comparison with the frame + * buffer. As an alternative, we can compress the frame buffer and check the + * size of the compressed data. This provides a pretty good level of + * certainty and the resulting tests need only check a single value. + * + * @uts: Test state + * @dev: Video device + * @use_copy: Use copy frame buffer if available + * Return: compressed size of the frame buffer, or -ve on error + */ +int video_compress_fb(struct unit_test_state *uts, struct udevice *dev, + bool use_copy); + +/** + * check_copy_frame_buffer() - Compare main frame buffer to copy + * + * If the copy frame buffer is enabled, this compares it to the main + * frame buffer. Normally they should have the same contents after a + * sync. + * + * @uts: Test state + * @dev: Video device + * Return: 0, or -ve on error + */ +int video_check_copy_fb(struct unit_test_state *uts, struct udevice *dev); + +#endif diff --git a/include/video.h b/include/video.h index 2fe2f73a865..9ea6b676463 100644 --- a/include/video.h +++ b/include/video.h @@ -100,6 +100,7 @@ enum video_format { * @fg_col_idx: Foreground color code (bit 3 = bold, bit 0-2 = color) * @bg_col_idx: Background color code (bit 3 = bold, bit 0-2 = color) * @last_sync: Monotonic time of last video sync + * @white_on_black: Use a black background */ struct video_priv { /* Things set up by the driver: */ @@ -131,6 +132,7 @@ struct video_priv { u8 fg_col_idx; u8 bg_col_idx; ulong last_sync; + bool white_on_black; }; /** @@ -247,7 +249,7 @@ int video_fill(struct udevice *dev, u32 colour); /** * video_fill_part() - Erase a region * - * Erase a rectangle of the display within the given bounds. + * Erase a rectangle on the display within the given bounds * * @dev: Device to update * @xstart: X start position in pixels from the left @@ -261,6 +263,23 @@ int video_fill_part(struct udevice *dev, int xstart, int ystart, int xend, int yend, u32 colour); /** + * video_draw_box() - Draw a box + * + * Draw a rectangle on the display within the given bounds + * + * @dev: Device to update + * @x0: X start position in pixels from the left + * @y0: Y start position in pixels from the top + * @x1: X end position in pixels from the left + * @y1: Y end position in pixels from the top + * @width: width in pixels + * @colour: Value to write + * Return: 0 if OK, -ENOSYS if the display depth is not supported + */ +int video_draw_box(struct udevice *dev, int x0, int y0, int x1, int y1, + int width, u32 colour); + +/** * video_sync() - Sync a device's frame buffer with its hardware * * @vid: Device to sync @@ -347,6 +366,16 @@ void video_set_flush_dcache(struct udevice *dev, bool flush); void video_set_default_colors(struct udevice *dev, bool invert); /** + * video_set_white_on_black() - Change the setting for white-on-black + * + * This does nothing if the setting is already the same. + * + * @dev: video device + * @white_on_black: true to use white-on-black, false for black-on-white + */ +void video_set_white_on_black(struct udevice *dev, bool white_on_black); + +/** * video_default_font_height() - Get the default font height * * @dev: video device diff --git a/include/video_console.h b/include/video_console.h index 13197fa4518..8f3f58f3aa9 100644 --- a/include/video_console.h +++ b/include/video_console.h @@ -6,6 +6,7 @@ #ifndef __video_console_h #define __video_console_h +#include <alist.h> #include <video.h> struct abuf; @@ -52,6 +53,7 @@ enum { * @row_saved: Saved Y position in pixels (0=top) * @escape_buf: Buffer to accumulate escape sequence * @utf8_buf: Buffer to accumulate UTF-8 byte sequence + * @quiet: Suppress all output from stdio */ struct vidconsole_priv { struct stdio_dev sdev; @@ -76,6 +78,7 @@ struct vidconsole_priv { int col_saved; char escape_buf[32]; char utf8_buf[5]; + bool quiet; }; /** @@ -120,6 +123,19 @@ struct vidconsole_bbox { }; /** + * vidconsole_mline - Holds information about a line of measured text + * + * @bbox: Bounding box of the line, assuming it starts at 0,0 + * @start: String index of the first character in the line + * @len: Number of characters in the line + */ +struct vidconsole_mline { + struct vidconsole_bbox bbox; + int start; + int len; +}; + +/** * struct vidconsole_ops - Video console operations * * These operations work on either an absolute console position (measured @@ -228,18 +244,26 @@ struct vidconsole_ops { int (*select_font)(struct udevice *dev, const char *name, uint size); /** - * measure() - Measure the bounds of some text + * measure() - Measure the bounding box of some text * - * @dev: Device to adjust + * The text can include newlines + * + * @dev: Console device to use * @name: Font name to use (NULL to use default) * @size: Font size to use (0 to use default) * @text: Text to measure + * @limit: Width limit for each line, or -1 if none * @bbox: Returns bounding box of text, assuming it is positioned * at 0,0 + * @lines: If non-NULL, this must be an alist of + * struct vidconsole_mline inited by caller. A separate + * record is added for each line of text + * * Returns: 0 on success, -ENOENT if no such font */ int (*measure)(struct udevice *dev, const char *name, uint size, - const char *text, struct vidconsole_bbox *bbox); + const char *text, int limit, + struct vidconsole_bbox *bbox, struct alist *lines); /** * nominal() - Measure the expected width of a line of text @@ -320,19 +344,27 @@ int vidconsole_get_font(struct udevice *dev, int seq, */ int vidconsole_select_font(struct udevice *dev, const char *name, uint size); -/* - * vidconsole_measure() - Measuring the bounding box of some text +/** + * vidconsole_measure() - Measure the bounding box of some text * - * @dev: Console device to use - * @name: Font name, NULL for default - * @size: Font size, ignored if @name is NULL - * @text: Text to measure - * @bbox: Returns nounding box of text - * Returns: 0 if OK, -ve on error + * The text can include newlines + * + * @dev: Device to adjust + * @name: Font name to use (NULL to use default) + * @size: Font size to use (0 to use default) + * @text: Text to measure + * @limit: Width limit for each line, or -1 if none + * @bbox: Returns bounding box of text, assuming it is positioned + * at 0,0 + * @lines: If non-NULL, this must be an alist of + * struct vidconsole_mline inited by caller. The list is emptied + * and then a separate record is added for each line of text + * + * Returns: 0 on success, -ENOENT if no such font */ int vidconsole_measure(struct udevice *dev, const char *name, uint size, - const char *text, struct vidconsole_bbox *bbox); - + const char *text, int limit, + struct vidconsole_bbox *bbox, struct alist *lines); /** * vidconsole_nominal() - Measure the expected width of a line of text * @@ -470,6 +502,23 @@ int vidconsole_entry_start(struct udevice *dev); int vidconsole_put_char(struct udevice *dev, char ch); /** + * vidconsole_put_stringn() - Output part of a string to the current console pos + * + * Outputs part of a string to the console and advances the cursor. This + * function handles wrapping to new lines and scrolling the console. Special + * characters are handled also: \n, \r, \b and \t. + * + * The device always starts with the cursor at position 0,0 (top left). It + * can be adjusted manually using vidconsole_position_cursor(). + * + * @dev: Device to adjust + * @str: String to write + * @maxlen: Maximum chars to output, or -1 for all + * Return: 0 if OK, -ve on error + */ +int vidconsole_put_stringn(struct udevice *dev, const char *str, int maxlen); + +/** * vidconsole_put_string() - Output a string to the current console position * * Outputs a string to the console and advances the cursor. This function @@ -537,4 +586,12 @@ void vidconsole_list_fonts(struct udevice *dev); */ int vidconsole_get_font_size(struct udevice *dev, const char **name, uint *sizep); +/** + * vidconsole_set_quiet() - Select whether the console should output stdio + * + * @dev: vidconsole device + * @quiet: true to suppress stdout/stderr output, false to enable it + */ +void vidconsole_set_quiet(struct udevice *dev, bool quiet); + #endif diff --git a/test/dm/video.c b/test/dm/video.c index 929fc16d0ef..ecf74605b5c 100644 --- a/test/dm/video.c +++ b/test/dm/video.c @@ -17,8 +17,10 @@ #include <asm/sdl.h> #include <dm/test.h> #include <dm/uclass-internal.h> +#include <test/lib.h> #include <test/test.h> #include <test/ut.h> +#include <test/video.h> /* * These tests use the standard sandbox frame buffer, the resolution of which @@ -44,24 +46,8 @@ static int dm_test_video_base(struct unit_test_state *uts) } DM_TEST(dm_test_video_base, UTF_SCAN_PDATA | UTF_SCAN_FDT); -/** - * compress_frame_buffer() - Compress the frame buffer and return its size - * - * We want to write tests which perform operations on the video console and - * check that the frame buffer ends up with the correct contents. But it is - * painful to store 'known good' images for comparison with the frame - * buffer. As an alternative, we can compress the frame buffer and check the - * size of the compressed data. This provides a pretty good level of - * certainty and the resulting tests need only check a single value. - * - * @uts: Test state - * @dev: Video device - * @use_copy: Use copy frame buffer if available - * Return: compressed size of the frame buffer, or -ve on error - */ -static int compress_frame_buffer(struct unit_test_state *uts, - struct udevice *dev, - bool use_copy) +int video_compress_fb(struct unit_test_state *uts, struct udevice *dev, + bool use_copy) { struct video_priv *priv = dev_get_uclass_priv(dev); uint destlen; @@ -86,19 +72,7 @@ static int compress_frame_buffer(struct unit_test_state *uts, return destlen; } -/** - * check_copy_frame_buffer() - Compare main frame buffer to copy - * - * If the copy frame buffer is enabled, this compares it to the main - * frame buffer. Normally they should have the same contents after a - * sync. - * - * @uts: Test state - * @dev: Video device - * Return: 0, or -ve on error - */ -static int check_copy_frame_buffer(struct unit_test_state *uts, - struct udevice *dev) +int video_check_copy_fb(struct unit_test_state *uts, struct udevice *dev) { struct video_priv *priv = dev_get_uclass_priv(dev); @@ -174,31 +148,31 @@ static int dm_test_video_text(struct unit_test_state *uts) ut_assertok(video_get_nologo(uts, &dev)); ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con)); ut_assertok(vidconsole_select_font(con, "8x16", 0)); - ut_asserteq(46, compress_frame_buffer(uts, dev, false)); - ut_assertok(check_copy_frame_buffer(uts, dev)); + ut_asserteq(46, video_compress_fb(uts, dev, false)); + ut_assertok(video_check_copy_fb(uts, dev)); ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con)); vidconsole_putc_xy(con, 0, 0, 'a'); - ut_asserteq(79, compress_frame_buffer(uts, dev, false)); - ut_assertok(check_copy_frame_buffer(uts, dev)); + ut_asserteq(79, video_compress_fb(uts, dev, false)); + ut_assertok(video_check_copy_fb(uts, dev)); vidconsole_putc_xy(con, 0, 0, ' '); - ut_asserteq(46, compress_frame_buffer(uts, dev, false)); - ut_assertok(check_copy_frame_buffer(uts, dev)); + ut_asserteq(46, video_compress_fb(uts, dev, false)); + ut_assertok(video_check_copy_fb(uts, dev)); for (i = 0; i < 20; i++) vidconsole_putc_xy(con, VID_TO_POS(i * 8), 0, ' ' + i); - ut_asserteq(273, compress_frame_buffer(uts, dev, false)); - ut_assertok(check_copy_frame_buffer(uts, dev)); + ut_asserteq(273, video_compress_fb(uts, dev, false)); + ut_assertok(video_check_copy_fb(uts, dev)); vidconsole_set_row(con, 0, WHITE); - ut_asserteq(46, compress_frame_buffer(uts, dev, false)); - ut_assertok(check_copy_frame_buffer(uts, dev)); + ut_asserteq(46, video_compress_fb(uts, dev, false)); + ut_assertok(video_check_copy_fb(uts, dev)); for (i = 0; i < 20; i++) vidconsole_putc_xy(con, VID_TO_POS(i * 8), 0, ' ' + i); - ut_asserteq(273, compress_frame_buffer(uts, dev, false)); - ut_assertok(check_copy_frame_buffer(uts, dev)); + ut_asserteq(273, video_compress_fb(uts, dev, false)); + ut_assertok(video_check_copy_fb(uts, dev)); return 0; } @@ -216,31 +190,31 @@ static int dm_test_video_text_12x22(struct unit_test_state *uts) ut_assertok(video_get_nologo(uts, &dev)); ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con)); ut_assertok(vidconsole_select_font(con, "12x22", 0)); - ut_asserteq(46, compress_frame_buffer(uts, dev, false)); - ut_assertok(check_copy_frame_buffer(uts, dev)); + ut_asserteq(46, video_compress_fb(uts, dev, false)); + ut_assertok(video_check_copy_fb(uts, dev)); ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con)); vidconsole_putc_xy(con, 0, 0, 'a'); - ut_asserteq(89, compress_frame_buffer(uts, dev, false)); - ut_assertok(check_copy_frame_buffer(uts, dev)); + ut_asserteq(89, video_compress_fb(uts, dev, false)); + ut_assertok(video_check_copy_fb(uts, dev)); vidconsole_putc_xy(con, 0, 0, ' '); - ut_asserteq(46, compress_frame_buffer(uts, dev, false)); - ut_assertok(check_copy_frame_buffer(uts, dev)); + ut_asserteq(46, video_compress_fb(uts, dev, false)); + ut_assertok(video_check_copy_fb(uts, dev)); for (i = 0; i < 20; i++) vidconsole_putc_xy(con, VID_TO_POS(i * 8), 0, ' ' + i); - ut_asserteq(363, compress_frame_buffer(uts, dev, false)); - ut_assertok(check_copy_frame_buffer(uts, dev)); + ut_asserteq(363, video_compress_fb(uts, dev, false)); + ut_assertok(video_check_copy_fb(uts, dev)); vidconsole_set_row(con, 0, WHITE); - ut_asserteq(46, compress_frame_buffer(uts, dev, false)); - ut_assertok(check_copy_frame_buffer(uts, dev)); + ut_asserteq(46, video_compress_fb(uts, dev, false)); + ut_assertok(video_check_copy_fb(uts, dev)); for (i = 0; i < 20; i++) vidconsole_putc_xy(con, VID_TO_POS(i * 8), 0, ' ' + i); - ut_asserteq(363, compress_frame_buffer(uts, dev, false)); - ut_assertok(check_copy_frame_buffer(uts, dev)); + ut_asserteq(363, video_compress_fb(uts, dev, false)); + ut_assertok(video_check_copy_fb(uts, dev)); return 0; } @@ -257,8 +231,8 @@ static int dm_test_video_chars(struct unit_test_state *uts) ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con)); ut_assertok(vidconsole_select_font(con, "8x16", 0)); vidconsole_put_string(con, test_string); - ut_asserteq(466, compress_frame_buffer(uts, dev, false)); - ut_assertok(check_copy_frame_buffer(uts, dev)); + ut_asserteq(466, video_compress_fb(uts, dev, false)); + ut_assertok(video_check_copy_fb(uts, dev)); return 0; } @@ -279,24 +253,24 @@ static int dm_test_video_ansi(struct unit_test_state *uts) /* reference clear: */ video_clear(con->parent); video_sync(con->parent, false); - ut_asserteq(46, compress_frame_buffer(uts, dev, false)); - ut_assertok(check_copy_frame_buffer(uts, dev)); + ut_asserteq(46, video_compress_fb(uts, dev, false)); + ut_assertok(video_check_copy_fb(uts, dev)); /* test clear escape sequence: [2J */ vidconsole_put_string(con, "A\tB\tC"ANSI_ESC"[2J"); - ut_asserteq(46, compress_frame_buffer(uts, dev, false)); - ut_assertok(check_copy_frame_buffer(uts, dev)); + ut_asserteq(46, video_compress_fb(uts, dev, false)); + ut_assertok(video_check_copy_fb(uts, dev)); /* test set-cursor: [%d;%df */ vidconsole_put_string(con, "abc"ANSI_ESC"[2;2fab"ANSI_ESC"[4;4fcd"); - ut_asserteq(143, compress_frame_buffer(uts, dev, false)); - ut_assertok(check_copy_frame_buffer(uts, dev)); + ut_asserteq(143, video_compress_fb(uts, dev, false)); + ut_assertok(video_check_copy_fb(uts, dev)); /* test colors (30-37 fg color, 40-47 bg color) */ vidconsole_put_string(con, ANSI_ESC"[30;41mfoo"); /* black on red */ vidconsole_put_string(con, ANSI_ESC"[33;44mbar"); /* yellow on blue */ - ut_asserteq(272, compress_frame_buffer(uts, dev, false)); - ut_assertok(check_copy_frame_buffer(uts, dev)); + ut_asserteq(272, video_compress_fb(uts, dev, false)); + ut_assertok(video_check_copy_fb(uts, dev)); return 0; } @@ -328,28 +302,28 @@ static int check_vidconsole_output(struct unit_test_state *uts, int rot, ut_assertok(video_get_nologo(uts, &dev)); ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con)); ut_assertok(vidconsole_select_font(con, "8x16", 0)); - ut_asserteq(46, compress_frame_buffer(uts, dev, false)); - ut_assertok(check_copy_frame_buffer(uts, dev)); + ut_asserteq(46, video_compress_fb(uts, dev, false)); + ut_assertok(video_check_copy_fb(uts, dev)); /* Check display wrap */ for (i = 0; i < 120; i++) vidconsole_put_char(con, 'A' + i % 50); - ut_asserteq(wrap_size, compress_frame_buffer(uts, dev, false)); - ut_assertok(check_copy_frame_buffer(uts, dev)); + ut_asserteq(wrap_size, video_compress_fb(uts, dev, false)); + ut_assertok(video_check_copy_fb(uts, dev)); /* Check display scrolling */ for (i = 0; i < SCROLL_LINES; i++) { vidconsole_put_char(con, 'A' + i % 50); vidconsole_put_char(con, '\n'); } - ut_asserteq(scroll_size, compress_frame_buffer(uts, dev, false)); - ut_assertok(check_copy_frame_buffer(uts, dev)); + ut_asserteq(scroll_size, video_compress_fb(uts, dev, false)); + ut_assertok(video_check_copy_fb(uts, dev)); /* If we scroll enough, the screen becomes blank again */ for (i = 0; i < SCROLL_LINES; i++) vidconsole_put_char(con, '\n'); - ut_asserteq(46, compress_frame_buffer(uts, dev, false)); - ut_assertok(check_copy_frame_buffer(uts, dev)); + ut_asserteq(46, video_compress_fb(uts, dev, false)); + ut_assertok(video_check_copy_fb(uts, dev)); return 0; } @@ -423,8 +397,8 @@ static int dm_test_video_bmp(struct unit_test_state *uts) ut_assertok(read_file(uts, "tools/logos/denx.bmp", &addr)); ut_assertok(video_bmp_display(dev, addr, 0, 0, false)); - ut_asserteq(1368, compress_frame_buffer(uts, dev, false)); - ut_assertok(check_copy_frame_buffer(uts, dev)); + ut_asserteq(1368, video_compress_fb(uts, dev, false)); + ut_assertok(video_check_copy_fb(uts, dev)); return 0; } @@ -443,8 +417,8 @@ static int dm_test_video_bmp8(struct unit_test_state *uts) ut_assertok(read_file(uts, "tools/logos/denx.bmp", &addr)); ut_assertok(video_bmp_display(dev, addr, 0, 0, false)); - ut_asserteq(1247, compress_frame_buffer(uts, dev, false)); - ut_assertok(check_copy_frame_buffer(uts, dev)); + ut_asserteq(1247, video_compress_fb(uts, dev, false)); + ut_assertok(video_check_copy_fb(uts, dev)); return 0; } @@ -467,8 +441,8 @@ static int dm_test_video_bmp16(struct unit_test_state *uts) &src_len)); ut_assertok(video_bmp_display(dev, dst, 0, 0, false)); - ut_asserteq(3700, compress_frame_buffer(uts, dev, false)); - ut_assertok(check_copy_frame_buffer(uts, dev)); + ut_asserteq(3700, video_compress_fb(uts, dev, false)); + ut_assertok(video_check_copy_fb(uts, dev)); return 0; } @@ -491,8 +465,8 @@ static int dm_test_video_bmp24(struct unit_test_state *uts) &src_len)); ut_assertok(video_bmp_display(dev, dst, 0, 0, false)); - ut_asserteq(3656, compress_frame_buffer(uts, dev, false)); - ut_assertok(check_copy_frame_buffer(uts, dev)); + ut_asserteq(3656, video_compress_fb(uts, dev, false)); + ut_assertok(video_check_copy_fb(uts, dev)); return 0; } @@ -515,8 +489,8 @@ static int dm_test_video_bmp24_32(struct unit_test_state *uts) &src_len)); ut_assertok(video_bmp_display(dev, dst, 0, 0, false)); - ut_asserteq(6827, compress_frame_buffer(uts, dev, false)); - ut_assertok(check_copy_frame_buffer(uts, dev)); + ut_asserteq(6827, video_compress_fb(uts, dev, false)); + ut_assertok(video_check_copy_fb(uts, dev)); return 0; } @@ -534,8 +508,8 @@ static int dm_test_video_bmp32(struct unit_test_state *uts) ut_assertok(read_file(uts, "tools/logos/denx.bmp", &addr)); ut_assertok(video_bmp_display(dev, addr, 0, 0, false)); - ut_asserteq(2024, compress_frame_buffer(uts, dev, false)); - ut_assertok(check_copy_frame_buffer(uts, dev)); + ut_asserteq(2024, video_compress_fb(uts, dev, false)); + ut_assertok(video_check_copy_fb(uts, dev)); return 0; } @@ -551,8 +525,8 @@ static int dm_test_video_bmp_comp(struct unit_test_state *uts) ut_assertok(read_file(uts, "tools/logos/denx-comp.bmp", &addr)); ut_assertok(video_bmp_display(dev, addr, 0, 0, false)); - ut_asserteq(1368, compress_frame_buffer(uts, dev, false)); - ut_assertok(check_copy_frame_buffer(uts, dev)); + ut_asserteq(1368, video_compress_fb(uts, dev, false)); + ut_assertok(video_check_copy_fb(uts, dev)); return 0; } @@ -571,8 +545,8 @@ static int dm_test_video_comp_bmp32(struct unit_test_state *uts) ut_assertok(read_file(uts, "tools/logos/denx.bmp", &addr)); ut_assertok(video_bmp_display(dev, addr, 0, 0, false)); - ut_asserteq(2024, compress_frame_buffer(uts, dev, false)); - ut_assertok(check_copy_frame_buffer(uts, dev)); + ut_asserteq(2024, video_compress_fb(uts, dev, false)); + ut_assertok(video_check_copy_fb(uts, dev)); return 0; } @@ -591,8 +565,8 @@ static int dm_test_video_comp_bmp8(struct unit_test_state *uts) ut_assertok(read_file(uts, "tools/logos/denx.bmp", &addr)); ut_assertok(video_bmp_display(dev, addr, 0, 0, false)); - ut_asserteq(1247, compress_frame_buffer(uts, dev, false)); - ut_assertok(check_copy_frame_buffer(uts, dev)); + ut_asserteq(1247, video_compress_fb(uts, dev, false)); + ut_assertok(video_check_copy_fb(uts, dev)); return 0; } @@ -607,8 +581,9 @@ static int dm_test_video_truetype(struct unit_test_state *uts) ut_assertok(video_get_nologo(uts, &dev)); ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con)); vidconsole_put_string(con, test_string); - ut_asserteq(12174, compress_frame_buffer(uts, dev, false)); - ut_assertok(check_copy_frame_buffer(uts, dev)); + vidconsole_put_stringn(con, test_string, 30); + ut_asserteq(13184, video_compress_fb(uts, dev, false)); + ut_assertok(video_check_copy_fb(uts, dev)); return 0; } @@ -629,8 +604,8 @@ static int dm_test_video_truetype_scroll(struct unit_test_state *uts) ut_assertok(video_get_nologo(uts, &dev)); ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con)); vidconsole_put_string(con, test_string); - ut_asserteq(34287, compress_frame_buffer(uts, dev, false)); - ut_assertok(check_copy_frame_buffer(uts, dev)); + ut_asserteq(34287, video_compress_fb(uts, dev, false)); + ut_assertok(video_check_copy_fb(uts, dev)); return 0; } @@ -651,8 +626,8 @@ static int dm_test_video_truetype_bs(struct unit_test_state *uts) ut_assertok(video_get_nologo(uts, &dev)); ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con)); vidconsole_put_string(con, test_string); - ut_asserteq(29471, compress_frame_buffer(uts, dev, false)); - ut_assertok(check_copy_frame_buffer(uts, dev)); + ut_asserteq(29471, video_compress_fb(uts, dev, false)); + ut_assertok(video_check_copy_fb(uts, dev)); return 0; } @@ -690,8 +665,8 @@ static int dm_test_video_copy(struct unit_test_state *uts) vidconsole_put_string(con, test_string); vidconsole_put_string(con, test_string); - ut_asserteq(6678, compress_frame_buffer(uts, dev, false)); - ut_assertok(check_copy_frame_buffer(uts, dev)); + ut_asserteq(6678, video_compress_fb(uts, dev, false)); + ut_assertok(video_check_copy_fb(uts, dev)); /* * Secretly clear the hardware frame buffer, but in a different @@ -715,8 +690,8 @@ static int dm_test_video_copy(struct unit_test_state *uts) vidconsole_put_string(con, test_string); vidconsole_put_string(con, test_string); video_sync(dev, true); - ut_asserteq(7589, compress_frame_buffer(uts, dev, false)); - ut_asserteq(7704, compress_frame_buffer(uts, dev, true)); + ut_asserteq(7589, video_compress_fb(uts, dev, false)); + ut_asserteq(7704, video_compress_fb(uts, dev, true)); return 0; } @@ -771,9 +746,180 @@ static int dm_test_video_damage(struct unit_test_state *uts) ut_asserteq(0, priv->damage.xend); ut_asserteq(0, priv->damage.yend); - ut_asserteq(7339, compress_frame_buffer(uts, dev, false)); - ut_assertok(check_copy_frame_buffer(uts, dev)); + ut_asserteq(7339, video_compress_fb(uts, dev, false)); + ut_assertok(video_check_copy_fb(uts, dev)); return 0; } DM_TEST(dm_test_video_damage, UTF_SCAN_PDATA | UTF_SCAN_FDT); + +/* Test font measurement */ +static int dm_test_font_measure(struct unit_test_state *uts) +{ + const char *test_string = "There is always much\nto be said for not " + "attempting more than you can do and for making a certainty of " + "what you try. But this principle, like others in life and " + "war, has its exceptions."; + const struct vidconsole_mline *line; + struct vidconsole_bbox bbox; + struct video_priv *priv; + struct udevice *dev, *con; + const int limit = 0x320; + struct alist lines; + int nl; + + ut_assertok(uclass_get_device(UCLASS_VIDEO, 0, &dev)); + priv = dev_get_uclass_priv(dev); + ut_asserteq(1366, priv->xsize); + ut_asserteq(768, priv->ysize); + + /* this is using the Nimbus font with size of 18 pixels */ + ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con)); + vidconsole_position_cursor(con, 0, 0); + alist_init_struct(&lines, struct vidconsole_mline); + ut_assertok(vidconsole_measure(con, NULL, 0, test_string, -1, &bbox, + &lines)); + ut_asserteq(0, bbox.x0); + ut_asserteq(0, bbox.y0); + ut_asserteq(0x3ea, bbox.x1); + ut_asserteq(0x24, bbox.y1); + ut_asserteq(2, lines.count); + + nl = strchr(test_string, '\n') - test_string; + + line = alist_get(&lines, 0, struct vidconsole_mline); + ut_assertnonnull(line); + ut_asserteq(0, line->bbox.x0); + ut_asserteq(0, line->bbox.y0); + ut_asserteq(0x8c, line->bbox.x1); + ut_asserteq(0x12, line->bbox.y1); + ut_asserteq(0, line->start); + ut_asserteq(20, line->len); + ut_asserteq(nl, line->len); + + line++; + ut_asserteq(0x0, line->bbox.x0); + ut_asserteq(0x12, line->bbox.y0); + ut_asserteq(0x3ea, line->bbox.x1); + ut_asserteq(0x24, line->bbox.y1); + ut_asserteq(21, line->start); + ut_asserteq(nl + 1, line->start); + ut_asserteq(163, line->len); + ut_asserteq(strlen(test_string + nl + 1), line->len); + + /* now use a limit on the width */ + ut_assertok(vidconsole_measure(con, NULL, 0, test_string, limit, &bbox, + &lines)); + ut_asserteq(0, bbox.x0); + ut_asserteq(0, bbox.y0); + ut_asserteq(0x31e, bbox.x1); + ut_asserteq(0x36, bbox.y1); + ut_asserteq(3, lines.count); + + nl = strchr(test_string, '\n') - test_string; + + line = alist_get(&lines, 0, struct vidconsole_mline); + ut_assertnonnull(line); + ut_asserteq(0, line->bbox.x0); + ut_asserteq(0, line->bbox.y0); + ut_asserteq(0x8c, line->bbox.x1); + ut_asserteq(0x12, line->bbox.y1); + ut_asserteq(0, line->start); + ut_asserteq(20, line->len); + ut_asserteq(nl, line->len); + printf("line0 '%.*s'\n", line->len, test_string + line->start); + ut_asserteq_strn("There is always much", + test_string + line->start); + + line++; + ut_asserteq(0x0, line->bbox.x0); + ut_asserteq(0x12, line->bbox.y0); + ut_asserteq(0x31e, line->bbox.x1); + ut_asserteq(0x24, line->bbox.y1); + ut_asserteq(21, line->start); + ut_asserteq(nl + 1, line->start); + ut_asserteq(129, line->len); + printf("line1 '%.*s'\n", line->len, test_string + line->start); + ut_asserteq_strn("to be said for not attempting more than you can do " + "and for making a certainty of what you try. But this " + "principle, like others in", + test_string + line->start); + + line++; + ut_asserteq(0x0, line->bbox.x0); + ut_asserteq(0x24, line->bbox.y0); + ut_asserteq(0xc8, line->bbox.x1); + ut_asserteq(0x36, line->bbox.y1); + ut_asserteq(21 + 130, line->start); + ut_asserteq(33, line->len); + printf("line2 '%.*s'\n", line->len, test_string + line->start); + ut_asserteq_strn("life and war, has its exceptions.", + test_string + line->start); + + /* + * all characters should be accounted for, except the newline and the + * space which is consumed in the wordwrap + */ + ut_asserteq(strlen(test_string) - 2, + line[-2].len + line[-1].len + line->len); + + return 0; +} +DM_TEST(dm_test_font_measure, UTF_SCAN_FDT); + +/* Test silencing the video console */ +static int dm_test_video_silence(struct unit_test_state *uts) +{ + struct udevice *dev, *con; + struct stdio_dev *sdev; + + ut_assertok(uclass_first_device_err(UCLASS_VIDEO, &dev)); + + /* + * use the old console device from before when dm_test_pre_run() was + * called, since that is what is in stdio / console + */ + sdev = stdio_get_by_name("vidconsole"); + ut_assertnonnull(sdev); + con = sdev->priv; + ut_assertok(vidconsole_clear_and_reset(con)); + ut_unsilence_console(uts); + + printf("message 1: console\n"); + vidconsole_put_string(con, "message 1: video\n"); + + vidconsole_set_quiet(con, true); + printf("second message: console\n"); + vidconsole_put_string(con, "second message: video\n"); + + vidconsole_set_quiet(con, false); + printf("final message: console\n"); + vidconsole_put_string(con, "final message: video\n"); + + ut_asserteq(3892, video_compress_fb(uts, dev, false)); + ut_assertok(video_check_copy_fb(uts, dev)); + + return 0; +} +DM_TEST(dm_test_video_silence, UTF_SCAN_FDT); + +/* test drawing a box */ +static int dm_test_video_box(struct unit_test_state *uts) +{ + struct video_priv *priv; + struct udevice *dev; + + ut_assertok(video_get_nologo(uts, &dev)); + priv = dev_get_uclass_priv(dev); + video_draw_box(dev, 100, 100, 200, 200, 3, + video_index_to_colour(priv, VID_LIGHT_BLUE)); + video_draw_box(dev, 300, 100, 400, 200, 1, + video_index_to_colour(priv, VID_MAGENTA)); + video_draw_box(dev, 500, 100, 600, 200, 20, + video_index_to_colour(priv, VID_LIGHT_RED)); + ut_asserteq(133, video_compress_fb(uts, dev, false)); + ut_assertok(video_check_copy_fb(uts, dev)); + + return 0; +} +DM_TEST(dm_test_video_box, UTF_SCAN_FDT); |