Kernel: Restructure terminal initialization

This is still very ugly and will be rewritten in the future :D
This commit is contained in:
2025-04-18 01:19:59 +03:00
parent 439fb57d88
commit 554b13ac50
11 changed files with 85 additions and 53 deletions

View File

@@ -3,39 +3,42 @@
namespace Kernel
{
FramebufferTerminalDriver* FramebufferTerminalDriver::create(BAN::RefPtr<FramebufferDevice> framebuffer_device)
BAN::ErrorOr<BAN::RefPtr<FramebufferTerminalDriver>> FramebufferTerminalDriver::create(BAN::RefPtr<FramebufferDevice> framebuffer_device)
{
auto font = TRY(LibFont::Font::prefs());;
auto* driver = new FramebufferTerminalDriver(framebuffer_device);
if (driver == nullptr)
return nullptr;
return BAN::Error::from_errno(ENOMEM);
driver->m_font = BAN::move(font);
driver->set_cursor_position(0, 0);
driver->clear(TerminalColor::BLACK);
return driver;
return BAN::RefPtr<FramebufferTerminalDriver>::adopt(driver);
}
void FramebufferTerminalDriver::putchar_at(uint16_t ch, uint32_t x, uint32_t y, Color fg, Color bg)
{
const uint8_t* glyph = font().has_glyph(ch) ? font().glyph(ch) : font().glyph('?');
const uint8_t* glyph = m_font.has_glyph(ch) ? m_font.glyph(ch) : m_font.glyph('?');
x *= font().width();
y *= font().height();
x *= m_font.width();
y *= m_font.height();
for (uint32_t dy = 0; dy < font().height() && y + dy < m_framebuffer_device->height(); dy++)
for (uint32_t dy = 0; dy < m_font.height() && y + dy < m_framebuffer_device->height(); dy++)
{
for (uint32_t dx = 0; dx < font().width() && x + dx < m_framebuffer_device->width(); dx++)
for (uint32_t dx = 0; dx < m_font.width() && x + dx < m_framebuffer_device->width(); dx++)
{
const uint8_t bitmask = 1 << (font().width() - dx - 1);
const auto color = glyph[dy * font().pitch()] & bitmask ? fg : bg;
const uint8_t bitmask = 1 << (m_font.width() - dx - 1);
const auto color = glyph[dy * m_font.pitch()] & bitmask ? fg : bg;
m_framebuffer_device->set_pixel(x + dx, y + dy, color.rgb);
}
}
m_framebuffer_device->sync_pixels_rectangle(x, y, font().width(), font().height());
m_framebuffer_device->sync_pixels_rectangle(x, y, m_font.width(), m_font.height());
}
bool FramebufferTerminalDriver::scroll(Color color)
{
m_framebuffer_device->scroll(font().height(), color.rgb);
m_framebuffer_device->scroll(m_font.height(), color.rgb);
m_framebuffer_device->sync_pixels_full();
return true;
}
@@ -50,16 +53,16 @@ namespace Kernel
void FramebufferTerminalDriver::set_cursor_position(uint32_t x, uint32_t y)
{
const uint32_t cursor_h = font().height() / 8;
const uint32_t cursor_top = font().height() * 13 / 16;
const uint32_t cursor_h = m_font.height() / 8;
const uint32_t cursor_top = m_font.height() * 13 / 16;
x *= font().width();
y *= font().height();
x *= m_font.width();
y *= m_font.height();
for (uint32_t dy = 0; dy < cursor_h; dy++)
for (uint32_t dx = 0; dx < font().width(); dx++)
for (uint32_t dx = 0; dx < m_font.width(); dx++)
m_framebuffer_device->set_pixel(x + dx, y + cursor_top + dy, s_cursor_color.rgb);
m_framebuffer_device->sync_pixels_rectangle(x, y + cursor_top, font().width(), cursor_h);
m_framebuffer_device->sync_pixels_rectangle(x, y + cursor_top, m_font.width(), cursor_h);
}
}

View File

@@ -0,0 +1,25 @@
#include <kernel/BootInfo.h>
#include <kernel/Terminal/FramebufferTerminal.h>
namespace Kernel
{
BAN::RefPtr<TerminalDriver> g_terminal_driver;
BAN::ErrorOr<void> TerminalDriver::initialize_from_boot_info()
{
switch (g_boot_info.framebuffer.type)
{
case FramebufferInfo::Type::None:
case FramebufferInfo::Type::Unknown:
return BAN::Error::from_errno(ENODEV);
case FramebufferInfo::Type::RGB:
g_terminal_driver = TRY(FramebufferTerminalDriver::create(
TRY(FramebufferDevice::create_from_boot_framebuffer())
));
break;
}
return {};
}
}

View File

@@ -25,7 +25,7 @@ namespace Kernel
static BAN::Atomic<uint32_t> s_next_tty_number = 0;
BAN::ErrorOr<BAN::RefPtr<VirtualTTY>> VirtualTTY::create(TerminalDriver* driver)
BAN::ErrorOr<BAN::RefPtr<VirtualTTY>> VirtualTTY::create(BAN::RefPtr<TerminalDriver> driver)
{
auto* tty_ptr = new VirtualTTY(driver);
ASSERT(tty_ptr);
@@ -35,7 +35,7 @@ namespace Kernel
return tty;
}
VirtualTTY::VirtualTTY(TerminalDriver* driver)
VirtualTTY::VirtualTTY(BAN::RefPtr<TerminalDriver> driver)
: TTY(0600, 0, 0)
, m_name(MUST(BAN::String::formatted("tty{}", s_next_tty_number++)))
, m_terminal_driver(driver)
@@ -59,6 +59,12 @@ namespace Kernel
{
SpinLockGuard _(m_write_lock);
if (!m_terminal_driver->has_font())
{
dwarnln("terminal driver does not have a font");
return;
}
m_terminal_driver->set_font(font);
uint32_t new_width = m_terminal_driver->width();