From 9ff9d679e96598b42e9ccc63788245d73cefc6ea Mon Sep 17 00:00:00 2001 From: Bananymous Date: Fri, 25 Apr 2025 02:31:33 +0300 Subject: [PATCH] Kernel: Fix text mode cursor Apparently text mode renders cursor in the *foreground* color. My current clear function used the same color for foreground and background making the cursor effectively invisible. Also cursor hiding is now done by moving the cursor off bounds (0, height) some website I read said this to be valid even on VGA compatible cards without disable bit. http://www.osdever.net/FreeVGA/vga/textcur.htm --- .../kernel/Terminal/TextModeTerminal.h | 5 ++ kernel/kernel/Terminal/TextModeTerminal.cpp | 53 +++++++++++-------- 2 files changed, 35 insertions(+), 23 deletions(-) diff --git a/kernel/include/kernel/Terminal/TextModeTerminal.h b/kernel/include/kernel/Terminal/TextModeTerminal.h index e2971938..673256ce 100644 --- a/kernel/include/kernel/Terminal/TextModeTerminal.h +++ b/kernel/include/kernel/Terminal/TextModeTerminal.h @@ -30,6 +30,7 @@ namespace Kernel {} BAN::ErrorOr initialize(); + void move_cursor_impl(uint32_t x, uint32_t y); private: const paddr_t m_paddr; @@ -37,6 +38,10 @@ namespace Kernel const uint32_t m_height; const uint32_t m_pitch; vaddr_t m_vaddr { 0 }; + + uint32_t m_cursor_x { 0 }; + uint32_t m_cursor_y { 0 }; + bool m_cursor_shown { true }; static constexpr Color s_cursor_color = TerminalColor::WHITE; }; diff --git a/kernel/kernel/Terminal/TextModeTerminal.cpp b/kernel/kernel/Terminal/TextModeTerminal.cpp index f63ab085..8a2ef5b2 100644 --- a/kernel/kernel/Terminal/TextModeTerminal.cpp +++ b/kernel/kernel/Terminal/TextModeTerminal.cpp @@ -122,32 +122,11 @@ namespace Kernel { for (uint32_t y = 0; y < m_height; y++) for (uint32_t x = 0; x < m_width; x++) - putchar_at(' ', x, y, color, color); + putchar_at(' ', x, y, TerminalColor::WHITE, color); } - void TextModeTerminalDriver::set_cursor_shown(bool shown) + void TextModeTerminalDriver::move_cursor_impl(uint32_t x, uint32_t y) { - if (shown) - { - IO::outb(0x3D4, 0x0A); - IO::outb(0x3D5, (IO::inb(0x3D5) & 0xC0) | 14); - - IO::outb(0x3D4, 0x0B); - IO::outb(0x3D5, (IO::inb(0x3D5) & 0xE0) | 15); - } - else - { - IO::outb(0x3D4, 0x0A); - IO::outb(0x3D5, 0x20); - } - } - - void TextModeTerminalDriver::set_cursor_position(uint32_t x, uint32_t y) - { - // NOTE: cursor is allowed to be on width as scrolling only - // happens after character gets printed to next line - if (x == m_width) - return; const uint16_t pos = y * m_width + x; IO::outb(0x3D4, 0x0F); IO::outb(0x3D5, pos & 0xFF); @@ -155,4 +134,32 @@ namespace Kernel IO::outb(0x3D5, pos >> 8); } + void TextModeTerminalDriver::set_cursor_shown(bool shown) + { + if (m_cursor_shown == shown) + return; + m_cursor_shown = shown; + + if (shown) + move_cursor_impl(m_cursor_x, m_cursor_y); + else + move_cursor_impl(0, m_height); + } + + void TextModeTerminalDriver::set_cursor_position(uint32_t x, uint32_t y) + { + ASSERT(x <= m_width); + ASSERT(y < m_height); + m_cursor_x = x; + m_cursor_y = y; + + if (!m_cursor_shown) + return; + + if (x == m_width) + move_cursor_impl(0, m_height); + else + move_cursor_impl(x, y); + } + }