Kernel: Fix ANSI CSI @ and b for VirtualTTY
This commit is contained in:
parent
4409d0f03f
commit
439fb57d88
|
@ -31,6 +31,7 @@ namespace Kernel
|
||||||
void reset_ansi();
|
void reset_ansi();
|
||||||
void handle_ansi_csi(uint8_t ch);
|
void handle_ansi_csi(uint8_t ch);
|
||||||
void handle_ansi_csi_color(uint8_t ch);
|
void handle_ansi_csi_color(uint8_t ch);
|
||||||
|
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 set_cursor_position(uint32_t x, uint32_t y);
|
void set_cursor_position(uint32_t x, uint32_t y);
|
||||||
|
|
|
@ -329,23 +329,24 @@ namespace Kernel
|
||||||
case '@':
|
case '@':
|
||||||
if (m_ansi_state.nums[0] == -1)
|
if (m_ansi_state.nums[0] == -1)
|
||||||
m_ansi_state.nums[0] = 1;
|
m_ansi_state.nums[0] = 1;
|
||||||
reset_ansi();
|
m_ansi_state.nums[0] = BAN::Math::min<uint32_t>(m_ansi_state.nums[0], m_width - m_column);
|
||||||
|
memmove(
|
||||||
|
&m_buffer[m_row * m_width + m_column],
|
||||||
|
&m_buffer[m_row * m_width + m_column + m_ansi_state.nums[0]],
|
||||||
|
m_width - m_column - m_ansi_state.nums[0]
|
||||||
|
);
|
||||||
for (int i = 0; i < m_ansi_state.nums[0]; i++)
|
for (int i = 0; i < m_ansi_state.nums[0]; i++)
|
||||||
putchar_impl(' ');
|
putchar_at(' ', m_column + i, m_row);
|
||||||
return;
|
for (uint32_t x = m_column + m_ansi_state.nums[0]; x < m_width; x++)
|
||||||
|
render_from_buffer(x, m_row);
|
||||||
|
return reset_ansi();
|
||||||
case 'b':
|
case 'b':
|
||||||
if (m_ansi_state.nums[0] == -1)
|
if (m_ansi_state.nums[0] == -1)
|
||||||
m_ansi_state.nums[0] = 1;
|
m_ansi_state.nums[0] = 1;
|
||||||
reset_ansi();
|
|
||||||
if (m_last_graphic_char)
|
if (m_last_graphic_char)
|
||||||
{
|
|
||||||
char buffer[5] {};
|
|
||||||
BAN::UTF8::from_codepoints(&m_last_graphic_char, 1, buffer);
|
|
||||||
for (int i = 0; i < m_ansi_state.nums[0]; i++)
|
for (int i = 0; i < m_ansi_state.nums[0]; i++)
|
||||||
for (int j = 0; buffer[j]; j++)
|
putcodepoint(m_last_graphic_char);
|
||||||
putchar_impl(buffer[j]);
|
return reset_ansi();
|
||||||
}
|
|
||||||
return;
|
|
||||||
case 'd':
|
case 'd':
|
||||||
if (m_ansi_state.nums[0] == -1)
|
if (m_ansi_state.nums[0] == -1)
|
||||||
m_ansi_state.nums[0] = 1;
|
m_ansi_state.nums[0] = 1;
|
||||||
|
@ -396,6 +397,70 @@ namespace Kernel
|
||||||
m_terminal_driver->putchar_at(codepoint, x, y, m_foreground, m_background);
|
m_terminal_driver->putchar_at(codepoint, x, y, m_foreground, m_background);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VirtualTTY::putcodepoint(uint32_t codepoint)
|
||||||
|
{
|
||||||
|
ASSERT(m_write_lock.current_processor_has_lock());
|
||||||
|
|
||||||
|
switch (codepoint)
|
||||||
|
{
|
||||||
|
case BEL: // TODO
|
||||||
|
break;
|
||||||
|
case BS:
|
||||||
|
if (m_column > 0)
|
||||||
|
putchar_at(' ', --m_column, m_row);
|
||||||
|
break;
|
||||||
|
case HT:
|
||||||
|
m_column++;
|
||||||
|
while (m_column % 8)
|
||||||
|
m_column++;
|
||||||
|
break;
|
||||||
|
case LF:
|
||||||
|
m_column = 0;
|
||||||
|
m_row++;
|
||||||
|
break;
|
||||||
|
case FF:
|
||||||
|
m_row++;
|
||||||
|
break;
|
||||||
|
case CR:
|
||||||
|
m_column = 0;
|
||||||
|
break;
|
||||||
|
case ESC:
|
||||||
|
m_state = State::WaitingAnsiEscape;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
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--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void VirtualTTY::putchar_impl(uint8_t ch)
|
void VirtualTTY::putchar_impl(uint8_t ch)
|
||||||
{
|
{
|
||||||
ASSERT(m_write_lock.current_processor_has_lock());
|
ASSERT(m_write_lock.current_processor_has_lock());
|
||||||
|
@ -465,64 +530,7 @@ namespace Kernel
|
||||||
m_show_cursor = false;
|
m_show_cursor = false;
|
||||||
set_cursor_position(m_column, m_row);
|
set_cursor_position(m_column, m_row);
|
||||||
|
|
||||||
switch (codepoint)
|
putcodepoint(codepoint);
|
||||||
{
|
|
||||||
case BEL: // TODO
|
|
||||||
break;
|
|
||||||
case BS:
|
|
||||||
if (m_column > 0)
|
|
||||||
putchar_at(' ', --m_column, m_row);
|
|
||||||
break;
|
|
||||||
case HT:
|
|
||||||
m_column++;
|
|
||||||
while (m_column % 8)
|
|
||||||
m_column++;
|
|
||||||
break;
|
|
||||||
case LF:
|
|
||||||
m_column = 0;
|
|
||||||
m_row++;
|
|
||||||
break;
|
|
||||||
case FF:
|
|
||||||
m_row++;
|
|
||||||
break;
|
|
||||||
case CR:
|
|
||||||
m_column = 0;
|
|
||||||
break;
|
|
||||||
case ESC:
|
|
||||||
m_state = State::WaitingAnsiEscape;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
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--;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_show_cursor = old_show_cursor;
|
m_show_cursor = old_show_cursor;
|
||||||
set_cursor_position(m_column, m_row);
|
set_cursor_position(m_column, m_row);
|
||||||
|
|
Loading…
Reference in New Issue