Kernel: Don't wrap cursor immediatly at cols()
This prevents unwanted scrolling when writing to bottom right cell
This commit is contained in:
parent
cc7c1ad30d
commit
dabc3c6cc4
|
@ -38,6 +38,7 @@ namespace Kernel
|
|||
void putcodepoint(uint32_t codepoint);
|
||||
void putchar_at(uint32_t codepoint, uint32_t x, uint32_t y);
|
||||
void render_from_buffer(uint32_t x, uint32_t y);
|
||||
void scroll_if_needed();
|
||||
|
||||
private:
|
||||
enum class State
|
||||
|
|
|
@ -104,6 +104,11 @@ namespace Kernel
|
|||
|
||||
void FramebufferTerminalDriver::show_cursor(bool use_data)
|
||||
{
|
||||
// NOTE: cursor is allowed to be on width as scrolling only
|
||||
// happens after character gets printed to next line
|
||||
if (m_cursor_x == width())
|
||||
return;
|
||||
|
||||
if (!use_data)
|
||||
read_cursor();
|
||||
|
||||
|
|
|
@ -140,6 +140,10 @@ namespace Kernel
|
|||
|
||||
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);
|
||||
|
|
|
@ -385,6 +385,29 @@ namespace Kernel
|
|||
m_terminal_driver->putchar_at(codepoint, x, y, cell.foreground, cell.background);
|
||||
}
|
||||
|
||||
void VirtualTTY::scroll_if_needed()
|
||||
{
|
||||
while (m_row >= m_height)
|
||||
{
|
||||
memmove(m_buffer, m_buffer + m_width, m_width * (m_height - 1) * sizeof(Cell));
|
||||
|
||||
// Clear last line in buffer
|
||||
for (uint32_t x = 0; x < m_width; x++)
|
||||
m_buffer[(m_height - 1) * m_width + x] = { .foreground = m_foreground, .background = m_background, .codepoint = ' ' };
|
||||
|
||||
if (!m_terminal_driver->scroll(m_background))
|
||||
{
|
||||
// No fast scrolling, render the whole buffer to the screen
|
||||
for (uint32_t y = 0; y < m_height; y++)
|
||||
for (uint32_t x = 0; x < m_width; x++)
|
||||
render_from_buffer(x, y);
|
||||
}
|
||||
|
||||
m_column = 0;
|
||||
m_row--;
|
||||
}
|
||||
}
|
||||
|
||||
void VirtualTTY::putcodepoint(uint32_t codepoint)
|
||||
{
|
||||
ASSERT(m_write_lock.current_processor_has_lock());
|
||||
|
@ -416,37 +439,19 @@ namespace Kernel
|
|||
m_state = State::WaitingAnsiEscape;
|
||||
break;
|
||||
default:
|
||||
if (m_column >= m_width)
|
||||
{
|
||||
m_column = 0;
|
||||
m_row++;
|
||||
}
|
||||
scroll_if_needed();
|
||||
putchar_at(codepoint, m_column, m_row);
|
||||
m_last_graphic_char = codepoint;
|
||||
m_column++;
|
||||
break;
|
||||
}
|
||||
|
||||
if (m_column >= m_width)
|
||||
{
|
||||
m_column = 0;
|
||||
m_row++;
|
||||
}
|
||||
|
||||
while (m_row >= m_height)
|
||||
{
|
||||
memmove(m_buffer, m_buffer + m_width, m_width * (m_height - 1) * sizeof(Cell));
|
||||
|
||||
// Clear last line in buffer
|
||||
for (uint32_t x = 0; x < m_width; x++)
|
||||
m_buffer[(m_height - 1) * m_width + x] = { .foreground = m_foreground, .background = m_background, .codepoint = ' ' };
|
||||
|
||||
if (!m_terminal_driver->scroll(m_background))
|
||||
{
|
||||
// No fast scrolling, render the whole buffer to the screen
|
||||
for (uint32_t y = 0; y < m_height; y++)
|
||||
for (uint32_t x = 0; x < m_width; x++)
|
||||
render_from_buffer(x, y);
|
||||
}
|
||||
|
||||
m_column = 0;
|
||||
m_row--;
|
||||
}
|
||||
scroll_if_needed();
|
||||
}
|
||||
|
||||
void VirtualTTY::putchar_impl(uint8_t ch)
|
||||
|
|
Loading…
Reference in New Issue