bootloader: Refactor console functions into the VFS ConsoleNode class.

This way it becomes much easier to write multiple console implementations
in one bootloader.

Tested for bios_ia32 and efi.

Change-Id: I67134f5c3de109b15d46898864ba7f51c6592afc
Reviewed-on: https://review.haiku-os.org/c/haiku/+/4642
Tested-by: Commit checker robot <no-reply+buildbot@haiku-os.org>
Reviewed-by: waddlesplash <waddlesplash@gmail.com>
This commit is contained in:
Augustin Cavalier 2021-10-22 11:40:40 -04:00 committed by waddlesplash
parent f6f9c751d6
commit 5e43707307
9 changed files with 235 additions and 246 deletions

View File

@ -89,6 +89,13 @@ class ConsoleNode : public Node {
virtual ssize_t Read(void *buffer, size_t bufferSize);
virtual ssize_t Write(const void *buffer, size_t bufferSize);
virtual void ClearScreen() = 0;
virtual int32 Width() = 0;
virtual int32 Height() = 0;
virtual void SetCursor(int32 x, int32 y) = 0;
virtual void SetCursorVisible(bool visible) = 0;
virtual void SetColors(int32 foreground, int32 background) = 0;
};

View File

@ -22,6 +22,13 @@ class Console : public ConsoleNode {
virtual ssize_t ReadAt(void *cookie, off_t pos, void *buffer, size_t bufferSize);
virtual ssize_t WriteAt(void *cookie, off_t pos, const void *buffer, size_t bufferSize);
virtual void ClearScreen();
virtual int32 Width();
virtual int32 Height();
virtual void SetCursor(int32 x, int32 y);
virtual void SetCursorVisible(bool visible);
virtual void SetColors(int32 foreground, int32 background);
};
static uint16 *sScreenBase = (uint16 *)0xb8000;
@ -30,7 +37,8 @@ static uint32 sScreenHeight = 25;
static uint32 sScreenOffset = 0;
static uint16 sColor = 0x0f00;
static Console sInput, sOutput;
extern ConsoleNode* gConsoleNode;
static Console sConsole;
FILE *stdin, *stdout, *stderr;
@ -87,11 +95,8 @@ Console::WriteAt(void *cookie, off_t /*pos*/, const void *buffer, size_t bufferS
}
// #pragma mark -
void
console_clear_screen(void)
Console::ClearScreen()
{
if (gKernelArgs.frame_buffer.enabled)
return;
@ -105,21 +110,21 @@ console_clear_screen(void)
int32
console_width(void)
Console::Width()
{
return sScreenWidth;
}
int32
console_height(void)
Console::Height()
{
return sScreenHeight;
}
void
console_set_cursor(int32 x, int32 y)
Console::SetCursor(int32 x, int32 y)
{
if (y >= (int32)sScreenHeight)
y = sScreenHeight - 1;
@ -136,21 +141,17 @@ console_set_cursor(int32 x, int32 y)
void
console_show_cursor(void)
Console::SetCursorVisible(bool visible)
{
video_show_text_cursor();
if (visible)
video_show_text_cursor();
else
video_hide_text_cursor();
}
void
console_hide_cursor(void)
{
video_hide_text_cursor();
}
void
console_set_color(int32 foreground, int32 background)
Console::SetColors(int32 foreground, int32 background)
{
sColor = (background & 0xf) << 12 | (foreground & 0xf) << 8;
}
@ -192,11 +193,13 @@ console_init(void)
{
// ToDo: make screen size changeable via stage2_args
gConsoleNode = &sConsole;
console_clear_screen();
// enable stdio functionality
stdin = (FILE *)&sInput;
stdout = stderr = (FILE *)&sOutput;
stdin = (FILE *)&sConsole;
stdout = stderr = (FILE *)&sConsole;
return B_OK;
}

View File

@ -30,42 +30,51 @@
#endif
class Console : public ConsoleNode {
class EFITextConsole : public ConsoleNode {
public:
Console();
EFITextConsole();
virtual ssize_t ReadAt(void *cookie, off_t pos, void *buffer,
size_t bufferSize);
virtual ssize_t WriteAt(void *cookie, off_t pos, const void *buffer,
size_t bufferSize);
virtual void ClearScreen();
virtual int32 Width();
virtual int32 Height();
virtual void SetCursor(int32 x, int32 y);
virtual void SetCursorVisible(bool visible);
virtual void SetColors(int32 foreground, int32 background);
public:
uint32 fScreenWidth, fScreenHeight;
};
static uint32 sScreenWidth;
static uint32 sScreenHeight;
extern ConsoleNode* gConsoleNode;
static uint32 sScreenMode;
static Console sInput, sOutput;
static EFITextConsole sConsole;
FILE *stdin, *stdout, *stderr;
// #pragma mark -
Console::Console()
EFITextConsole::EFITextConsole()
: ConsoleNode()
{
}
ssize_t
Console::ReadAt(void *cookie, off_t pos, void *buffer, size_t bufferSize)
EFITextConsole::ReadAt(void *cookie, off_t pos, void *buffer, size_t bufferSize)
{
return B_ERROR;
}
ssize_t
Console::WriteAt(void *cookie, off_t /*pos*/, const void *buffer,
EFITextConsole::WriteAt(void *cookie, off_t /*pos*/, const void *buffer,
size_t bufferSize)
{
const char *string = (const char *)buffer;
@ -100,53 +109,43 @@ Console::WriteAt(void *cookie, off_t /*pos*/, const void *buffer,
}
// #pragma mark -
void
console_clear_screen(void)
EFITextConsole::ClearScreen()
{
kSystemTable->ConOut->ClearScreen(kSystemTable->ConOut);
}
int32
console_width(void)
EFITextConsole::Width()
{
return sScreenWidth;
return fScreenWidth;
}
int32
console_height(void)
EFITextConsole::Height()
{
return sScreenHeight;
return fScreenHeight;
}
void
console_set_cursor(int32 x, int32 y)
EFITextConsole::SetCursor(int32 x, int32 y)
{
kSystemTable->ConOut->SetCursorPosition(kSystemTable->ConOut, x, y);
}
void
console_show_cursor(void)
EFITextConsole::SetCursorVisible(bool visible)
{
kSystemTable->ConOut->EnableCursor(kSystemTable->ConOut, true);
kSystemTable->ConOut->EnableCursor(kSystemTable->ConOut, visible);
}
void
console_hide_cursor(void)
{
kSystemTable->ConOut->EnableCursor(kSystemTable->ConOut, false);
}
void
console_set_color(int32 foreground, int32 background)
EFITextConsole::SetColors(int32 foreground, int32 background)
{
kSystemTable->ConOut->SetAttribute(kSystemTable->ConOut,
EFI_TEXT_ATTR((foreground & 0xf), (background & 0xf)));
@ -202,8 +201,8 @@ static void update_screen_size(void)
for (int mode = 0; mode < ConOut->Mode->MaxMode; ++mode) {
if (ConOut->QueryMode(ConOut, mode, &width, &height) == EFI_SUCCESS) {
if (width * height > area) {
sScreenWidth = width;
sScreenHeight = height;
sConsole.fScreenWidth = width;
sConsole.fScreenHeight = height;
sScreenMode = mode;
}
}
@ -216,13 +215,15 @@ static void update_screen_size(void)
status_t
console_init(void)
{
gConsoleNode = &sConsole;
update_screen_size();
console_hide_cursor();
console_clear_screen();
// enable stdio functionality
stdin = (FILE *)&sInput;
stdout = stderr = (FILE *)&sOutput;
stdin = (FILE *)&sConsole;
stdout = stderr = (FILE *)&sConsole;
return B_OK;
}

View File

@ -9,6 +9,7 @@ local platform ;
for platform in [ MultiBootSubDirSetup ] {
on $(platform) {
BootStaticLibrary boot_platform_generic_$(platform:G=) :
text_console.cpp
text_menu.cpp
video_blit.cpp
video_splash.cpp
@ -17,4 +18,4 @@ for platform in [ MultiBootSubDirSetup ] {
Includes [ FGristFiles video_splash.cpp ]
: [ BuildFeatureAttribute zlib : headers ] ;
}
}
}

View File

@ -0,0 +1,61 @@
/*
* Copyright 2021, Haiku, Inc. All rights reserved.
* Distributed under the terms of the MIT License.
*/
#include <boot/platform/generic/text_console.h>
#include <boot/vfs.h>
// This is set by the boot platform during console_init().
ConsoleNode* gConsoleNode;
void
console_clear_screen()
{
gConsoleNode->ClearScreen();
}
int32
console_width()
{
return gConsoleNode->Width();
}
int32
console_height()
{
return gConsoleNode->Height();
}
void
console_set_cursor(int32 x, int32 y)
{
gConsoleNode->SetCursor(x, y);
}
void
console_show_cursor()
{
gConsoleNode->SetCursorVisible(true);
}
void
console_hide_cursor(void)
{
gConsoleNode->SetCursorVisible(false);
}
void
console_set_color(int32 foreground, int32 background)
{
gConsoleNode->SetColors(foreground, background);
}

View File

@ -29,7 +29,7 @@ static bool sShowCursor;
static int32 sCursorX, sCursorY;
static int32 sScreenWidth, sScreenHeight;
static Console sInput, sOutput;
static Console sConsole;
FILE *stdin, *stdout, *stderr;
@ -153,8 +153,8 @@ video_text_console_init(addr_t frameBuffer)
console_clear_screen();
// enable stdio functionality
stdin = (FILE *)&sInput;
stdout = stderr = (FILE *)&sOutput;
stdin = (FILE *)&sConsole;
stdout = stderr = (FILE *)&sConsole;
return B_OK;
}

View File

@ -29,14 +29,17 @@ class Console : public ConsoleNode {
virtual ssize_t WriteAt(void *cookie, off_t pos, const void *buffer,
size_t bufferSize);
void PutChar(char c);
void PutChars(const char *buffer, int count);
char GetChar();
virtual void ClearScreen();
virtual int32 Width();
virtual int32 Height();
virtual void SetCursor(int32 x, int32 y);
virtual void SetCursorVisible(bool visible);
virtual void SetColors(int32 foreground, int32 background);
};
static Console sInput;
static Console sOutput;
extern ConsoleNode* gConsoleNode;
static Console sConsole;
FILE *stdin, *stdout, *stderr;
@ -81,71 +84,14 @@ Console::WriteAt(void */*cookie*/, off_t /*pos*/, const void *buffer,
void
Console::PutChar(char c)
Console::ClearScreen()
{
mg->mg_putc(c);
}
void
Console::PutChars(const char *buffer, int count)
{
for (int i = 0; i < count; i++)
mg->mg_putc(buffer[i]);
}
char
Console::GetChar()
{
return (char)(mg->mg_getc());
}
// #pragma mark -
static void
dump_colors()
{
int bg, fg;
dprintf("colors:\n");
for (bg = 0; bg < 16; bg++) {
for (fg = 0; fg < 16; fg++) {
console_set_color(fg, bg);
dprintf("#");
}
console_set_color(0, 15);
dprintf("\n");
}
}
status_t
console_init(void)
{
// now that we're initialized, enable stdio functionality
stdin = (FILE *)&sInput;
stdout = stderr = (FILE *)&sOutput;
//dump_colors();
return B_OK;
}
// #pragma mark -
void
console_clear_screen(void)
{
sInput.WriteAt(NULL, 0LL, "\033E", 2);
sConsole.WriteAt(NULL, 0LL, "\033E", 2);
}
int32
console_width(void)
Console::Width()
{
int columnCount = 80; //XXX: check video mode
return columnCount;
@ -153,7 +99,7 @@ console_width(void)
int32
console_height(void)
Console::Height()
{
int lineCount = 25; //XXX: check video mode
return lineCount;
@ -161,14 +107,14 @@ console_height(void)
void
console_set_cursor(int32 x, int32 y)
Console::SetCursor(int32 x, int32 y)
{
char buff[] = "\033Y ";
x = MIN(79,MAX(0,x));
y = MIN(24,MAX(0,y));
buff[3] += (char)x;
buff[2] += (char)y;
sInput.WriteAt(NULL, 0LL, buff, 4);
sConsole.WriteAt(NULL, 0LL, buff, 4);
}
@ -207,36 +153,67 @@ translate_color(int32 color)
void
console_set_color(int32 foreground, int32 background)
Console::SetColors(int32 foreground, int32 background)
{
char buff[] = "\033b \033c ";
if (sForceBW) {
if (background == 0)
if (background == 0) {
foreground = 15;
else {
} else {
background = 15;
foreground = 0;
}
}
buff[2] += (char)translate_color(foreground);
buff[5] += (char)translate_color(background);
sInput.WriteAt(NULL, 0LL, buff, 6);
sConsole.WriteAt(NULL, 0LL, buff, 6);
}
void
console_show_cursor(void)
Console::SetCursorVisible(bool)
{
// TODO?
}
void
console_hide_cursor(void)
// #pragma mark -
static void
dump_colors()
{
int bg, fg;
dprintf("colors:\n");
for (bg = 0; bg < 16; bg++) {
for (fg = 0; fg < 16; fg++) {
console_set_color(fg, bg);
dprintf("#");
}
console_set_color(0, 15);
dprintf("\n");
}
}
status_t
console_init(void)
{
gConsoleNode = &sConsole;
// now that we're initialized, enable stdio functionality
stdin = (FILE *)&sConsole;
stdout = stderr = (FILE *)&sConsole;
//dump_colors();
return B_OK;
}
// #pragma mark -
int
console_wait_for_key(void)
{
@ -246,7 +223,7 @@ console_wait_for_key(void)
char buffer[3];
ssize_t bytesRead;
do {
bytesRead = sInput.ReadAt(NULL, 0, buffer, 3);
bytesRead = sConsole.ReadAt(NULL, 0, buffer, 3);
if (bytesRead < 0)
return 0;
} while (bytesRead == 0);
@ -273,4 +250,3 @@ console_wait_for_key(void)
} else
return key.code.ascii;
}

View File

@ -19,13 +19,20 @@
class Console : public ConsoleNode {
public:
public:
Console();
virtual ssize_t ReadAt(void *cookie, off_t pos, void *buffer,
size_t bufferSize);
virtual ssize_t WriteAt(void *cookie, off_t pos, const void *buffer,
size_t bufferSize);
virtual void ClearScreen();
virtual int32 Width();
virtual int32 Height();
virtual void SetCursor(int32 x, int32 y);
virtual void SetCursorVisible(bool visible);
virtual void SetColors(int32 foreground, int32 background);
};
static uint16* sScreenBase;
@ -36,7 +43,8 @@ static uint32 sScreenHeight = 25;
static uint32 sScreenOffset = 0;
static uint16 sColor = 0x0f00;
static Console sInput, sOutput;
extern ConsoleNode* gConsoleNode;
static Console sConsole;
FILE *stdin, *stdout, *stderr;
@ -138,11 +146,8 @@ Console::WriteAt(void *cookie, off_t /*pos*/, const void *buffer,
}
// #pragma mark -
void
console_clear_screen(void)
Console::ClearScreen()
{
if (gKernelArgs.frame_buffer.enabled)
return;
@ -158,21 +163,21 @@ console_clear_screen(void)
int32
console_width(void)
Console::Width()
{
return sScreenWidth;
}
int32
console_height(void)
Console::Height()
{
return sScreenHeight;
}
void
console_set_cursor(int32 x, int32 y)
Console::SetCursor(int32 x, int32 y)
{
if (y >= (int32)sScreenHeight)
y = sScreenHeight - 1;
@ -188,21 +193,14 @@ console_set_cursor(int32 x, int32 y)
void
console_show_cursor(void)
Console::SetCursorVisible(bool)
{
// TODO: implement
}
void
console_hide_cursor(void)
{
// TODO: implement
}
void
console_set_color(int32 foreground, int32 background)
Console::SetColors(int32 foreground, int32 background)
{
sColor = (background & 0xf) << 12 | (foreground & 0xf) << 8;
}
@ -244,11 +242,12 @@ console_init(void)
sScreenBase = new(std::nothrow) uint16[sScreenWidth * sScreenHeight];
console_clear_screen();
sConsole.ClearScreen();
// enable stdio functionality
stdin = (FILE *)&sInput;
stdout = stderr = (FILE *)&sOutput;
gConsoleNode = &sConsole;
stdin = (FILE *)&sConsole;
stdout = stderr = (FILE *)&sConsole;
return B_OK;
}

View File

@ -18,23 +18,16 @@
#include <string.h>
class Console : public ConsoleNode {
public:
Console();
virtual ssize_t ReadAt(void* cookie, off_t pos, void* buffer,
size_t bufferSize);
virtual ssize_t WriteAt(void* cookie, off_t pos,
const void* buffer, size_t bufferSize);
};
class VTConsole : public ConsoleNode {
public:
VTConsole();
void ClearScreen();
void SetCursor(int32 x, int32 y);
void SetColor(int32 foreground, int32 background);
virtual void ClearScreen();
virtual int32 Width();
virtual int32 Height();
virtual void SetCursor(int32 x, int32 y);
virtual void SetCursorVisible(bool visible);
virtual void SetColors(int32 foreground, int32 background);
};
@ -49,8 +42,7 @@ public:
};
static Console sInput;
static Console sOutput;
extern ConsoleNode* gConsoleNode;
static SerialConsole sSerial;
FILE* stdin;
@ -61,33 +53,6 @@ FILE* stderr;
// #pragma mark -
Console::Console()
:
ConsoleNode()
{
}
ssize_t
Console::ReadAt(void* cookie, off_t pos, void* buffer, size_t bufferSize)
{
// don't seek in character devices
// not implemented (and not yet? needed)
return B_ERROR;
}
ssize_t
Console::WriteAt(void* cookie, off_t /*pos*/, const void* buffer,
size_t bufferSize)
{
return 0;
}
// #pragma mark -
VTConsole::VTConsole()
:
ConsoleNode()
@ -102,6 +67,22 @@ VTConsole::ClearScreen()
}
int32
VTConsole::Width()
{
// TODO?
return 80;
}
int32
VTConsole::Height()
{
// TODO?
return 25;
}
void
VTConsole::SetCursor(int32 x, int32 y)
{
@ -115,7 +96,14 @@ VTConsole::SetCursor(int32 x, int32 y)
void
VTConsole::SetColor(int32 foreground, int32 background)
VTConsole::SetCursorVisible(bool visible)
{
// TODO?
}
void
VTConsole::SetColors(int32 foreground, int32 background)
{
static const char cmap[] = {
0, 4, 2, 6, 1, 5, 3, 7 };
@ -165,46 +153,6 @@ SerialConsole::WriteAt(void *cookie, off_t /*pos*/, const void *buffer,
// #pragma mark -
void
console_clear_screen(void)
{
sSerial.ClearScreen();
}
int32
console_width(void)
{
return 80;
}
int32
console_height(void)
{
return 25;
}
void
console_set_cursor(int32 x, int32 y)
{
sSerial.SetCursor(x, y);
}
void
console_show_cursor(void)
{
}
void
console_hide_cursor(void)
{
}
int
console_wait_for_key(void)
{
@ -214,19 +162,12 @@ console_wait_for_key(void)
}
void
console_set_color(int32 foreground, int32 background)
{
sSerial.SetColor(foreground, background);
}
status_t
console_init(void)
{
gConsoleNode = &sSerial;
stdin = (FILE *)&sSerial;
stdout = (FILE *)&sSerial;
stderr = (FILE *)&sSerial;
return B_OK;
}