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 putcodepoint(uint32_t codepoint);
|
||||||
void putchar_at(uint32_t codepoint, uint32_t x, uint32_t y);
|
void putchar_at(uint32_t codepoint, uint32_t x, uint32_t y);
|
||||||
void render_from_buffer(uint32_t x, uint32_t y);
|
void render_from_buffer(uint32_t x, uint32_t y);
|
||||||
|
void scroll_if_needed();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
enum class State
|
enum class State
|
||||||
|
|
|
@ -104,6 +104,11 @@ namespace Kernel
|
||||||
|
|
||||||
void FramebufferTerminalDriver::show_cursor(bool use_data)
|
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)
|
if (!use_data)
|
||||||
read_cursor();
|
read_cursor();
|
||||||
|
|
||||||
|
|
|
@ -140,6 +140,10 @@ namespace Kernel
|
||||||
|
|
||||||
void TextModeTerminalDriver::set_cursor_position(uint32_t x, uint32_t y)
|
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;
|
const uint16_t pos = y * m_width + x;
|
||||||
IO::outb(0x3D4, 0x0F);
|
IO::outb(0x3D4, 0x0F);
|
||||||
IO::outb(0x3D5, pos & 0xFF);
|
IO::outb(0x3D5, pos & 0xFF);
|
||||||
|
|
|
@ -385,6 +385,29 @@ namespace Kernel
|
||||||
m_terminal_driver->putchar_at(codepoint, x, y, cell.foreground, cell.background);
|
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)
|
void VirtualTTY::putcodepoint(uint32_t codepoint)
|
||||||
{
|
{
|
||||||
ASSERT(m_write_lock.current_processor_has_lock());
|
ASSERT(m_write_lock.current_processor_has_lock());
|
||||||
|
@ -416,37 +439,19 @@ namespace Kernel
|
||||||
m_state = State::WaitingAnsiEscape;
|
m_state = State::WaitingAnsiEscape;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
if (m_column >= m_width)
|
||||||
|
{
|
||||||
|
m_column = 0;
|
||||||
|
m_row++;
|
||||||
|
}
|
||||||
|
scroll_if_needed();
|
||||||
putchar_at(codepoint, m_column, m_row);
|
putchar_at(codepoint, m_column, m_row);
|
||||||
m_last_graphic_char = codepoint;
|
m_last_graphic_char = codepoint;
|
||||||
m_column++;
|
m_column++;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_column >= m_width)
|
scroll_if_needed();
|
||||||
{
|
|
||||||
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--;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void VirtualTTY::putchar_impl(uint8_t ch)
|
void VirtualTTY::putchar_impl(uint8_t ch)
|
||||||
|
|
Loading…
Reference in New Issue