diff --git a/Kernel/Graphics/VirtIOGPU/Console.cpp b/Kernel/Graphics/VirtIOGPU/Console.cpp index e2962fa858..5b2d5b8c9d 100644 --- a/Kernel/Graphics/VirtIOGPU/Console.cpp +++ b/Kernel/Graphics/VirtIOGPU/Console.cpp @@ -5,6 +5,7 @@ */ #include +#include #include namespace Kernel::Graphics::VirtIOGPU { @@ -21,12 +22,42 @@ Console::Console(VirtIODisplayConnector const& parent_display_connector, Display : GenericFramebufferConsole(current_resolution.horizontal_active, current_resolution.vertical_active, current_resolution.horizontal_stride) , m_parent_display_connector(parent_display_connector) { + // NOTE: Clear the framebuffer, in case it's left with some garbage. + memset(framebuffer_data(), 0, current_resolution.horizontal_stride * current_resolution.vertical_active); enqueue_refresh_timer(); } -void Console::set_resolution(size_t, size_t, size_t) +void Console::set_resolution(size_t width, size_t height, size_t pitch) { - // FIXME: Update some values here? + m_width = width; + m_height = height; + m_pitch = pitch; + + // Just to start cleanly, we clean the entire framebuffer + memset(framebuffer_data(), 0, pitch * height); + + ConsoleManagement::the().resolution_was_changed(); +} + +void Console::set_cursor(size_t x, size_t y) +{ + GenericFramebufferConsole::hide_cursor(); + m_x = x; + m_y = y; + GenericFramebufferConsole::show_cursor(); + m_dirty = true; +} + +void Console::hide_cursor() +{ + GenericFramebufferConsole::hide_cursor(); + m_dirty = true; +} + +void Console::show_cursor() +{ + GenericFramebufferConsole::show_cursor(); + m_dirty = true; } void Console::flush(size_t, size_t, size_t, size_t) @@ -54,11 +85,13 @@ void Console::enqueue_refresh_timer() void Console::enable() { + // FIXME: Do we need some locking here to ensure the resolution doesn't change + // while we enable the console? auto current_resolution = m_parent_display_connector->current_mode_setting(); - GenericFramebufferConsole::enable(); m_width = current_resolution.horizontal_active; m_height = current_resolution.vertical_active; m_pitch = current_resolution.horizontal_stride; + GenericFramebufferConsole::enable(); m_dirty = true; } diff --git a/Kernel/Graphics/VirtIOGPU/Console.h b/Kernel/Graphics/VirtIOGPU/Console.h index d798eff1a2..744a640d89 100644 --- a/Kernel/Graphics/VirtIOGPU/Console.h +++ b/Kernel/Graphics/VirtIOGPU/Console.h @@ -20,10 +20,15 @@ public: virtual void flush(size_t x, size_t y, size_t width, size_t height) override; virtual void enable() override; + virtual void set_cursor(size_t x, size_t y) override; + private: void enqueue_refresh_timer(); virtual u8* framebuffer_data() override; + virtual void hide_cursor() override; + virtual void show_cursor() override; + Console(VirtIODisplayConnector const& parent_display_connector, DisplayConnector::ModeSetting current_resolution); NonnullLockRefPtr m_parent_display_connector; bool m_dirty { false }; diff --git a/Kernel/Graphics/VirtIOGPU/DisplayConnector.cpp b/Kernel/Graphics/VirtIOGPU/DisplayConnector.cpp index bac91a30e3..d63d389678 100644 --- a/Kernel/Graphics/VirtIOGPU/DisplayConnector.cpp +++ b/Kernel/Graphics/VirtIOGPU/DisplayConnector.cpp @@ -20,7 +20,6 @@ NonnullLockRefPtr VirtIODisplayConnector::must_create(Vi auto device_or_error = DeviceManagement::try_create_device(graphics_adapter, scanout_id); VERIFY(!device_or_error.is_error()); auto connector = device_or_error.release_value(); - connector->initialize_console(); return connector; } @@ -33,9 +32,10 @@ VirtIODisplayConnector::VirtIODisplayConnector(VirtIOGraphicsAdapter& graphics_a { } -void VirtIODisplayConnector::initialize_console() +void VirtIODisplayConnector::initialize_console(Badge) { m_console = Kernel::Graphics::VirtIOGPU::Console::initialize(*this); + GraphicsManagement::the().set_console(*m_console); } void VirtIODisplayConnector::set_safe_mode_setting_after_initialization(Badge) @@ -58,6 +58,9 @@ ErrorOr VirtIODisplayConnector::set_mode_setting(ModeSetting const& mode_s }; TRY(m_graphics_adapter->mode_set_resolution({}, *this, mode_setting.horizontal_active, mode_setting.vertical_active)); + + if (m_console) + m_console->set_resolution(info.rect.width, info.rect.height, info.rect.width * sizeof(u32)); DisplayConnector::ModeSetting mode_set { .horizontal_stride = info.rect.width * sizeof(u32), .pixel_clock_in_khz = 0, // Note: There's no pixel clock in paravirtualized hardware diff --git a/Kernel/Graphics/VirtIOGPU/DisplayConnector.h b/Kernel/Graphics/VirtIOGPU/DisplayConnector.h index 804286ac01..f59629a2e8 100644 --- a/Kernel/Graphics/VirtIOGPU/DisplayConnector.h +++ b/Kernel/Graphics/VirtIOGPU/DisplayConnector.h @@ -39,8 +39,9 @@ public: void draw_ntsc_test_pattern(Badge); + void initialize_console(Badge); + private: - void initialize_console(); virtual bool mutable_mode_setting_capable() const override { return true; } virtual bool double_framebuffering_capable() const override { return false; } virtual bool partial_flush_support() const override { return true; } @@ -82,7 +83,7 @@ private: Graphics::VirtIOGPU::ContextID m_kernel_context_id; NonnullLockRefPtr m_graphics_adapter; - LockRefPtr m_console; + LockRefPtr m_console; Graphics::VirtIOGPU::Protocol::DisplayInfoResponse::Display m_display_info {}; Graphics::VirtIOGPU::ScanoutID m_scanout_id; diff --git a/Kernel/Graphics/VirtIOGPU/GraphicsAdapter.cpp b/Kernel/Graphics/VirtIOGPU/GraphicsAdapter.cpp index 8038258769..5e8872011f 100644 --- a/Kernel/Graphics/VirtIOGPU/GraphicsAdapter.cpp +++ b/Kernel/Graphics/VirtIOGPU/GraphicsAdapter.cpp @@ -47,6 +47,7 @@ ErrorOr VirtIOGraphicsAdapter::initialize_adapter() m_scanouts[index].display_connector = display_connector; MUST(query_and_set_edid(index, *display_connector)); display_connector->set_safe_mode_setting_after_initialization({}); + display_connector->initialize_console({}); } return {}; }