From 0d66d8d486e9e37607aa7ba9e18e2676b3ca308a Mon Sep 17 00:00:00 2001 From: Augustin Cavalier Date: Fri, 22 Oct 2021 10:40:59 -0400 Subject: [PATCH] boot_loader: Add a video_text_console for potential use by bootloaders. This uses the frame buffer console that KDL uses. It needs some work, though, as the frame_buffer_console colors system is not quite compatible. --- .../kernel/boot/platform/generic/video.h | 3 + .../platform/generic/video_text_console.cpp | 160 ++++++++++++++++++ src/system/kernel/debug/blue_screen.cpp | 8 - .../kernel/debug/frame_buffer_console.cpp | 7 + 4 files changed, 170 insertions(+), 8 deletions(-) create mode 100644 src/system/boot/platform/generic/video_text_console.cpp diff --git a/headers/private/kernel/boot/platform/generic/video.h b/headers/private/kernel/boot/platform/generic/video.h index b157372b90..d7fe344efc 100644 --- a/headers/private/kernel/boot/platform/generic/video.h +++ b/headers/private/kernel/boot/platform/generic/video.h @@ -34,6 +34,9 @@ void uncompress_8bit_RLE(const uint8 compressed[], uint8 *uncompressed); /* default splash display */ status_t video_display_splash(addr_t frameBuffer); +/* video text console */ +status_t video_text_console_init(addr_t frameBuffer); + #ifdef __cplusplus } #endif diff --git a/src/system/boot/platform/generic/video_text_console.cpp b/src/system/boot/platform/generic/video_text_console.cpp new file mode 100644 index 0000000000..fa958268aa --- /dev/null +++ b/src/system/boot/platform/generic/video_text_console.cpp @@ -0,0 +1,160 @@ +/* + * Copyright 2021, Haiku, Inc. All rights reserved. + * Distributed under the terms of the MIT License. + */ + +#include +#include +#include + +#include + + +extern console_module_info gFrameBufferConsoleModule; + + +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); +}; + + +static uint16 sColor = 0x0f00; +static bool sShowCursor; +static int32 sCursorX, sCursorY; +static int32 sScreenWidth, sScreenHeight; + +static Console sInput, sOutput; +FILE *stdin, *stdout, *stderr; + + +// #pragma mark - + + +Console::Console() + : ConsoleNode() +{ +} + + +ssize_t +Console::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, + size_t bufferSize) +{ + const char *string = (const char *)buffer; + for (size_t i = 0; i < bufferSize; i++) { + const char c = string[i]; + if (c == '\n' || sCursorX >= sScreenWidth) { + sCursorX = 0; + if (sCursorY == (sScreenHeight - 1)) { + // Move the screen up and clear the bottom line. + gFrameBufferConsoleModule.blit(0, 1, sScreenWidth, 0, + 0, sScreenHeight - 1); + gFrameBufferConsoleModule.fill_glyph(0, sCursorY, sScreenWidth, + 1, ' ', sColor); + } else { + sCursorY++; + } + } + + switch (c) { + case '\n': + // already handled above + break; + + default: + gFrameBufferConsoleModule.put_glyph(sCursorX, sCursorY, c, sColor); + break; + } + sCursorX++; + } + return bufferSize; +} + + +// #pragma mark - + + +void +console_clear_screen(void) +{ + gFrameBufferConsoleModule.clear(sColor); +} + + +int32 +console_width(void) +{ + return sScreenWidth; +} + + +int32 +console_height() +{ + return sScreenHeight; +} + + +void +console_set_cursor(int32 x, int32 y) +{ + sCursorX = x; + sCursorY = y; + if (sShowCursor) + console_show_cursor(); +} + + +void +console_show_cursor() +{ + sShowCursor = true; + gFrameBufferConsoleModule.move_cursor(sCursorX, sCursorY); +} + + +void +console_hide_cursor() +{ + sShowCursor = false; + gFrameBufferConsoleModule.move_cursor(-1, -1); +} + + +void +console_set_color(int32 foreground, int32 background) +{ + sColor = (background & 0xf) << 4 | (foreground & 0xf); +} + + +status_t +video_text_console_init(addr_t frameBuffer) +{ + frame_buffer_update(frameBuffer, gKernelArgs.frame_buffer.width, + gKernelArgs.frame_buffer.height, gKernelArgs.frame_buffer.depth, + gKernelArgs.frame_buffer.bytes_per_row); + gFrameBufferConsoleModule.get_size(&sScreenWidth, &sScreenHeight); + + console_hide_cursor(); + console_clear_screen(); + + // enable stdio functionality + stdin = (FILE *)&sInput; + stdout = stderr = (FILE *)&sOutput; + + return B_OK; +} diff --git a/src/system/kernel/debug/blue_screen.cpp b/src/system/kernel/debug/blue_screen.cpp index e298cf05e4..3cfa6f8be1 100644 --- a/src/system/kernel/debug/blue_screen.cpp +++ b/src/system/kernel/debug/blue_screen.cpp @@ -568,7 +568,6 @@ parse_character(char c) } -#ifndef _BOOT_MODE static int set_paging(int argc, char **argv) { @@ -589,7 +588,6 @@ set_paging(int argc, char **argv) kprintf("paging is turned %s now.\n", sScreen.paging ? "on" : "off"); return 0; } -#endif // !_BOOT_MODE // #pragma mark - @@ -606,15 +604,11 @@ blue_screen_init(void) return B_ERROR; sModule = &gFrameBufferConsoleModule; -#ifdef _BOOT_MODE - sScreen.paging = false; -#else sScreen.paging = !get_safemode_boolean( "disable_onscreen_paging", false); sScreen.paging_timeout = false; add_debugger_command("paging", set_paging, "Enable or disable paging"); -#endif return B_OK; } @@ -665,7 +659,6 @@ blue_screen_clear_screen(void) } -#ifndef _BOOT_MODE int blue_screen_try_getchar(void) { @@ -678,7 +671,6 @@ blue_screen_getchar(void) { return arch_debug_blue_screen_getchar(); } -#endif void diff --git a/src/system/kernel/debug/frame_buffer_console.cpp b/src/system/kernel/debug/frame_buffer_console.cpp index 34d3023e58..40b9f796e0 100644 --- a/src/system/kernel/debug/frame_buffer_console.cpp +++ b/src/system/kernel/debug/frame_buffer_console.cpp @@ -24,6 +24,13 @@ #include #include +#else +#define mutex_lock(...) +#define mutex_unlock(...) +#undef set_ac +#undef clear_ac +#define set_ac() +#define clear_ac() #endif #include "font.h"