Kernel: Restructure terminal initialization
This is still very ugly and will be rewritten in the future :D
This commit is contained in:
parent
439fb57d88
commit
554b13ac50
|
@ -89,6 +89,7 @@ set(KERNEL_SOURCES
|
|||
kernel/Terminal/FramebufferTerminal.cpp
|
||||
kernel/Terminal/PseudoTerminal.cpp
|
||||
kernel/Terminal/Serial.cpp
|
||||
kernel/Terminal/TerminalDriver.cpp
|
||||
kernel/Terminal/TTY.cpp
|
||||
kernel/Terminal/VirtualTTY.cpp
|
||||
kernel/Thread.cpp
|
||||
|
|
|
@ -9,10 +9,10 @@ namespace Kernel
|
|||
class FramebufferTerminalDriver final : public TerminalDriver
|
||||
{
|
||||
public:
|
||||
static FramebufferTerminalDriver* create(BAN::RefPtr<FramebufferDevice>);
|
||||
static BAN::ErrorOr<BAN::RefPtr<FramebufferTerminalDriver>> create(BAN::RefPtr<FramebufferDevice>);
|
||||
|
||||
virtual uint32_t width() const override { return m_framebuffer_device->width() / font().width(); }
|
||||
virtual uint32_t height() const override { return m_framebuffer_device->height() / font().height(); }
|
||||
virtual uint32_t width() const override { return m_framebuffer_device->width() / m_font.width(); }
|
||||
virtual uint32_t height() const override { return m_framebuffer_device->height() / m_font.height(); }
|
||||
|
||||
virtual void putchar_at(uint16_t, uint32_t, uint32_t, Color, Color) override;
|
||||
virtual bool scroll(Color) override;
|
||||
|
@ -20,6 +20,11 @@ namespace Kernel
|
|||
|
||||
virtual void set_cursor_position(uint32_t, uint32_t) override;
|
||||
|
||||
virtual bool has_font() const override { return true; }
|
||||
|
||||
virtual void set_font(const LibFont::Font& font) override { m_font = font; };
|
||||
virtual const LibFont::Font& font() const override { return m_font; };
|
||||
|
||||
private:
|
||||
FramebufferTerminalDriver(BAN::RefPtr<FramebufferDevice> framebuffer_device)
|
||||
: m_framebuffer_device(framebuffer_device)
|
||||
|
@ -27,6 +32,7 @@ namespace Kernel
|
|||
|
||||
private:
|
||||
BAN::RefPtr<FramebufferDevice> m_framebuffer_device;
|
||||
LibFont::Font m_font;
|
||||
static constexpr Color s_cursor_color = TerminalColor::BRIGHT_WHITE;
|
||||
};
|
||||
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
#pragma once
|
||||
|
||||
#include <LibFont/Font.h>
|
||||
#include <BAN/RefPtr.h>
|
||||
|
||||
#include <stdint.h>
|
||||
#include <LibFont/Font.h>
|
||||
|
||||
namespace Kernel
|
||||
{
|
||||
|
||||
class TerminalDriver
|
||||
class TerminalDriver : public BAN::RefCounted<TerminalDriver>
|
||||
{
|
||||
public:
|
||||
struct Color
|
||||
|
@ -25,7 +25,7 @@ namespace Kernel
|
|||
};
|
||||
|
||||
public:
|
||||
TerminalDriver() : m_font(MUST(LibFont::Font::prefs())) {}
|
||||
static BAN::ErrorOr<void> initialize_from_boot_info();
|
||||
virtual ~TerminalDriver() {}
|
||||
virtual uint32_t width() const = 0;
|
||||
virtual uint32_t height() const = 0;
|
||||
|
@ -36,13 +36,13 @@ namespace Kernel
|
|||
|
||||
virtual void set_cursor_position(uint32_t, uint32_t) = 0;
|
||||
|
||||
void set_font(const LibFont::Font& font) { m_font = font; };
|
||||
const LibFont::Font& font() const { return m_font; }
|
||||
|
||||
private:
|
||||
LibFont::Font m_font;
|
||||
virtual bool has_font() const { return false; }
|
||||
virtual void set_font(const LibFont::Font&) { ASSERT_NOT_REACHED(); };
|
||||
virtual const LibFont::Font& font() const { ASSERT_NOT_REACHED(); };
|
||||
};
|
||||
|
||||
extern BAN::RefPtr<TerminalDriver> g_terminal_driver;
|
||||
|
||||
namespace TerminalColor
|
||||
{
|
||||
static constexpr TerminalDriver::Color BLACK = 0x000000;
|
||||
|
|
|
@ -12,7 +12,7 @@ namespace Kernel
|
|||
class VirtualTTY : public TTY
|
||||
{
|
||||
public:
|
||||
static BAN::ErrorOr<BAN::RefPtr<VirtualTTY>> create(TerminalDriver*);
|
||||
static BAN::ErrorOr<BAN::RefPtr<VirtualTTY>> create(BAN::RefPtr<TerminalDriver>);
|
||||
|
||||
virtual void set_font(const LibFont::Font&) override;
|
||||
|
||||
|
@ -26,7 +26,7 @@ namespace Kernel
|
|||
virtual void putchar_impl(uint8_t ch) override;
|
||||
|
||||
private:
|
||||
VirtualTTY(TerminalDriver*);
|
||||
VirtualTTY(BAN::RefPtr<TerminalDriver>);
|
||||
|
||||
void reset_ansi();
|
||||
void handle_ansi_csi(uint8_t ch);
|
||||
|
@ -84,7 +84,7 @@ namespace Kernel
|
|||
Cell* m_buffer { nullptr };
|
||||
bool m_show_cursor { true };
|
||||
|
||||
TerminalDriver* m_terminal_driver { nullptr };
|
||||
BAN::RefPtr<TerminalDriver> m_terminal_driver;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
#include <ctype.h>
|
||||
|
||||
bool g_disable_debug = false;
|
||||
extern Kernel::TerminalDriver* g_terminal_driver;
|
||||
|
||||
namespace Debug
|
||||
{
|
||||
|
|
|
@ -3,14 +3,12 @@
|
|||
#include <kernel/Device/FramebufferDevice.h>
|
||||
#include <kernel/FS/DevFS/FileSystem.h>
|
||||
#include <kernel/Memory/Heap.h>
|
||||
#include <kernel/Terminal/TerminalDriver.h>
|
||||
#include <kernel/Terminal/FramebufferTerminal.h>
|
||||
|
||||
#include <sys/framebuffer.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/sysmacros.h>
|
||||
|
||||
extern Kernel::TerminalDriver* g_terminal_driver;
|
||||
|
||||
namespace Kernel
|
||||
{
|
||||
|
||||
|
@ -22,8 +20,7 @@ namespace Kernel
|
|||
|
||||
BAN::ErrorOr<BAN::RefPtr<FramebufferDevice>> FramebufferDevice::create_from_boot_framebuffer()
|
||||
{
|
||||
if (g_boot_info.framebuffer.type != FramebufferInfo::Type::RGB)
|
||||
return BAN::Error::from_errno(ENODEV);
|
||||
ASSERT(g_boot_info.framebuffer.type == FramebufferInfo::Type::RGB);
|
||||
if (g_boot_info.framebuffer.bpp != 24 && g_boot_info.framebuffer.bpp != 32)
|
||||
return BAN::Error::from_errno(ENOTSUP);
|
||||
auto* device_ptr = new FramebufferDevice(
|
||||
|
@ -39,6 +36,7 @@ namespace Kernel
|
|||
return BAN::Error::from_errno(ENOMEM);
|
||||
auto device = BAN::RefPtr<FramebufferDevice>::adopt(device_ptr);
|
||||
TRY(device->initialize());
|
||||
DevFileSystem::get().add_device(device);
|
||||
return device;
|
||||
}
|
||||
|
||||
|
@ -315,6 +313,8 @@ namespace Kernel
|
|||
|
||||
const uint32_t fb_width = m_framebuffer->width();
|
||||
|
||||
// If we are here (in FramebufferMemoryRegion), our terminal driver is FramebufferTerminalDriver
|
||||
ASSERT(g_terminal_driver->has_font());
|
||||
const auto& font = g_terminal_driver->font();
|
||||
|
||||
const uint32_t x = first_pixel % fb_width;
|
||||
|
|
|
@ -5,8 +5,6 @@
|
|||
#include <kernel/Thread.h>
|
||||
#include <kernel/Timer/Timer.h>
|
||||
|
||||
extern Kernel::TerminalDriver* g_terminal_driver;
|
||||
|
||||
namespace Kernel
|
||||
{
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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 {};
|
||||
}
|
||||
|
||||
}
|
|
@ -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();
|
||||
|
|
|
@ -107,8 +107,6 @@ static void parse_command_line()
|
|||
}
|
||||
}
|
||||
|
||||
Kernel::TerminalDriver* g_terminal_driver = nullptr;
|
||||
|
||||
static void init2(void*);
|
||||
|
||||
extern "C" void kernel_main(uint32_t boot_magic, uint32_t boot_info)
|
||||
|
@ -163,14 +161,10 @@ extern "C" void kernel_main(uint32_t boot_magic, uint32_t boot_info)
|
|||
DevFileSystem::initialize();
|
||||
dprintln("devfs initialized");
|
||||
|
||||
auto framebuffer_device = FramebufferDevice::create_from_boot_framebuffer();
|
||||
if (!framebuffer_device.is_error())
|
||||
{
|
||||
DevFileSystem::get().add_device(framebuffer_device.value());
|
||||
g_terminal_driver = FramebufferTerminalDriver::create(framebuffer_device.value());
|
||||
}
|
||||
if (g_terminal_driver)
|
||||
dprintln("Framebuffer terminal initialized");
|
||||
if (auto ret = TerminalDriver::initialize_from_boot_info(); ret.is_error())
|
||||
dprintln("failed to initialize terminal driver: {}", ret.error());
|
||||
else
|
||||
dprintln("terminal driver initialized");
|
||||
|
||||
if (!cmdline.disable_smp)
|
||||
InterruptController::get().initialize_multiprocessor();
|
||||
|
|
Loading…
Reference in New Issue