Kernel: Fix rendering bugs with framebuffer cursor

This commit is contained in:
Bananymous 2025-04-18 03:54:17 +03:00
parent 7c6966a9c4
commit 6858546ce9
1 changed files with 24 additions and 24 deletions

View File

@ -19,6 +19,8 @@ namespace Kernel
{ {
const uint8_t* glyph = m_font.has_glyph(ch) ? m_font.glyph(ch) : m_font.glyph('?'); const uint8_t* glyph = m_font.has_glyph(ch) ? m_font.glyph(ch) : m_font.glyph('?');
const bool update_cursor = m_cursor_shown && x == m_cursor_x && y == m_cursor_y;
x *= m_font.width(); x *= m_font.width();
y *= m_font.height(); y *= m_font.height();
@ -34,17 +36,18 @@ namespace Kernel
m_framebuffer_device->sync_pixels_rectangle(x, y, m_font.width(), m_font.height()); m_framebuffer_device->sync_pixels_rectangle(x, y, m_font.width(), m_font.height());
if (x == m_cursor_x && y == m_cursor_y) if (update_cursor)
{
read_cursor();
show_cursor(false); show_cursor(false);
} }
}
bool FramebufferTerminalDriver::scroll(Color color) bool FramebufferTerminalDriver::scroll(Color color)
{ {
if (m_cursor_shown)
show_cursor(true);
m_framebuffer_device->scroll(m_font.height(), color.rgb); m_framebuffer_device->scroll(m_font.height(), color.rgb);
m_framebuffer_device->sync_pixels_full(); m_framebuffer_device->sync_pixels_full();
if (m_cursor_shown)
show_cursor(false);
return true; return true;
} }
@ -62,25 +65,21 @@ namespace Kernel
void FramebufferTerminalDriver::read_cursor() void FramebufferTerminalDriver::read_cursor()
{ {
const uint32_t cursor_h = m_font.height() / 8; const uint32_t cursor_h = m_font.height() / 8;
const uint32_t cursor_w = m_font.width();
const uint32_t cursor_top = m_font.height() * 13 / 16; const uint32_t cursor_top = m_font.height() * 13 / 16;
const uint32_t x = m_cursor_x * m_font.width(); const uint32_t x = m_cursor_x * m_font.width();
const uint32_t y = m_cursor_y * m_font.height(); const uint32_t y = m_cursor_y * m_font.height();
for (uint32_t dy = 0; dy < cursor_h; dy++) for (uint32_t dy = 0; dy < cursor_h; dy++)
for (uint32_t dx = 0; dx < m_font.width(); dx++) for (uint32_t dx = 0; dx < cursor_w; dx++)
m_cursor_data[dy * m_font.width() + dx] = m_framebuffer_device->get_pixel(x + dx, y + cursor_top + dy); m_cursor_data[dy * cursor_w + dx] = m_framebuffer_device->get_pixel(x + dx, y + cursor_top + dy);
} }
void FramebufferTerminalDriver::show_cursor(bool use_data) void FramebufferTerminalDriver::show_cursor(bool use_data)
{
const auto get_color =
[this, use_data](uint32_t x, uint32_t y) -> uint32_t
{ {
if (!use_data) if (!use_data)
return m_cursor_color.rgb; read_cursor();
return m_cursor_data[y * m_font.width() + x];
};
const uint32_t cursor_h = m_font.height() / 8; const uint32_t cursor_h = m_font.height() / 8;
const uint32_t cursor_w = m_font.width(); const uint32_t cursor_w = m_font.width();
@ -89,6 +88,14 @@ namespace Kernel
const uint32_t x = m_cursor_x * m_font.width(); const uint32_t x = m_cursor_x * m_font.width();
const uint32_t y = m_cursor_y * m_font.height(); const uint32_t y = m_cursor_y * m_font.height();
const auto get_color =
[&](uint32_t x, uint32_t y) -> uint32_t
{
if (!use_data)
return m_cursor_color.rgb;
return m_cursor_data[y * cursor_w + x];
};
for (uint32_t dy = 0; dy < cursor_h; dy++) for (uint32_t dy = 0; dy < cursor_h; dy++)
for (uint32_t dx = 0; dx < cursor_w; dx++) for (uint32_t dx = 0; dx < cursor_w; dx++)
m_framebuffer_device->set_pixel(x + dx, y + cursor_top + dy, get_color(dx, dy)); m_framebuffer_device->set_pixel(x + dx, y + cursor_top + dy, get_color(dx, dy));
@ -100,20 +107,14 @@ namespace Kernel
if (m_cursor_shown == shown) if (m_cursor_shown == shown)
return; return;
m_cursor_shown = shown; m_cursor_shown = shown;
show_cursor(!m_cursor_shown);
if (m_cursor_shown)
{
read_cursor();
show_cursor(false);
}
else
{
show_cursor(true);
}
} }
void FramebufferTerminalDriver::set_cursor_position(uint32_t x, uint32_t y) void FramebufferTerminalDriver::set_cursor_position(uint32_t x, uint32_t y)
{ {
if (x == m_cursor_x && y == m_cursor_y)
return;
if (!m_cursor_shown) if (!m_cursor_shown)
{ {
m_cursor_x = x; m_cursor_x = x;
@ -124,7 +125,6 @@ namespace Kernel
show_cursor(true); show_cursor(true);
m_cursor_x = x; m_cursor_x = x;
m_cursor_y = y; m_cursor_y = y;
read_cursor();
show_cursor(false); show_cursor(false);
} }