Kernel: TTY now supports clearing

This commit is contained in:
Bananymous 2023-04-05 02:04:18 +03:00
parent a423cd8bb3
commit d0b1457f30
2 changed files with 70 additions and 35 deletions

View File

@ -286,9 +286,7 @@ argument_done:
{ {
if (arguments.size() != 1) if (arguments.size() != 1)
return BAN::Error::from_c_string("'clear' does not support command line arguments"); return BAN::Error::from_c_string("'clear' does not support command line arguments");
//m_tty->clear(); TTY_PRINT("\e[2J\e[H");
//m_tty->set_cursor_position(0, 0);
TTY_PRINT("\e[2J\e[1;1H"); // clear and reset cursor
} }
else if (arguments.front() == "time") else if (arguments.front() == "time")
{ {

View File

@ -93,33 +93,7 @@ namespace Kernel
break; break;
case Input::Key::Backspace: case Input::Key::Backspace:
ansi = nullptr; ansi = nullptr;
if (m_output.bytes > 0)
{
// Multibyte UTF8
if ((m_output.buffer[m_output.bytes - 1] & 0xC0) == 0x80)
{
// NOTE: this should be valid UTF8 since keyboard input already 'validates' it
while ((m_output.buffer[m_output.bytes - 1] & 0xC0) == 0x80)
{
ASSERT(m_output.bytes > 0);
m_output.bytes--;
}
do_backspace(); do_backspace();
}
// Control sequence
else if (m_output.bytes >= 2 && m_output.buffer[m_output.bytes - 2] == '\e')
{
m_output.bytes -= 2;
do_backspace();
do_backspace();
}
// Ascii
else
{
m_output.bytes--;
do_backspace();
}
}
break; break;
default: default:
break; break;
@ -159,6 +133,9 @@ namespace Kernel
} }
void TTY::do_backspace() void TTY::do_backspace()
{
auto print_backspace =
[this]
{ {
if (m_column > 0) if (m_column > 0)
{ {
@ -166,6 +143,35 @@ namespace Kernel
putchar_at(' ', m_column, m_row); putchar_at(' ', m_column, m_row);
set_cursor_position(m_column, m_row); set_cursor_position(m_column, m_row);
} }
};
if (m_output.bytes > 0)
{
// Multibyte UTF8
if ((m_output.buffer[m_output.bytes - 1] & 0xC0) == 0x80)
{
// NOTE: this should be valid UTF8 since keyboard input already 'validates' it
while ((m_output.buffer[m_output.bytes - 1] & 0xC0) == 0x80)
{
ASSERT(m_output.bytes > 0);
m_output.bytes--;
}
print_backspace();
}
// Control sequence
else if (m_output.bytes >= 2 && m_output.buffer[m_output.bytes - 2] == '\e')
{
m_output.bytes -= 2;
print_backspace();
print_backspace();
}
// Ascii
else
{
m_output.bytes--;
print_backspace();
}
}
} }
void TTY::set_cursor_position(uint32_t x, uint32_t y) void TTY::set_cursor_position(uint32_t x, uint32_t y)
@ -310,7 +316,38 @@ namespace Kernel
m_column = BAN::Math::clamp<int32_t>(m_ansi_state.nums[1] - 1, 0, m_width - 1); m_column = BAN::Math::clamp<int32_t>(m_ansi_state.nums[1] - 1, 0, m_width - 1);
return reset_ansi(); return reset_ansi();
case 'J': // Erase in Display case 'J': // Erase in Display
if (m_ansi_state.nums[0] == -1 || m_ansi_state.nums[0] == 0)
{
// Clear from cursor to the end of screen
for (uint32_t i = m_column; i < m_width; i++)
putchar_at(' ', i, m_row);
for (uint32_t row = 0; row < m_height; row++)
for (uint32_t col = 0; col < m_width; col++)
putchar_at(' ', col, row);
}
else if (m_ansi_state.nums[0] == 1)
{
// Clear from cursor to the beginning of screen
for (uint32_t row = 0; row < m_row; row++)
for (uint32_t col = 0; col < m_width; col++)
putchar_at(' ', col, row);
for (uint32_t i = 0; i <= m_column; i++)
putchar_at(' ', i, m_row);
}
else if (m_ansi_state.nums[0] == 2 || m_ansi_state.nums[0] == 3)
{
// Clean entire screen
clear();
}
else
{
dprintln("Unsupported ANSI CSI character J"); dprintln("Unsupported ANSI CSI character J");
}
if (m_ansi_state.nums[0] == 3)
{
// FIXME: Clear scroll backbuffer if/when added
}
return reset_ansi(); return reset_ansi();
case 'K': // Erase in Line case 'K': // Erase in Line
if (m_ansi_state.nums[0] == -1 || m_ansi_state.nums[0] == 0) if (m_ansi_state.nums[0] == -1 || m_ansi_state.nums[0] == 0)