1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-22 16:35:08 +00:00

Kernel: Implement scrolling critical messages in framebuffer console

This commit is contained in:
DaftMouse 2023-08-30 15:17:46 -03:00 committed by Andrew Kaster
parent df2bc8187c
commit 6f7f0b3a8c
5 changed files with 42 additions and 4 deletions

View file

@ -63,6 +63,8 @@ protected:
virtual void hide_cursor() = 0;
virtual void show_cursor() = 0;
virtual void scroll_up() = 0;
Console(size_t width, size_t height)
: m_width(width)
, m_height(height)

View file

@ -288,6 +288,22 @@ void GenericFramebufferConsoleImpl::disable()
m_enabled.store(false);
}
void GenericFramebufferConsoleImpl::scroll_up()
{
for (size_t row = 1; row < max_row(); row++) {
auto prev_line = framebuffer_offset(0, row - 1);
auto line = framebuffer_offset(0, row);
for (size_t glyph_row = 0; glyph_row < m_glyph_rows; glyph_row++) {
memmove(prev_line.pixels, line.pixels, width() * sizeof(*line.pixels));
prev_line.bytes += framebuffer_pitch();
line.bytes += framebuffer_pitch();
}
}
for (size_t column = 0; column < max_column(); column++)
clear_glyph(column, m_y);
}
void GenericFramebufferConsoleImpl::write(size_t x, size_t y, char ch, Color background, Color foreground, bool critical)
{
if (!m_enabled.load())
@ -298,15 +314,19 @@ void GenericFramebufferConsoleImpl::write(size_t x, size_t y, char ch, Color bac
if (critical && (ch == '\r' || ch == '\n')) {
m_x = 0;
m_y += 1;
if (m_y >= max_row())
m_y = 0;
if (m_y >= max_row()) {
m_y = max_row() - 1;
scroll_up();
}
return;
}
if ((int)ch < 0x20 || (int)ch == 0x7f) {
// FIXME: There's no point in printing empty glyphs...
// Maybe try to add these special glyphs and print them.
return;
}
clear_glyph(x, y);
auto bitmap = font_cathode_8x16[(int)ch];
auto offset_in_framebuffer = framebuffer_offset(x, y);
@ -322,14 +342,21 @@ void GenericFramebufferConsoleImpl::write(size_t x, size_t y, char ch, Color bac
offset_in_framebuffer.bytes += framebuffer_pitch();
}
flush_glyph(x, y);
m_x = x + 1;
if (m_x >= max_column()) {
m_x = 0;
m_y = y + 1;
if (m_y >= max_row())
if (m_y >= max_row()) {
if (critical) {
m_y = max_row() - 1;
scroll_up();
} else {
m_y = 0;
}
}
}
}
void GenericFramebufferConsoleImpl::flush_glyph(size_t x, size_t y)
{

View file

@ -39,6 +39,8 @@ protected:
virtual void hide_cursor() override;
virtual void show_cursor() override;
virtual void scroll_up() override;
GenericFramebufferConsoleImpl(size_t width, size_t height, size_t pitch)
: Console(width, height)
, m_pitch(pitch)

View file

@ -112,6 +112,11 @@ void VGATextModeConsole::clear(size_t x, size_t y, size_t length)
buf[index] = 0x0720;
}
}
void VGATextModeConsole::scroll_up()
{
}
void VGATextModeConsole::write(size_t x, size_t y, char ch, bool critical)
{
write(x, y, ch, m_default_background_color, m_default_foreground_color, critical);

View file

@ -34,6 +34,8 @@ private:
virtual void hide_cursor() override;
virtual void show_cursor() override;
virtual void scroll_up() override;
void clear_vga_row(u16 row);
explicit VGATextModeConsole(NonnullOwnPtr<Memory::Region>);