drivers/pc80/vga: Add API to write multi-line video message

This patch provides an API to allow users to output multi-line
messages using VGA framebuffer.

The current limitation with multiline message is that,
vga_line_write() function is unable to understand newline character
hence, eventually output multiple lines separated with a newline
character with a single line statement.

This patch ensures to parse the entire string and split it into
multiple lines based on the newline character and print each line
separately to the VFG framebuffer.

User can choose to align the output video message as per given choice
between left/center/right of the screen
(i.e. enum VGA_TEXT_ALIGNMENT ).

Additionally, added macros to define the horizontal screen alignment
as well. Ideally if user would like to print the video message at the
middle of the screen then the vertical alignment would be
`VGA_TEXT_CENTER` and horizontal alignment would be
`VGA_TEXT_HORIZONTAL_MIDDLE`.

TEST=Able to build and boot Google/Taeko.

While output a video message such as :

"Your device is finishing an update. This may take 1-2 minutes.\nPlease
do not turn off your device."

Without this patch:

Your device is finishing an update. This may take 1-2 minutes. nPlease
do not turn off your device.

With this patch:

(in Left Alignment):
Your device is finishing an update. This may take 1-2 minutes.
Please do not turn off your device.

(in Right Alignment):
         Your device is finishing an update. This may take 1-2 minutes.
                                    Please do not turn off your device.

(in Center Alignment):
   Your device is finishing an update. This may take 1-2 minutes.
              Please do not turn off your device.

Signed-off-by: Subrata Banik <subratabanik@google.com>
Change-Id: Ib837e4deeba9b84038a91c93a68f03cee3474f9b
Reviewed-on: https://review.coreboot.org/c/coreboot/+/71265
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Tarun Tuli <taruntuli@google.com>
This commit is contained in:
Subrata Banik 2022-12-26 21:39:59 +05:30
parent e51978f26f
commit 3e3b78a391
2 changed files with 56 additions and 9 deletions

View File

@ -256,23 +256,55 @@ vga_frame_set(unsigned int line, unsigned int character)
vga_cr_write(0x0D, offset & 0xFF); vga_cr_write(0x0D, offset & 0xFF);
} }
static void
vga_write_at_offset(unsigned int line, unsigned int offset, const char *string)
{
if (!string)
return;
unsigned short *p = (unsigned short *)VGA_FB + (VGA_COLUMNS * line) + offset;
size_t i, len = strlen(string);
for (i = 0; i < (VGA_COLUMNS - offset); i++) {
if (i < len)
p[i] = 0x0F00 | string[i];
else
p[i] = 0x0F00;
}
}
/* /*
* simply fills a line with the given string. * simply fills a line with the given string.
*/ */
void void
vga_line_write(unsigned int line, const char *string) vga_line_write(unsigned int line, const char *string)
{ {
if (!string) vga_write_at_offset(line, 0, string);
return; }
unsigned short *p = (unsigned short *)VGA_FB + (VGA_COLUMNS * line); void
size_t i, len = strlen(string); vga_write_text(enum VGA_TEXT_ALIGNMENT alignment, unsigned int line, const char *string)
{
char str[VGA_COLUMNS * VGA_LINES] = {0};
memcpy(str, string, strnlen(string, sizeof(str) - 1));
for (i = 0; i < VGA_COLUMNS; i++) { char *token = strtok(str, "\n");
if (i < len)
p[i] = 0x0F00 | string[i]; while (token != NULL) {
else size_t offset = VGA_COLUMNS - strnlen(token, VGA_COLUMNS);
p[i] = 0x0F00; switch (alignment) {
case VGA_TEXT_CENTER:
vga_write_at_offset(line++, offset/2, token);
break;
case VGA_TEXT_RIGHT:
vga_write_at_offset(line++, offset, token);
break;
case VGA_TEXT_LEFT:
default:
vga_write_at_offset(line++, 0, token);
break;
}
token = strtok(NULL, "\n");
} }
} }

View File

@ -8,6 +8,15 @@
#define VGA_COLUMNS 80 #define VGA_COLUMNS 80
#define VGA_LINES 25 #define VGA_LINES 25
#define VGA_TEXT_HORIZONTAL_TOP 0
#define VGA_TEXT_HORIZONTAL_MIDDLE (VGA_LINES / 2)
enum VGA_TEXT_ALIGNMENT {
VGA_TEXT_LEFT,
VGA_TEXT_CENTER,
VGA_TEXT_RIGHT,
};
void vga_io_init(void); void vga_io_init(void);
void vga_textmode_init(void); void vga_textmode_init(void);
@ -20,4 +29,10 @@ void vga_frame_set(unsigned int line, unsigned int character);
void vga_line_write(unsigned int line, const char *string); void vga_line_write(unsigned int line, const char *string);
/*
* vga_write_text() writes a line of text aligned left/center/right
* horizontally on the screen (i.e. enum VGA_TEXT_ALIGNMENT)
*/
void vga_write_text(enum VGA_TEXT_ALIGNMENT alignment, unsigned int line, const char *string);
#endif /* VGA_H */ #endif /* VGA_H */