mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 19:57:35 +00:00
Kernel+LibVT: Implement left-right scrolling
This commit implements the left/right scrolling used in the `ICH`/`DCH` escape sequences for `VirtualConsole`. This brings us one step closer to VT420/xterm compatibility. We can now finally remove the last escape sequence related `ifdef`s.
This commit is contained in:
parent
7419569a2b
commit
89843cd692
4 changed files with 68 additions and 43 deletions
|
@ -86,14 +86,14 @@ void ConsoleImpl::clear_in_line(u16 row, u16 first_column, u16 last_column)
|
||||||
m_client.clear_in_line(row, first_column, last_column);
|
m_client.clear_in_line(row, first_column, last_column);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConsoleImpl::ICH(Parameters)
|
void ConsoleImpl::scroll_left(u16 row, u16 column, size_t count)
|
||||||
{
|
{
|
||||||
// FIXME: Implement this
|
m_client.scroll_left(row, column, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConsoleImpl::DCH(Parameters)
|
void ConsoleImpl::scroll_right(u16 row, u16 column, size_t count)
|
||||||
{
|
{
|
||||||
// FIXME: Implement this
|
m_client.scroll_right(row, column, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VirtualConsole::set_graphical(bool graphical)
|
void VirtualConsole::set_graphical(bool graphical)
|
||||||
|
@ -425,6 +425,28 @@ void VirtualConsole::scroll_down(u16 region_top, u16 region_bottom, size_t count
|
||||||
m_lines[row].dirty = true;
|
m_lines[row].dirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VirtualConsole::scroll_left(u16 row, u16 column, size_t count)
|
||||||
|
{
|
||||||
|
VERIFY(row < rows());
|
||||||
|
VERIFY(column < columns());
|
||||||
|
count = min<size_t>(count, columns() - column);
|
||||||
|
memmove(&cell_at(column, row), &cell_at(column + count, row), sizeof(Cell) * (columns() - column - count));
|
||||||
|
for (size_t i = column + count; i < columns(); ++i)
|
||||||
|
cell_at(i, row).clear();
|
||||||
|
m_lines[row].dirty = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void VirtualConsole::scroll_right(u16 row, u16 column, size_t count)
|
||||||
|
{
|
||||||
|
VERIFY(row < rows());
|
||||||
|
VERIFY(column < columns());
|
||||||
|
count = min<size_t>(count, columns() - column);
|
||||||
|
memmove(&cell_at(column + count, row), &cell_at(column, row), sizeof(Cell) * (columns() - column - count));
|
||||||
|
for (size_t i = column; i < column + count; ++i)
|
||||||
|
cell_at(i, row).clear();
|
||||||
|
m_lines[row].dirty = true;
|
||||||
|
}
|
||||||
|
|
||||||
void VirtualConsole::clear_in_line(u16 row, u16 first_column, u16 last_column)
|
void VirtualConsole::clear_in_line(u16 row, u16 first_column, u16 last_column)
|
||||||
{
|
{
|
||||||
VERIFY(row < rows());
|
VERIFY(row < rows());
|
||||||
|
|
|
@ -39,11 +39,10 @@ private:
|
||||||
|
|
||||||
virtual void scroll_up(u16 region_top, u16 region_bottom, size_t count) override;
|
virtual void scroll_up(u16 region_top, u16 region_bottom, size_t count) override;
|
||||||
virtual void scroll_down(u16 region_top, u16 region_bottom, size_t count) override;
|
virtual void scroll_down(u16 region_top, u16 region_bottom, size_t count) override;
|
||||||
|
virtual void scroll_left(u16 row, u16 column, size_t count) override;
|
||||||
|
virtual void scroll_right(u16 row, u16 column, size_t count) override;
|
||||||
virtual void put_character_at(unsigned row, unsigned column, u32 ch) override;
|
virtual void put_character_at(unsigned row, unsigned column, u32 ch) override;
|
||||||
virtual void clear_in_line(u16 row, u16 first_column, u16 last_column) override;
|
virtual void clear_in_line(u16 row, u16 first_column, u16 last_column) override;
|
||||||
|
|
||||||
virtual void ICH(Parameters) override;
|
|
||||||
virtual void DCH(Parameters) override;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class VirtualConsole final : public TTY
|
class VirtualConsole final : public TTY
|
||||||
|
@ -138,6 +137,8 @@ private:
|
||||||
|
|
||||||
void scroll_down(u16 region_top, u16 region_bottom, size_t count);
|
void scroll_down(u16 region_top, u16 region_bottom, size_t count);
|
||||||
void scroll_up(u16 region_top, u16 region_bottom, size_t count);
|
void scroll_up(u16 region_top, u16 region_bottom, size_t count);
|
||||||
|
void scroll_left(u16 row, u16 column, size_t count);
|
||||||
|
void scroll_right(u16 row, u16 column, size_t count);
|
||||||
void clear_line(size_t index)
|
void clear_line(size_t index)
|
||||||
{
|
{
|
||||||
clear_in_line(index, 0, m_console_impl.columns() - 1);
|
clear_in_line(index, 0, m_console_impl.columns() - 1);
|
||||||
|
|
|
@ -692,27 +692,15 @@ void Terminal::DL(Parameters params)
|
||||||
scroll_up(cursor_row(), m_scroll_region_bottom, count);
|
scroll_up(cursor_row(), m_scroll_region_bottom, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef KERNEL
|
|
||||||
void Terminal::DCH(Parameters params)
|
void Terminal::DCH(Parameters params)
|
||||||
{
|
{
|
||||||
int num = 1;
|
int num = 1;
|
||||||
if (params.size() >= 1 && params[0] != 0)
|
if (params.size() >= 1 && params[0] != 0)
|
||||||
num = params[0];
|
num = params[0];
|
||||||
|
|
||||||
auto& line = active_buffer()[cursor_row()];
|
num = min<int>(num, columns() - cursor_column());
|
||||||
num = min(num, static_cast<int>(line.length()) - cursor_column());
|
scroll_left(cursor_row(), cursor_column(), num);
|
||||||
|
|
||||||
// Move n characters of line to the left
|
|
||||||
for (size_t i = cursor_column(); i < line.length() - num; i++)
|
|
||||||
line.cell_at(i) = line.cell_at(i + num);
|
|
||||||
|
|
||||||
// Fill remainder of line with blanks
|
|
||||||
for (size_t i = line.length() - num; i < line.length(); i++)
|
|
||||||
line.set_code_point(i, ' ');
|
|
||||||
|
|
||||||
line.set_dirty(true);
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
void Terminal::linefeed()
|
void Terminal::linefeed()
|
||||||
{
|
{
|
||||||
|
@ -807,6 +795,36 @@ void Terminal::scroll_down(u16 region_top, u16 region_bottom, size_t count)
|
||||||
active_buffer()[row].set_dirty(true);
|
active_buffer()[row].set_dirty(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Insert `count` blank cells at the end of the line. Text moves left.
|
||||||
|
void Terminal::scroll_left(u16 row, u16 column, size_t count)
|
||||||
|
{
|
||||||
|
VERIFY(row < rows());
|
||||||
|
VERIFY(column < columns());
|
||||||
|
count = min<size_t>(count, columns() - column);
|
||||||
|
dbgln_if(TERMINAL_DEBUG, "Scroll left {} columns from line {} column {}", count, row, column);
|
||||||
|
|
||||||
|
auto& line = active_buffer()[row];
|
||||||
|
for (size_t i = column; i < columns() - count; ++i)
|
||||||
|
swap(line.cell_at(i), line.cell_at(i + count));
|
||||||
|
clear_in_line(row, columns() - count, columns() - 1);
|
||||||
|
line.set_dirty(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Insert `count` blank cells after `row`. Text moves right.
|
||||||
|
void Terminal::scroll_right(u16 row, u16 column, size_t count)
|
||||||
|
{
|
||||||
|
VERIFY(row < rows());
|
||||||
|
VERIFY(column < columns());
|
||||||
|
count = min<size_t>(count, columns() - column);
|
||||||
|
dbgln_if(TERMINAL_DEBUG, "Scroll right {} columns from line {} column {}", count, row, column);
|
||||||
|
|
||||||
|
auto& line = active_buffer()[row];
|
||||||
|
for (int i = columns() - 1; i >= static_cast<int>(column + count); --i)
|
||||||
|
swap(line.cell_at(i), line.cell_at(i - count));
|
||||||
|
clear_in_line(row, column, column + count - 1);
|
||||||
|
line.set_dirty(true);
|
||||||
|
}
|
||||||
|
|
||||||
void Terminal::put_character_at(unsigned row, unsigned column, u32 code_point)
|
void Terminal::put_character_at(unsigned row, unsigned column, u32 code_point)
|
||||||
{
|
{
|
||||||
VERIFY(row < rows());
|
VERIFY(row < rows());
|
||||||
|
@ -883,27 +901,15 @@ void Terminal::DSR(Parameters params)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef KERNEL
|
|
||||||
void Terminal::ICH(Parameters params)
|
void Terminal::ICH(Parameters params)
|
||||||
{
|
{
|
||||||
unsigned num = 1;
|
unsigned num = 1;
|
||||||
if (params.size() >= 1 && params[0] != 0)
|
if (params.size() >= 1 && params[0] != 0)
|
||||||
num = params[0];
|
num = params[0];
|
||||||
auto& line = active_buffer()[cursor_row()];
|
|
||||||
|
|
||||||
auto max_insert = static_cast<unsigned>(line.length()) - cursor_column();
|
num = min<unsigned>(num, columns() - cursor_column());
|
||||||
num = min(num, max_insert);
|
scroll_right(cursor_row(), cursor_column(), num);
|
||||||
// Move characters after cursor to the right
|
|
||||||
for (int i = line.length() - num - 1; i >= cursor_column(); --i)
|
|
||||||
line.cell_at(i + num) = line.cell_at(i);
|
|
||||||
|
|
||||||
// Fill n characters after cursor with blanks
|
|
||||||
for (unsigned i = 0; i < num; ++i)
|
|
||||||
line.set_code_point(cursor_column() + i, ' ');
|
|
||||||
|
|
||||||
line.set_dirty(true);
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
void Terminal::on_input(u8 byte)
|
void Terminal::on_input(u8 byte)
|
||||||
{
|
{
|
||||||
|
|
|
@ -216,11 +216,15 @@ protected:
|
||||||
#ifndef KERNEL
|
#ifndef KERNEL
|
||||||
void scroll_up(u16 region_top, u16 region_bottom, size_t count);
|
void scroll_up(u16 region_top, u16 region_bottom, size_t count);
|
||||||
void scroll_down(u16 region_top, u16 region_bottom, size_t count);
|
void scroll_down(u16 region_top, u16 region_bottom, size_t count);
|
||||||
|
void scroll_left(u16 row, u16 column, size_t count);
|
||||||
|
void scroll_right(u16 row, u16 column, size_t count);
|
||||||
void put_character_at(unsigned row, unsigned column, u32 ch);
|
void put_character_at(unsigned row, unsigned column, u32 ch);
|
||||||
void clear_in_line(u16 row, u16 first_column, u16 last_column);
|
void clear_in_line(u16 row, u16 first_column, u16 last_column);
|
||||||
#else
|
#else
|
||||||
virtual void scroll_up(u16 region_top, u16 region_bottom, size_t count) = 0;
|
virtual void scroll_up(u16 region_top, u16 region_bottom, size_t count) = 0;
|
||||||
virtual void scroll_down(u16 region_top, u16 region_bottom, size_t count) = 0;
|
virtual void scroll_down(u16 region_top, u16 region_bottom, size_t count) = 0;
|
||||||
|
virtual void scroll_left(u16 row, u16 column, size_t count) = 0;
|
||||||
|
virtual void scroll_right(u16 row, u16 column, size_t count) = 0;
|
||||||
virtual void put_character_at(unsigned row, unsigned column, u32 ch) = 0;
|
virtual void put_character_at(unsigned row, unsigned column, u32 ch) = 0;
|
||||||
virtual void clear_in_line(u16 row, u16 first_column, u16 last_column) = 0;
|
virtual void clear_in_line(u16 row, u16 first_column, u16 last_column) = 0;
|
||||||
#endif
|
#endif
|
||||||
|
@ -306,12 +310,8 @@ protected:
|
||||||
// DECSCUSR - Set Cursor Style
|
// DECSCUSR - Set Cursor Style
|
||||||
void DECSCUSR(Parameters);
|
void DECSCUSR(Parameters);
|
||||||
|
|
||||||
#ifndef KERNEL
|
|
||||||
// ICH - Insert Character
|
// ICH - Insert Character
|
||||||
void ICH(Parameters);
|
void ICH(Parameters);
|
||||||
#else
|
|
||||||
virtual void ICH(Parameters) = 0;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// SU - Scroll Up (called "Pan Down" in VT510)
|
// SU - Scroll Up (called "Pan Down" in VT510)
|
||||||
void SU(Parameters);
|
void SU(Parameters);
|
||||||
|
@ -322,12 +322,8 @@ protected:
|
||||||
// IL - Insert Line
|
// IL - Insert Line
|
||||||
void IL(Parameters);
|
void IL(Parameters);
|
||||||
|
|
||||||
#ifndef KERNEL
|
|
||||||
// DCH - Delete Character
|
// DCH - Delete Character
|
||||||
void DCH(Parameters);
|
void DCH(Parameters);
|
||||||
#else
|
|
||||||
virtual void DCH(Parameters) = 0;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// DL - Delete Line
|
// DL - Delete Line
|
||||||
void DL(Parameters);
|
void DL(Parameters);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue