summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Bertalan <dani@danielbertalan.dev>2021-06-05 15:11:45 +0200
committerAndreas Kling <kling@serenityos.org>2021-06-10 17:18:02 +0200
commit89843cd6928651171474b4ba486471f46a3bee1b (patch)
tree9f9296c029dad8c1a8b51d308f7bb2fadb1bbc7c
parent7419569a2ba6d5a285293ae59e98a1e38e3c62e3 (diff)
downloadserenity-89843cd6928651171474b4ba486471f46a3bee1b.zip
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.
-rw-r--r--Kernel/TTY/VirtualConsole.cpp30
-rw-r--r--Kernel/TTY/VirtualConsole.h7
-rw-r--r--Userland/Libraries/LibVT/Terminal.cpp62
-rw-r--r--Userland/Libraries/LibVT/Terminal.h12
4 files changed, 68 insertions, 43 deletions
diff --git a/Kernel/TTY/VirtualConsole.cpp b/Kernel/TTY/VirtualConsole.cpp
index 8acc248f9f..e4c50127cb 100644
--- a/Kernel/TTY/VirtualConsole.cpp
+++ b/Kernel/TTY/VirtualConsole.cpp
@@ -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);
}
-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)
@@ -425,6 +425,28 @@ void VirtualConsole::scroll_down(u16 region_top, u16 region_bottom, size_t count
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)
{
VERIFY(row < rows());
diff --git a/Kernel/TTY/VirtualConsole.h b/Kernel/TTY/VirtualConsole.h
index a25c5a3731..4acd096f05 100644
--- a/Kernel/TTY/VirtualConsole.h
+++ b/Kernel/TTY/VirtualConsole.h
@@ -39,11 +39,10 @@ private:
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_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 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
@@ -138,6 +137,8 @@ private:
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_left(u16 row, u16 column, size_t count);
+ void scroll_right(u16 row, u16 column, size_t count);
void clear_line(size_t index)
{
clear_in_line(index, 0, m_console_impl.columns() - 1);
diff --git a/Userland/Libraries/LibVT/Terminal.cpp b/Userland/Libraries/LibVT/Terminal.cpp
index 5641e44cfc..5e72d1dd8e 100644
--- a/Userland/Libraries/LibVT/Terminal.cpp
+++ b/Userland/Libraries/LibVT/Terminal.cpp
@@ -692,27 +692,15 @@ void Terminal::DL(Parameters params)
scroll_up(cursor_row(), m_scroll_region_bottom, count);
}
-#ifndef KERNEL
void Terminal::DCH(Parameters params)
{
int num = 1;
if (params.size() >= 1 && params[0] != 0)
num = params[0];
- auto& line = active_buffer()[cursor_row()];
- num = min(num, static_cast<int>(line.length()) - cursor_column());
-
- // 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);
+ num = min<int>(num, columns() - cursor_column());
+ scroll_left(cursor_row(), cursor_column(), num);
}
-#endif
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);
}
+// 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)
{
VERIFY(row < rows());
@@ -883,27 +901,15 @@ void Terminal::DSR(Parameters params)
}
}
-#ifndef KERNEL
void Terminal::ICH(Parameters params)
{
unsigned num = 1;
if (params.size() >= 1 && params[0] != 0)
num = params[0];
- auto& line = active_buffer()[cursor_row()];
-
- auto max_insert = static_cast<unsigned>(line.length()) - cursor_column();
- num = min(num, max_insert);
- // 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);
+ num = min<unsigned>(num, columns() - cursor_column());
+ scroll_right(cursor_row(), cursor_column(), num);
}
-#endif
void Terminal::on_input(u8 byte)
{
diff --git a/Userland/Libraries/LibVT/Terminal.h b/Userland/Libraries/LibVT/Terminal.h
index def255546e..ea719935ba 100644
--- a/Userland/Libraries/LibVT/Terminal.h
+++ b/Userland/Libraries/LibVT/Terminal.h
@@ -216,11 +216,15 @@ protected:
#ifndef KERNEL
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_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 clear_in_line(u16 row, u16 first_column, u16 last_column);
#else
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_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 clear_in_line(u16 row, u16 first_column, u16 last_column) = 0;
#endif
@@ -306,12 +310,8 @@ protected:
// DECSCUSR - Set Cursor Style
void DECSCUSR(Parameters);
-#ifndef KERNEL
// ICH - Insert Character
void ICH(Parameters);
-#else
- virtual void ICH(Parameters) = 0;
-#endif
// SU - Scroll Up (called "Pan Down" in VT510)
void SU(Parameters);
@@ -322,12 +322,8 @@ protected:
// IL - Insert Line
void IL(Parameters);
-#ifndef KERNEL
// DCH - Delete Character
void DCH(Parameters);
-#else
- virtual void DCH(Parameters) = 0;
-#endif
// DL - Delete Line
void DL(Parameters);