mirror of
https://github.com/RGBCube/serenity
synced 2025-07-27 17:37:34 +00:00
Kernel: Move all Graphics-related code into Devices/GPU directory
Like the HID, Audio and Storage subsystem, the Graphics subsystem (which handles GPUs technically) exposes unix device files (typically in /dev). To ensure consistency across the repository, move all related files to a new directory under Kernel/Devices called "GPU". Also remove the redundant "GPU" word from the VirtIO driver directory, and the word "Graphics" from GraphicsManagement.{h,cpp} filenames.
This commit is contained in:
parent
31a7dabf02
commit
9ee098b119
69 changed files with 167 additions and 167 deletions
91
Kernel/Devices/GPU/Console/BootFramebufferConsole.cpp
Normal file
91
Kernel/Devices/GPU/Console/BootFramebufferConsole.cpp
Normal file
|
@ -0,0 +1,91 @@
|
|||
/*
|
||||
* Copyright (c) 2022, the SerenityOS developers.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <Kernel/Devices/GPU/Console/BootFramebufferConsole.h>
|
||||
#include <Kernel/Locking/Spinlock.h>
|
||||
#include <Kernel/Memory/MemoryManager.h>
|
||||
|
||||
namespace Kernel::Graphics {
|
||||
|
||||
BootFramebufferConsole::BootFramebufferConsole(PhysicalAddress framebuffer_addr, size_t width, size_t height, size_t pitch)
|
||||
: GenericFramebufferConsoleImpl(width, height, pitch)
|
||||
{
|
||||
// NOTE: We're very early in the boot process, memory allocations shouldn't really fail
|
||||
auto framebuffer_end = Memory::page_round_up(framebuffer_addr.offset(height * pitch).get()).release_value();
|
||||
m_framebuffer = MM.allocate_kernel_region(framebuffer_addr.page_base(), framebuffer_end - framebuffer_addr.page_base().get(), "Boot Framebuffer"sv, Memory::Region::Access::ReadWrite).release_value();
|
||||
|
||||
[[maybe_unused]] auto result = m_framebuffer->set_write_combine(true);
|
||||
m_framebuffer_data = m_framebuffer->vaddr().offset(framebuffer_addr.offset_in_page()).as_ptr();
|
||||
memset(m_framebuffer_data, 0, height * pitch);
|
||||
}
|
||||
|
||||
void BootFramebufferConsole::clear(size_t x, size_t y, size_t length)
|
||||
{
|
||||
SpinlockLocker lock(m_lock);
|
||||
if (m_framebuffer_data)
|
||||
GenericFramebufferConsoleImpl::clear(x, y, length);
|
||||
}
|
||||
|
||||
void BootFramebufferConsole::clear_glyph(size_t x, size_t y)
|
||||
{
|
||||
|
||||
VERIFY(m_lock.is_locked());
|
||||
GenericFramebufferConsoleImpl::clear_glyph(x, y);
|
||||
}
|
||||
|
||||
void BootFramebufferConsole::enable()
|
||||
{
|
||||
// Once disabled, ignore requests to re-enable
|
||||
}
|
||||
|
||||
void BootFramebufferConsole::disable()
|
||||
{
|
||||
SpinlockLocker lock(m_lock);
|
||||
GenericFramebufferConsoleImpl::disable();
|
||||
m_framebuffer = nullptr;
|
||||
m_framebuffer_data = nullptr;
|
||||
}
|
||||
|
||||
void BootFramebufferConsole::write(size_t x, size_t y, char ch, Color background, Color foreground, bool critical)
|
||||
{
|
||||
SpinlockLocker lock(m_lock);
|
||||
if (m_framebuffer_data)
|
||||
GenericFramebufferConsoleImpl::write(x, y, ch, background, foreground, critical);
|
||||
}
|
||||
|
||||
void BootFramebufferConsole::set_cursor(size_t x, size_t y)
|
||||
{
|
||||
// Note: To ensure we don't trigger a deadlock, let's assert in
|
||||
// case we already locked the spinlock, so we know there's a bug
|
||||
// in the call path.
|
||||
VERIFY(!m_lock.is_locked());
|
||||
SpinlockLocker lock(m_lock);
|
||||
hide_cursor();
|
||||
m_x = x;
|
||||
m_y = y;
|
||||
show_cursor();
|
||||
}
|
||||
|
||||
void BootFramebufferConsole::hide_cursor()
|
||||
{
|
||||
VERIFY(m_lock.is_locked());
|
||||
GenericFramebufferConsoleImpl::hide_cursor();
|
||||
}
|
||||
|
||||
void BootFramebufferConsole::show_cursor()
|
||||
{
|
||||
VERIFY(m_lock.is_locked());
|
||||
GenericFramebufferConsoleImpl::show_cursor();
|
||||
}
|
||||
|
||||
u8* BootFramebufferConsole::framebuffer_data()
|
||||
{
|
||||
VERIFY(m_lock.is_locked());
|
||||
VERIFY(m_framebuffer_data);
|
||||
return m_framebuffer_data;
|
||||
}
|
||||
|
||||
}
|
45
Kernel/Devices/GPU/Console/BootFramebufferConsole.h
Normal file
45
Kernel/Devices/GPU/Console/BootFramebufferConsole.h
Normal file
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* Copyright (c) 2022, the SerenityOS developers.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Kernel/Devices/GPU/Console/GenericFramebufferConsole.h>
|
||||
#include <Kernel/Forward.h>
|
||||
|
||||
namespace Kernel::Graphics {
|
||||
|
||||
class BootFramebufferConsole : public GenericFramebufferConsoleImpl {
|
||||
public:
|
||||
virtual void clear(size_t x, size_t y, size_t length) override;
|
||||
virtual void write(size_t x, size_t y, char ch, Color background, Color foreground, bool critical = false) override;
|
||||
using GenericFramebufferConsoleImpl::write;
|
||||
|
||||
virtual void enable() override;
|
||||
virtual void disable() override;
|
||||
|
||||
virtual void flush(size_t, size_t, size_t, size_t) override { }
|
||||
virtual void set_resolution(size_t, size_t, size_t) override { }
|
||||
|
||||
u8* unsafe_framebuffer_data() { return m_framebuffer_data; }
|
||||
|
||||
BootFramebufferConsole(PhysicalAddress framebuffer_addr, size_t width, size_t height, size_t pitch);
|
||||
|
||||
private:
|
||||
virtual void set_cursor(size_t x, size_t y) override;
|
||||
virtual void hide_cursor() override;
|
||||
virtual void show_cursor() override;
|
||||
|
||||
protected:
|
||||
virtual void clear_glyph(size_t x, size_t y) override;
|
||||
|
||||
virtual u8* framebuffer_data() override;
|
||||
|
||||
OwnPtr<Memory::Region> m_framebuffer;
|
||||
u8* m_framebuffer_data {};
|
||||
mutable Spinlock<LockRank::None> m_lock {};
|
||||
};
|
||||
|
||||
}
|
81
Kernel/Devices/GPU/Console/Console.h
Normal file
81
Kernel/Devices/GPU/Console/Console.h
Normal file
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
* Copyright (c) 2021, Liav A. <liavalb@hotmail.co.il>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AK/AtomicRefCounted.h>
|
||||
#include <AK/Types.h>
|
||||
#include <Kernel/Devices/GPU/GenericGraphicsAdapter.h>
|
||||
|
||||
namespace Kernel::Graphics {
|
||||
|
||||
class Console : public AtomicRefCounted<Console> {
|
||||
public:
|
||||
// Stanadard VGA text mode colors
|
||||
enum Color : u8 {
|
||||
Black = 0,
|
||||
Blue,
|
||||
Green,
|
||||
Cyan,
|
||||
Red,
|
||||
Magenta,
|
||||
Brown,
|
||||
LightGray,
|
||||
DarkGray,
|
||||
BrightBlue,
|
||||
BrightGreen,
|
||||
BrightCyan,
|
||||
BrightRed,
|
||||
BrightMagenta,
|
||||
Yellow,
|
||||
White,
|
||||
};
|
||||
|
||||
public:
|
||||
size_t width() const { return m_width; }
|
||||
size_t height() const { return m_height; }
|
||||
size_t pitch() const { return bytes_per_base_glyph() * width(); }
|
||||
virtual size_t max_column() const { return m_width; }
|
||||
virtual size_t max_row() const { return m_height; }
|
||||
virtual size_t bytes_per_base_glyph() const = 0;
|
||||
virtual size_t chars_per_line() const = 0;
|
||||
|
||||
virtual void enable() = 0;
|
||||
virtual void disable() = 0;
|
||||
|
||||
virtual bool is_hardware_paged_capable() const = 0;
|
||||
virtual bool has_hardware_cursor() const = 0;
|
||||
|
||||
virtual void set_cursor(size_t x, size_t y) = 0;
|
||||
|
||||
virtual void clear(size_t x, size_t y, size_t length) = 0;
|
||||
virtual void write(size_t x, size_t y, char ch, Color background, Color foreground, bool critical = false) = 0;
|
||||
virtual void write(size_t x, size_t y, char ch, bool critical = false) = 0;
|
||||
virtual void write(char ch, bool critical = false) = 0;
|
||||
virtual void flush(size_t x, size_t y, size_t width, size_t height) = 0;
|
||||
|
||||
virtual ~Console() = default;
|
||||
|
||||
protected:
|
||||
virtual void hide_cursor() = 0;
|
||||
virtual void show_cursor() = 0;
|
||||
|
||||
Console(size_t width, size_t height)
|
||||
: m_width(width)
|
||||
, m_height(height)
|
||||
{
|
||||
m_enabled.store(true);
|
||||
}
|
||||
|
||||
Atomic<bool> m_enabled;
|
||||
Color m_default_foreground_color { Color::White };
|
||||
Color m_default_background_color { Color::Black };
|
||||
size_t m_width;
|
||||
size_t m_height;
|
||||
mutable size_t m_x { 0 };
|
||||
mutable size_t m_y { 0 };
|
||||
};
|
||||
}
|
42
Kernel/Devices/GPU/Console/ContiguousFramebufferConsole.cpp
Normal file
42
Kernel/Devices/GPU/Console/ContiguousFramebufferConsole.cpp
Normal file
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* Copyright (c) 2021, Sahan Fernando <sahan.h.fernando@gmail.com>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <Kernel/Devices/GPU/Console/ContiguousFramebufferConsole.h>
|
||||
#include <Kernel/TTY/ConsoleManagement.h>
|
||||
|
||||
namespace Kernel::Graphics {
|
||||
|
||||
NonnullLockRefPtr<ContiguousFramebufferConsole> ContiguousFramebufferConsole::initialize(PhysicalAddress framebuffer_address, size_t width, size_t height, size_t pitch)
|
||||
{
|
||||
return adopt_lock_ref(*new ContiguousFramebufferConsole(framebuffer_address, width, height, pitch));
|
||||
}
|
||||
|
||||
ContiguousFramebufferConsole::ContiguousFramebufferConsole(PhysicalAddress framebuffer_address, size_t width, size_t height, size_t pitch)
|
||||
: GenericFramebufferConsole(width, height, pitch)
|
||||
, m_framebuffer_address(framebuffer_address)
|
||||
{
|
||||
set_resolution(width, height, pitch);
|
||||
}
|
||||
|
||||
void ContiguousFramebufferConsole::set_resolution(size_t width, size_t height, size_t pitch)
|
||||
{
|
||||
m_width = width;
|
||||
m_height = height;
|
||||
m_pitch = pitch;
|
||||
|
||||
size_t size = Memory::page_round_up(pitch * height).release_value_but_fixme_should_propagate_errors();
|
||||
dbgln("Framebuffer Console: taking {} bytes", size);
|
||||
auto region_or_error = MM.allocate_kernel_region(m_framebuffer_address, size, "Framebuffer Console"sv, Memory::Region::Access::ReadWrite, Memory::Region::Cacheable::Yes);
|
||||
VERIFY(!region_or_error.is_error());
|
||||
m_framebuffer_region = region_or_error.release_value();
|
||||
|
||||
// Just to start cleanly, we clean the entire framebuffer
|
||||
memset(m_framebuffer_region->vaddr().as_ptr(), 0, pitch * height);
|
||||
|
||||
ConsoleManagement::the().resolution_was_changed();
|
||||
}
|
||||
|
||||
}
|
30
Kernel/Devices/GPU/Console/ContiguousFramebufferConsole.h
Normal file
30
Kernel/Devices/GPU/Console/ContiguousFramebufferConsole.h
Normal file
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* Copyright (c) 2021, Sahan Fernando <sahan.h.fernando@gmail.com>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Kernel/Devices/GPU/Console/GenericFramebufferConsole.h>
|
||||
|
||||
namespace Kernel::Graphics {
|
||||
|
||||
class ContiguousFramebufferConsole final : public GenericFramebufferConsole {
|
||||
public:
|
||||
static NonnullLockRefPtr<ContiguousFramebufferConsole> initialize(PhysicalAddress, size_t width, size_t height, size_t pitch);
|
||||
|
||||
virtual void set_resolution(size_t width, size_t height, size_t pitch) override;
|
||||
virtual void flush(size_t, size_t, size_t, size_t) override { }
|
||||
|
||||
private:
|
||||
virtual u8* framebuffer_data() override
|
||||
{
|
||||
return m_framebuffer_region->vaddr().as_ptr();
|
||||
}
|
||||
OwnPtr<Memory::Region> m_framebuffer_region;
|
||||
ContiguousFramebufferConsole(PhysicalAddress, size_t width, size_t height, size_t pitch);
|
||||
PhysicalAddress m_framebuffer_address;
|
||||
};
|
||||
|
||||
}
|
379
Kernel/Devices/GPU/Console/GenericFramebufferConsole.cpp
Normal file
379
Kernel/Devices/GPU/Console/GenericFramebufferConsole.cpp
Normal file
|
@ -0,0 +1,379 @@
|
|||
/*
|
||||
* Copyright (c) 2021, Liav A. <liavalb@hotmail.co.il>
|
||||
* Copyright (c) 2022, MacDue <macdue@dueutil.tech>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <Kernel/Devices/GPU/Console/GenericFramebufferConsole.h>
|
||||
#include <Kernel/TTY/ConsoleManagement.h>
|
||||
|
||||
namespace Kernel::Graphics {
|
||||
|
||||
// Note: This bitmap was generated from CathodeRegular10.font
|
||||
constexpr unsigned char const font_cathode_8x16[128][16] = {
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+0000 (nul)
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+0001
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+0002
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+0003
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+0004
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+0005
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+0006
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+0007
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+0008
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+0009
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+000A
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+000B
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+000C
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+000D
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+000E
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+000F
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+0010
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+0011
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+0012
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+0013
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+0014
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+0015
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+0016
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+0017
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+0018
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+0019
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+001A
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+001B
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+001C
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+001D
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+001E
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+001F
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+0020 ( )
|
||||
{ 0x00, 0x00, 0x30, 0x78, 0x78, 0x78, 0x78, 0x78, 0x30, 0x30, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00 }, // U+0021 (!)
|
||||
{ 0x00, 0x00, 0x6C, 0x6C, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+0022 (")
|
||||
{ 0x00, 0x00, 0x6C, 0x6C, 0x6C, 0xFE, 0x6C, 0x6C, 0x6C, 0xFE, 0x6C, 0x6C, 0x6C, 0x00, 0x00, 0x00 }, // U+0023 (#)
|
||||
{ 0x00, 0x00, 0x30, 0x30, 0x78, 0xCC, 0xCC, 0x60, 0x18, 0xCC, 0xCC, 0x78, 0x30, 0x30, 0x00, 0x00 }, // U+0024 ($)
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0xC2, 0xC4, 0x08, 0x10, 0x20, 0x46, 0x86, 0x00, 0x00, 0x00, 0x00 }, // U+0025 (%)
|
||||
{ 0x00, 0x00, 0x78, 0xCC, 0xCC, 0xCC, 0x78, 0x36, 0x5C, 0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00 }, // U+0026 (&)
|
||||
{ 0x00, 0x00, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+0027 (')
|
||||
{ 0x00, 0x00, 0x0C, 0x18, 0x30, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x30, 0x18, 0x0C, 0x00, 0x00 }, // U+0028 (()
|
||||
{ 0x00, 0x00, 0x60, 0x30, 0x18, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x18, 0x30, 0x60, 0x00, 0x00 }, // U+0029 ())
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0xCC, 0x30, 0xFC, 0x30, 0xCC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+002A (*)
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0xFC, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+002B (+)
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30, 0x00, 0x00 }, // U+002C (,)
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+002D (-)
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00 }, // U+002E (.)
|
||||
{ 0x00, 0x00, 0x02, 0x06, 0x04, 0x0C, 0x18, 0x10, 0x30, 0x60, 0x40, 0xC0, 0x80, 0x00, 0x00, 0x00 }, // U+002F (/)
|
||||
{ 0x00, 0x00, 0x7C, 0xC6, 0xCE, 0xCE, 0xDE, 0xD6, 0xF6, 0xE6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00 }, // U+0030 (0)
|
||||
{ 0x00, 0x00, 0x30, 0x70, 0xF0, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0xFC, 0x00, 0x00, 0x00 }, // U+0031 (1)
|
||||
{ 0x00, 0x00, 0x7C, 0xC6, 0x06, 0x06, 0x06, 0x0C, 0x18, 0x30, 0x60, 0xC6, 0xFE, 0x00, 0x00, 0x00 }, // U+0032 (2)
|
||||
{ 0x00, 0x00, 0x7C, 0xC6, 0x06, 0x06, 0x04, 0x38, 0x04, 0x06, 0x06, 0xC6, 0x7C, 0x00, 0x00, 0x00 }, // U+0033 (3)
|
||||
{ 0x00, 0x00, 0x0C, 0x1C, 0x3C, 0x6C, 0xCC, 0xFE, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x00, 0x00, 0x00 }, // U+0034 (4)
|
||||
{ 0x00, 0x00, 0xFE, 0xC0, 0xC0, 0xC0, 0xFC, 0x06, 0x06, 0x06, 0x06, 0xC6, 0x7C, 0x00, 0x00, 0x00 }, // U+0035 (5)
|
||||
{ 0x00, 0x00, 0x1C, 0x30, 0x60, 0xC0, 0xC0, 0xFC, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00 }, // U+0036 (6)
|
||||
{ 0x00, 0x00, 0xFE, 0xC6, 0x06, 0x0C, 0x18, 0x30, 0x60, 0x60, 0x60, 0x60, 0x60, 0x00, 0x00, 0x00 }, // U+0037 (7)
|
||||
{ 0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00 }, // U+0038 (8)
|
||||
{ 0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0xC6, 0x7E, 0x06, 0x06, 0x0C, 0x18, 0x70, 0x00, 0x00, 0x00 }, // U+0039 (9)
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00 }, // U+003A (:)
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x60, 0x00, 0x00 }, // U+003B (;)
|
||||
{ 0x00, 0x00, 0x06, 0x0C, 0x18, 0x30, 0x60, 0xE0, 0x60, 0x30, 0x18, 0x0C, 0x06, 0x00, 0x00, 0x00 }, // U+003C (<)
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+003D (=)
|
||||
{ 0x00, 0x00, 0xC0, 0x60, 0x30, 0x18, 0x0C, 0x0E, 0x0C, 0x18, 0x30, 0x60, 0xC0, 0x00, 0x00, 0x00 }, // U+003E (>)
|
||||
{ 0x00, 0x00, 0x7C, 0xC6, 0xC6, 0x06, 0x0C, 0x18, 0x30, 0x30, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00 }, // U+003F (?)
|
||||
{ 0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xDE, 0xDE, 0xDE, 0xDE, 0xDE, 0xDC, 0xC0, 0x7C, 0x00, 0x00, 0x00 }, // U+0040 (@)
|
||||
{ 0x00, 0x00, 0x10, 0x38, 0x6C, 0xC6, 0xC6, 0xFE, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00 }, // U+0041 (A)
|
||||
{ 0x00, 0x00, 0xFC, 0x66, 0x66, 0x66, 0x66, 0x7C, 0x66, 0x66, 0x66, 0x66, 0xFC, 0x00, 0x00, 0x00 }, // U+0042 (B)
|
||||
{ 0x00, 0x00, 0x3C, 0x66, 0xC2, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC2, 0x66, 0x3C, 0x00, 0x00, 0x00 }, // U+0043 (C)
|
||||
{ 0x00, 0x00, 0xF8, 0x6C, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x6C, 0xF8, 0x00, 0x00, 0x00 }, // U+0044 (D)
|
||||
{ 0x00, 0x00, 0xFE, 0x66, 0x62, 0x60, 0x68, 0x78, 0x68, 0x60, 0x62, 0x66, 0xFE, 0x00, 0x00, 0x00 }, // U+0045 (E)
|
||||
{ 0x00, 0x00, 0xFE, 0x66, 0x62, 0x60, 0x64, 0x7C, 0x64, 0x60, 0x60, 0x60, 0xF0, 0x00, 0x00, 0x00 }, // U+0046 (F)
|
||||
{ 0x00, 0x00, 0x3C, 0x66, 0xC2, 0xC0, 0xC0, 0xDE, 0xC6, 0xC6, 0xC6, 0x66, 0x3A, 0x00, 0x00, 0x00 }, // U+0047 (G)
|
||||
{ 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xFE, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00 }, // U+0048 (H)
|
||||
{ 0x00, 0x00, 0x78, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00, 0x00, 0x00 }, // U+0049 (I)
|
||||
{ 0x00, 0x00, 0x1E, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0xCC, 0xCC, 0x78, 0x00, 0x00, 0x00 }, // U+004A (J)
|
||||
{ 0x00, 0x00, 0xE6, 0x66, 0x6C, 0x6C, 0x68, 0x78, 0x68, 0x6C, 0x6C, 0x66, 0xE6, 0x00, 0x00, 0x00 }, // U+004B (K)
|
||||
{ 0x00, 0x00, 0xF0, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x62, 0x66, 0xFE, 0x00, 0x00, 0x00 }, // U+004C (L)
|
||||
{ 0x00, 0x00, 0xC6, 0xEE, 0xFE, 0xFE, 0xD6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00 }, // U+004D (M)
|
||||
{ 0x00, 0x00, 0xC6, 0xE6, 0xF6, 0xFE, 0xFE, 0xDE, 0xCE, 0xC6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00 }, // U+004E (N)
|
||||
{ 0x00, 0x00, 0x38, 0x6C, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x6C, 0x38, 0x00, 0x00, 0x00 }, // U+004F (O)
|
||||
{ 0x00, 0x00, 0xFC, 0x66, 0x66, 0x66, 0x66, 0x7C, 0x60, 0x60, 0x60, 0x60, 0xF0, 0x00, 0x00, 0x00 }, // U+0050 (P)
|
||||
{ 0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xD6, 0xDE, 0x7C, 0x0E, 0x00, 0x00 }, // U+0051 (Q)
|
||||
{ 0x00, 0x00, 0xFC, 0x66, 0x66, 0x66, 0x66, 0x7C, 0x6C, 0x66, 0x66, 0x66, 0xF6, 0x00, 0x00, 0x00 }, // U+0052 (R)
|
||||
{ 0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xC0, 0x60, 0x30, 0x18, 0x0C, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00 }, // U+0053 (S)
|
||||
{ 0x00, 0x00, 0xFC, 0xFC, 0xB4, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00, 0x00, 0x00 }, // U+0054 (T)
|
||||
{ 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00 }, // U+0055 (U)
|
||||
{ 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x6C, 0x38, 0x10, 0x00, 0x00, 0x00 }, // U+0056 (V)
|
||||
{ 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xD6, 0xD6, 0xD6, 0xFE, 0x7C, 0x6C, 0x00, 0x00, 0x00 }, // U+0057 (W)
|
||||
{ 0x00, 0x00, 0xC6, 0xC6, 0x6C, 0x38, 0x38, 0x38, 0x38, 0x38, 0x6C, 0xC6, 0xC6, 0x00, 0x00, 0x00 }, // U+0058 (X)
|
||||
{ 0x00, 0x00, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0x78, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00, 0x00, 0x00 }, // U+0059 (Y)
|
||||
{ 0x00, 0x00, 0xFE, 0xC6, 0x86, 0x0C, 0x18, 0x30, 0x60, 0x40, 0xC2, 0xC6, 0xFE, 0x00, 0x00, 0x00 }, // U+005A (Z)
|
||||
{ 0x00, 0x00, 0xFC, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xFC, 0x00, 0x00, 0x00 }, // U+005B ([)
|
||||
{ 0x00, 0x00, 0x80, 0xC0, 0x40, 0x60, 0x30, 0x10, 0x18, 0x0C, 0x04, 0x06, 0x02, 0x00, 0x00, 0x00 }, // U+005C (\)
|
||||
{ 0x00, 0x00, 0xFC, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0xFC, 0x00, 0x00, 0x00 }, // U+005D (])
|
||||
{ 0x00, 0x00, 0x20, 0x70, 0xD8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+005E (^)
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, 0x00 }, // U+005F (_)
|
||||
{ 0x00, 0x00, 0x60, 0x70, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+0060 (`)
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0C, 0x0C, 0x7C, 0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00 }, // U+0061 (a)
|
||||
{ 0x00, 0x00, 0xE0, 0x60, 0x60, 0x78, 0x6C, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7C, 0x00, 0x00, 0x00 }, // U+0062 (b)
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC0, 0xC0, 0xC0, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00 }, // U+0063 (c)
|
||||
{ 0x00, 0x00, 0x1C, 0x0C, 0x0C, 0x3C, 0x6C, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00 }, // U+0064 (d)
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0xFE, 0xC0, 0xC0, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00 }, // U+0065 (e)
|
||||
{ 0x00, 0x00, 0x38, 0x6C, 0x64, 0x60, 0xF0, 0x60, 0x60, 0x60, 0x60, 0x60, 0xF0, 0x00, 0x00, 0x00 }, // U+0066 (f)
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xCC, 0xCC, 0xCC, 0xCC, 0x7C, 0x0C, 0xCC, 0x78, 0x00, 0x00 }, // U+0067 (g)
|
||||
{ 0x00, 0x00, 0xE0, 0x60, 0x60, 0x6C, 0x76, 0x66, 0x66, 0x66, 0x66, 0x66, 0xE6, 0x00, 0x00, 0x00 }, // U+0068 (h)
|
||||
{ 0x00, 0x00, 0x30, 0x30, 0x00, 0x70, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00, 0x00, 0x00 }, // U+0069 (i)
|
||||
{ 0x00, 0x00, 0x06, 0x06, 0x00, 0x0E, 0x06, 0x06, 0x06, 0x06, 0x06, 0xC6, 0xC6, 0x7C, 0x00, 0x00 }, // U+006A (j)
|
||||
{ 0x00, 0x00, 0xE0, 0x60, 0x60, 0x66, 0x6C, 0x68, 0x70, 0x68, 0x6C, 0x66, 0xE6, 0x00, 0x00, 0x00 }, // U+006B (k)
|
||||
{ 0x00, 0x00, 0x70, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00, 0x00, 0x00 }, // U+006C (l)
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0xEC, 0xFE, 0xD6, 0xD6, 0xD6, 0xD6, 0xC6, 0xC6, 0x00, 0x00, 0x00 }, // U+006D (m)
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0xDC, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00 }, // U+006E (n)
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00 }, // U+006F (o)
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0xDC, 0x66, 0x66, 0x66, 0x66, 0x7C, 0x60, 0x60, 0xF0, 0x00, 0x00 }, // U+0070 (p)
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xCC, 0xCC, 0xCC, 0xCC, 0x7C, 0x0C, 0x0C, 0x1E, 0x00, 0x00 }, // U+0071 (q)
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0xD8, 0x76, 0x66, 0x60, 0x60, 0x60, 0x60, 0xF0, 0x00, 0x00, 0x00 }, // U+0072 (r)
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0x40, 0x70, 0x1C, 0x04, 0xC6, 0x7C, 0x00, 0x00, 0x00 }, // U+0073 (s)
|
||||
{ 0x00, 0x00, 0x10, 0x30, 0x30, 0xFC, 0x30, 0x30, 0x30, 0x30, 0x30, 0x36, 0x1C, 0x00, 0x00, 0x00 }, // U+0074 (t)
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00 }, // U+0075 (u)
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0x78, 0x30, 0x00, 0x00, 0x00 }, // U+0076 (v)
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xD6, 0xD6, 0xD6, 0xFE, 0x6C, 0x00, 0x00, 0x00 }, // U+0077 (w)
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0x6C, 0x38, 0x38, 0x38, 0x38, 0x6C, 0xC6, 0x00, 0x00, 0x00 }, // U+0078 (x)
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0x7E, 0x06, 0x06, 0x0C, 0xF8, 0x00, 0x00 }, // U+0079 (y)
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xCC, 0x0C, 0x18, 0x30, 0x60, 0x66, 0xFE, 0x00, 0x00, 0x00 }, // U+007A (z)
|
||||
{ 0x00, 0x00, 0x1E, 0x30, 0x30, 0x30, 0x30, 0xE0, 0x30, 0x30, 0x30, 0x30, 0x1E, 0x00, 0x00, 0x00 }, // U+007B ({)
|
||||
{ 0x00, 0x00, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00 }, // U+007C (|)
|
||||
{ 0x00, 0x00, 0xF0, 0x18, 0x18, 0x18, 0x18, 0x0E, 0x18, 0x18, 0x18, 0x18, 0xF0, 0x00, 0x00, 0x00 }, // U+007D (})
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xDC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+007E (~)
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } // U+007F
|
||||
};
|
||||
|
||||
// FIXME: This assumes 32 bit BGR (Blue-Green-Red) palette
|
||||
enum BGRColor : u32 {
|
||||
Black = 0,
|
||||
Blue = 0x0000FF,
|
||||
Green = 0x00FF00,
|
||||
Cyan = 0x0000FFFF,
|
||||
Red = 0xFF0000,
|
||||
Magenta = 0x00FF00FF,
|
||||
Brown = 0x00964B00,
|
||||
LightGray = 0x00D3D3D3,
|
||||
DarkGray = 0x00A9A9A9,
|
||||
BrightBlue = 0x0ADD8E6,
|
||||
BrightGreen = 0x0090EE90,
|
||||
BrightCyan = 0x00E0FFFF,
|
||||
BrightRed = 0x00D70A53,
|
||||
BrightMagenta = 0x00F984E5,
|
||||
Yellow = 0x00FFE135,
|
||||
White = 0x00FFFFFF,
|
||||
};
|
||||
|
||||
static inline BGRColor convert_standard_color_to_bgr_color(Console::Color color)
|
||||
{
|
||||
switch (color) {
|
||||
case Console::Color::Black:
|
||||
return BGRColor::Black;
|
||||
case Console::Color::Red:
|
||||
return BGRColor::Red;
|
||||
case Console::Color::Brown:
|
||||
return BGRColor::Brown;
|
||||
case Console::Color::Blue:
|
||||
return BGRColor::Blue;
|
||||
case Console::Color::Magenta:
|
||||
return BGRColor::Magenta;
|
||||
case Console::Color::Green:
|
||||
return BGRColor::Green;
|
||||
case Console::Color::Cyan:
|
||||
return BGRColor::Cyan;
|
||||
case Console::Color::LightGray:
|
||||
return BGRColor::LightGray;
|
||||
case Console::Color::DarkGray:
|
||||
return BGRColor::DarkGray;
|
||||
case Console::Color::BrightRed:
|
||||
return BGRColor::BrightRed;
|
||||
case Console::Color::BrightGreen:
|
||||
return BGRColor::BrightGreen;
|
||||
case Console::Color::Yellow:
|
||||
return BGRColor::Yellow;
|
||||
case Console::Color::BrightBlue:
|
||||
return BGRColor::BrightBlue;
|
||||
case Console::Color::BrightMagenta:
|
||||
return BGRColor::BrightMagenta;
|
||||
case Console::Color::BrightCyan:
|
||||
return BGRColor::BrightCyan;
|
||||
case Console::Color::White:
|
||||
return BGRColor::White;
|
||||
default:
|
||||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
}
|
||||
|
||||
size_t GenericFramebufferConsoleImpl::bytes_per_base_glyph() const
|
||||
{
|
||||
// FIXME: We assume we have 32 bit bpp framebuffer.
|
||||
return 8 * 32;
|
||||
}
|
||||
|
||||
size_t GenericFramebufferConsoleImpl::chars_per_line() const
|
||||
{
|
||||
return max_column();
|
||||
}
|
||||
|
||||
void GenericFramebufferConsoleImpl::set_cursor(size_t x, size_t y)
|
||||
{
|
||||
hide_cursor();
|
||||
m_x = x;
|
||||
m_y = y;
|
||||
show_cursor();
|
||||
}
|
||||
|
||||
GenericFramebufferConsoleImpl::FramebufferOffset GenericFramebufferConsoleImpl::framebuffer_offset(size_t x, size_t y)
|
||||
{
|
||||
return { (&framebuffer_data()[x * sizeof(u32) * (m_glyph_columns + m_glyph_spacing) + y * m_glyph_rows * framebuffer_pitch()]) };
|
||||
}
|
||||
|
||||
void GenericFramebufferConsoleImpl::hide_cursor()
|
||||
{
|
||||
auto offset_in_framebuffer = framebuffer_offset(m_x, m_y);
|
||||
offset_in_framebuffer.bytes += framebuffer_pitch() * (m_glyph_rows - 1);
|
||||
for (size_t glyph_column = 0; glyph_column < m_glyph_columns; glyph_column++)
|
||||
offset_in_framebuffer.pixels[glyph_column] = m_cursor_overriden_pixels[glyph_column];
|
||||
}
|
||||
|
||||
void GenericFramebufferConsoleImpl::show_cursor()
|
||||
{
|
||||
auto offset_in_framebuffer = framebuffer_offset(m_x, m_y);
|
||||
offset_in_framebuffer.bytes += framebuffer_pitch() * (m_glyph_rows - 1);
|
||||
for (size_t glyph_column = 0; glyph_column < m_glyph_columns; glyph_column++) {
|
||||
m_cursor_overriden_pixels[glyph_column] = offset_in_framebuffer.pixels[glyph_column];
|
||||
memset(offset_in_framebuffer.pixels + glyph_column, 0xff, sizeof(u32));
|
||||
}
|
||||
}
|
||||
|
||||
void GenericFramebufferConsoleImpl::clear(size_t x, size_t y, size_t length)
|
||||
{
|
||||
if (x == 0 && length == max_column()) {
|
||||
// If we need to clear the entire row, just clean it with quick memset :)
|
||||
auto offset_in_framebuffer = framebuffer_offset(x, y);
|
||||
for (size_t glyph_row = 0; glyph_row < m_glyph_rows; glyph_row++) {
|
||||
memset(offset_in_framebuffer.pixels, 0, framebuffer_pitch());
|
||||
offset_in_framebuffer.bytes += framebuffer_pitch();
|
||||
}
|
||||
flush(0, m_glyph_rows * y, (m_glyph_columns + m_glyph_spacing) * length, 1);
|
||||
return;
|
||||
}
|
||||
for (size_t index = 0; index < length; index++) {
|
||||
if (x >= max_column()) {
|
||||
x = 0;
|
||||
y++;
|
||||
if (y >= max_row())
|
||||
y = 0;
|
||||
}
|
||||
clear_glyph(x, y);
|
||||
}
|
||||
}
|
||||
|
||||
void GenericFramebufferConsoleImpl::clear_glyph(size_t x, size_t y)
|
||||
{
|
||||
auto offset_in_framebuffer = framebuffer_offset(x, y);
|
||||
for (size_t glyph_row = 0; glyph_row < m_glyph_rows; glyph_row++) {
|
||||
memset(offset_in_framebuffer.pixels, 0, (m_glyph_columns + m_glyph_spacing) * sizeof(u32));
|
||||
offset_in_framebuffer.bytes += framebuffer_pitch();
|
||||
}
|
||||
flush_glyph(x, y);
|
||||
}
|
||||
|
||||
void GenericFramebufferConsoleImpl::enable()
|
||||
{
|
||||
memset(framebuffer_data(), 0, height() * framebuffer_pitch());
|
||||
m_enabled.store(true);
|
||||
}
|
||||
|
||||
void GenericFramebufferConsoleImpl::disable()
|
||||
{
|
||||
m_enabled.store(false);
|
||||
}
|
||||
|
||||
void GenericFramebufferConsoleImpl::write(size_t x, size_t y, char ch, Color background, Color foreground, bool critical)
|
||||
{
|
||||
if (!m_enabled.load())
|
||||
return;
|
||||
|
||||
// If we are in critical printing mode, we need to handle new lines here
|
||||
// because there's no other responsible object to do that in the print call path
|
||||
if (critical && (ch == '\r' || ch == '\n')) {
|
||||
m_x = 0;
|
||||
m_y += 1;
|
||||
if (m_y >= max_row())
|
||||
m_y = 0;
|
||||
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);
|
||||
BGRColor foreground_color = convert_standard_color_to_bgr_color(foreground);
|
||||
BGRColor background_color = convert_standard_color_to_bgr_color(background);
|
||||
for (size_t glyph_row = 0; glyph_row < m_glyph_rows; glyph_row++) {
|
||||
for (size_t glyph_column = m_glyph_columns; glyph_column > 0; glyph_column--) {
|
||||
bool pixel_set = bitmap[glyph_row] & (1 << glyph_column);
|
||||
offset_in_framebuffer.pixels[m_glyph_columns - glyph_column] = pixel_set ? foreground_color : background_color;
|
||||
}
|
||||
for (size_t spacing_column = 0; spacing_column < m_glyph_spacing; spacing_column++)
|
||||
offset_in_framebuffer.pixels[m_glyph_columns + spacing_column] = background_color;
|
||||
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())
|
||||
m_y = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void GenericFramebufferConsoleImpl::flush_glyph(size_t x, size_t y)
|
||||
{
|
||||
flush((m_glyph_columns + m_glyph_spacing) * x, m_glyph_rows * y, m_glyph_columns + m_glyph_spacing, m_glyph_rows);
|
||||
}
|
||||
|
||||
void GenericFramebufferConsoleImpl::write(size_t x, size_t y, char ch, bool critical)
|
||||
{
|
||||
write(x, y, ch, m_default_background_color, m_default_foreground_color, critical);
|
||||
}
|
||||
|
||||
void GenericFramebufferConsoleImpl::write(char ch, bool critical)
|
||||
{
|
||||
write(m_x, m_y, ch, m_default_background_color, m_default_foreground_color, critical);
|
||||
}
|
||||
|
||||
void GenericFramebufferConsole::clear(size_t x, size_t y, size_t length)
|
||||
{
|
||||
SpinlockLocker lock(m_lock);
|
||||
GenericFramebufferConsoleImpl::clear(x, y, length);
|
||||
}
|
||||
|
||||
void GenericFramebufferConsole::clear_glyph(size_t x, size_t y)
|
||||
{
|
||||
VERIFY(m_lock.is_locked());
|
||||
GenericFramebufferConsoleImpl::clear_glyph(x, y);
|
||||
}
|
||||
|
||||
void GenericFramebufferConsole::enable()
|
||||
{
|
||||
SpinlockLocker lock(m_lock);
|
||||
GenericFramebufferConsoleImpl::enable();
|
||||
}
|
||||
|
||||
void GenericFramebufferConsole::disable()
|
||||
{
|
||||
SpinlockLocker lock(m_lock);
|
||||
GenericFramebufferConsoleImpl::disable();
|
||||
}
|
||||
|
||||
void GenericFramebufferConsole::write(size_t x, size_t y, char ch, Color background, Color foreground, bool critical)
|
||||
{
|
||||
SpinlockLocker lock(m_lock);
|
||||
GenericFramebufferConsoleImpl::write(x, y, ch, background, foreground, critical);
|
||||
}
|
||||
|
||||
}
|
87
Kernel/Devices/GPU/Console/GenericFramebufferConsole.h
Normal file
87
Kernel/Devices/GPU/Console/GenericFramebufferConsole.h
Normal file
|
@ -0,0 +1,87 @@
|
|||
/*
|
||||
* Copyright (c) 2021, Liav A. <liavalb@hotmail.co.il>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AK/Types.h>
|
||||
#include <Kernel/Devices/GPU/Console/Console.h>
|
||||
#include <Kernel/Memory/PhysicalAddress.h>
|
||||
|
||||
namespace Kernel::Graphics {
|
||||
|
||||
class GenericFramebufferConsoleImpl : public Console {
|
||||
public:
|
||||
virtual size_t bytes_per_base_glyph() const override;
|
||||
virtual size_t chars_per_line() const override;
|
||||
|
||||
virtual size_t max_column() const override { return m_width / (m_glyph_columns + m_glyph_spacing); }
|
||||
virtual size_t max_row() const override { return m_height / m_glyph_rows; }
|
||||
|
||||
virtual bool is_hardware_paged_capable() const override { return false; }
|
||||
virtual bool has_hardware_cursor() const override { return false; }
|
||||
|
||||
virtual void set_cursor(size_t x, size_t y) override;
|
||||
|
||||
virtual void clear(size_t x, size_t y, size_t length) override;
|
||||
virtual void write(size_t x, size_t y, char ch, Color background, Color foreground, bool critical = false) override;
|
||||
virtual void write(size_t x, size_t y, char ch, bool critical = false) override;
|
||||
virtual void write(char ch, bool critical = false) override;
|
||||
|
||||
virtual void enable() override;
|
||||
virtual void disable() override;
|
||||
|
||||
virtual void set_resolution(size_t width, size_t height, size_t pitch) = 0;
|
||||
|
||||
protected:
|
||||
virtual void hide_cursor() override;
|
||||
virtual void show_cursor() override;
|
||||
|
||||
GenericFramebufferConsoleImpl(size_t width, size_t height, size_t pitch)
|
||||
: Console(width, height)
|
||||
, m_pitch(pitch)
|
||||
{
|
||||
m_cursor_overriden_pixels.fill(0);
|
||||
}
|
||||
virtual u8* framebuffer_data() = 0;
|
||||
size_t framebuffer_pitch() const { return m_pitch; }
|
||||
virtual void clear_glyph(size_t x, size_t y);
|
||||
|
||||
union FramebufferOffset {
|
||||
u8* bytes;
|
||||
u32* pixels;
|
||||
};
|
||||
FramebufferOffset framebuffer_offset(size_t x, size_t y);
|
||||
void flush_glyph(size_t x, size_t y);
|
||||
|
||||
size_t const m_glyph_spacing { 1 };
|
||||
size_t const m_glyph_columns { 8 };
|
||||
size_t const m_glyph_rows { 16 };
|
||||
|
||||
Array<u32, 8> m_cursor_overriden_pixels;
|
||||
|
||||
size_t m_pitch;
|
||||
};
|
||||
|
||||
class GenericFramebufferConsole : public GenericFramebufferConsoleImpl {
|
||||
public:
|
||||
virtual void clear(size_t x, size_t y, size_t length) override;
|
||||
virtual void write(size_t x, size_t y, char ch, Color background, Color foreground, bool critical = false) override;
|
||||
|
||||
virtual void enable() override;
|
||||
virtual void disable() override;
|
||||
|
||||
protected:
|
||||
GenericFramebufferConsole(size_t width, size_t height, size_t pitch)
|
||||
: GenericFramebufferConsoleImpl(width, height, pitch)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void clear_glyph(size_t x, size_t y) override;
|
||||
|
||||
mutable Spinlock<LockRank::None> m_lock {};
|
||||
};
|
||||
|
||||
}
|
158
Kernel/Devices/GPU/Console/VGATextModeConsole.cpp
Normal file
158
Kernel/Devices/GPU/Console/VGATextModeConsole.cpp
Normal file
|
@ -0,0 +1,158 @@
|
|||
/*
|
||||
* Copyright (c) 2021, Liav A. <liavalb@hotmail.co.il>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <Kernel/Devices/GPU/Console/VGATextModeConsole.h>
|
||||
#include <Kernel/Devices/GPU/Management.h>
|
||||
#include <Kernel/Sections.h>
|
||||
|
||||
namespace Kernel::Graphics {
|
||||
|
||||
UNMAP_AFTER_INIT NonnullLockRefPtr<VGATextModeConsole> VGATextModeConsole::initialize()
|
||||
{
|
||||
auto vga_window_size = MUST(Memory::page_round_up(0xc0000 - 0xa0000));
|
||||
auto vga_window_region = MUST(MM.allocate_kernel_region(PhysicalAddress(0xa0000), vga_window_size, "VGA Display"sv, Memory::Region::Access::ReadWrite));
|
||||
return adopt_lock_ref(*new (nothrow) VGATextModeConsole(move(vga_window_region)));
|
||||
}
|
||||
|
||||
UNMAP_AFTER_INIT VGATextModeConsole::VGATextModeConsole(NonnullOwnPtr<Memory::Region> vga_window_region)
|
||||
: Console(80, 25)
|
||||
, m_vga_window_region(move(vga_window_region))
|
||||
, m_current_vga_window(m_vga_window_region->vaddr().offset(0x18000).as_ptr())
|
||||
{
|
||||
for (size_t index = 0; index < height(); index++) {
|
||||
clear_vga_row(index);
|
||||
}
|
||||
dbgln("VGA Text mode console initialized!");
|
||||
}
|
||||
|
||||
enum VGAColor : u8 {
|
||||
Black = 0,
|
||||
Blue,
|
||||
Green,
|
||||
Cyan,
|
||||
Red,
|
||||
Magenta,
|
||||
Brown,
|
||||
LightGray,
|
||||
DarkGray,
|
||||
BrightBlue,
|
||||
BrightGreen,
|
||||
BrightCyan,
|
||||
BrightRed,
|
||||
BrightMagenta,
|
||||
Yellow,
|
||||
White,
|
||||
};
|
||||
|
||||
[[maybe_unused]] static inline VGAColor convert_standard_color_to_vga_color(Console::Color color)
|
||||
{
|
||||
switch (color) {
|
||||
case Console::Color::Black:
|
||||
return VGAColor::Black;
|
||||
case Console::Color::Red:
|
||||
return VGAColor::Red;
|
||||
case Console::Color::Brown:
|
||||
return VGAColor::Brown;
|
||||
case Console::Color::Blue:
|
||||
return VGAColor::Blue;
|
||||
case Console::Color::Magenta:
|
||||
return VGAColor::Magenta;
|
||||
case Console::Color::Green:
|
||||
return VGAColor::Green;
|
||||
case Console::Color::Cyan:
|
||||
return VGAColor::Cyan;
|
||||
case Console::Color::LightGray:
|
||||
return VGAColor::LightGray;
|
||||
case Console::Color::DarkGray:
|
||||
return VGAColor::DarkGray;
|
||||
case Console::Color::BrightRed:
|
||||
return VGAColor::BrightRed;
|
||||
case Console::Color::BrightGreen:
|
||||
return VGAColor::BrightGreen;
|
||||
case Console::Color::Yellow:
|
||||
return VGAColor::Yellow;
|
||||
case Console::Color::BrightBlue:
|
||||
return VGAColor::BrightBlue;
|
||||
case Console::Color::BrightMagenta:
|
||||
return VGAColor::BrightMagenta;
|
||||
case Console::Color::BrightCyan:
|
||||
return VGAColor::BrightCyan;
|
||||
case Console::Color::White:
|
||||
return VGAColor::White;
|
||||
default:
|
||||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
}
|
||||
|
||||
void VGATextModeConsole::set_cursor(size_t x, size_t y)
|
||||
{
|
||||
SpinlockLocker lock(m_vga_lock);
|
||||
GraphicsManagement::the().set_vga_text_mode_cursor(width(), x, y);
|
||||
m_x = x;
|
||||
m_y = y;
|
||||
}
|
||||
void VGATextModeConsole::hide_cursor()
|
||||
{
|
||||
SpinlockLocker lock(m_vga_lock);
|
||||
GraphicsManagement::the().disable_vga_text_mode_console_cursor();
|
||||
}
|
||||
void VGATextModeConsole::show_cursor()
|
||||
{
|
||||
set_cursor(m_x, m_y);
|
||||
}
|
||||
|
||||
void VGATextModeConsole::clear(size_t x, size_t y, size_t length)
|
||||
{
|
||||
SpinlockLocker lock(m_vga_lock);
|
||||
auto* buf = (u16*)m_current_vga_window.offset((x * 2) + (y * width() * 2)).as_ptr();
|
||||
for (size_t index = 0; index < length; index++) {
|
||||
buf[index] = 0x0720;
|
||||
}
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
void VGATextModeConsole::write(size_t x, size_t y, char ch, Color background, Color foreground, bool critical)
|
||||
{
|
||||
SpinlockLocker lock(m_vga_lock);
|
||||
// If we are in critical printing mode, we need to handle new lines here
|
||||
// because there's no other responsible object to do that in the print call path
|
||||
if (critical && (ch == '\r' || ch == '\n')) {
|
||||
// Disable hardware VGA cursor
|
||||
GraphicsManagement::the().disable_vga_text_mode_console_cursor();
|
||||
|
||||
m_x = 0;
|
||||
m_y += 1;
|
||||
if (m_y >= max_row())
|
||||
m_y = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
auto* buf = (u16*)m_current_vga_window.offset((x * 2) + (y * width() * 2)).as_ptr();
|
||||
*buf = foreground << 8 | background << 12 | ch;
|
||||
m_x = x + 1;
|
||||
|
||||
if (m_x >= max_column()) {
|
||||
m_x = 0;
|
||||
m_y = y + 1;
|
||||
if (m_y >= max_row())
|
||||
m_y = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void VGATextModeConsole::clear_vga_row(u16 row)
|
||||
{
|
||||
clear(0, row, width());
|
||||
}
|
||||
|
||||
void VGATextModeConsole::write(char ch, bool critical)
|
||||
{
|
||||
write(m_x, m_y, ch, critical);
|
||||
}
|
||||
|
||||
}
|
47
Kernel/Devices/GPU/Console/VGATextModeConsole.h
Normal file
47
Kernel/Devices/GPU/Console/VGATextModeConsole.h
Normal file
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* Copyright (c) 2021, Liav A. <liavalb@hotmail.co.il>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AK/Types.h>
|
||||
#include <Kernel/Devices/GPU/Console/Console.h>
|
||||
#include <Kernel/Locking/Spinlock.h>
|
||||
|
||||
namespace Kernel::Graphics {
|
||||
class VGATextModeConsole final : public Console {
|
||||
public:
|
||||
static NonnullLockRefPtr<VGATextModeConsole> initialize();
|
||||
virtual size_t chars_per_line() const override { return width(); };
|
||||
|
||||
virtual bool has_hardware_cursor() const override { return true; }
|
||||
virtual bool is_hardware_paged_capable() const override { return true; }
|
||||
|
||||
virtual size_t bytes_per_base_glyph() const override { return 2; }
|
||||
virtual void set_cursor(size_t x, size_t y) override;
|
||||
virtual void clear(size_t x, size_t y, size_t length) override;
|
||||
virtual void write(size_t x, size_t y, char ch, bool critical = false) override;
|
||||
virtual void write(size_t x, size_t y, char ch, Color background, Color foreground, bool critical = false) override;
|
||||
virtual void write(char ch, bool critical = false) override;
|
||||
virtual void flush(size_t, size_t, size_t, size_t) override { }
|
||||
|
||||
virtual void enable() override { }
|
||||
virtual void disable() override { }
|
||||
|
||||
private:
|
||||
virtual void hide_cursor() override;
|
||||
virtual void show_cursor() override;
|
||||
|
||||
void clear_vga_row(u16 row);
|
||||
|
||||
explicit VGATextModeConsole(NonnullOwnPtr<Memory::Region>);
|
||||
|
||||
mutable Spinlock<LockRank::None> m_vga_lock {};
|
||||
|
||||
NonnullOwnPtr<Memory::Region> m_vga_window_region;
|
||||
VirtualAddress m_current_vga_window;
|
||||
};
|
||||
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue