From 3944c00f23f023adabb71a53d1d25b8948b7482d Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Sun, 3 Feb 2019 14:00:48 +0100 Subject: [PATCH] Terminal: Add limited support for 'M' escape sequence (delete line.) --- Terminal/Terminal.cpp | 57 +++++++++++++++++++++++++++++++------------ Terminal/Terminal.h | 6 +++++ 2 files changed, 48 insertions(+), 15 deletions(-) diff --git a/Terminal/Terminal.cpp b/Terminal/Terminal.cpp index 3f6981f09f..bb016016c1 100644 --- a/Terminal/Terminal.cpp +++ b/Terminal/Terminal.cpp @@ -337,6 +337,25 @@ void Terminal::escape$J(const Vector& params) } } +void Terminal::escape$M(const Vector& params) +{ + int count = 1; + if (params.size() >= 1) + count = params[0]; + + if (count == 1 && m_cursor_row == 0) { + scroll_up(); + return; + } + + int max_count = m_rows - m_cursor_row; + count = min(count, max_count); + + dbgprintf("Delete %d line(s) starting from %d\n", count, m_cursor_row); + // FIXME: Implement. + ASSERT_NOT_REACHED(); +} + void Terminal::execute_xterm_command() { m_final = '@'; @@ -378,6 +397,7 @@ void Terminal::execute_escape_sequence(byte final) case 'H': escape$H(params); break; case 'J': escape$J(params); break; case 'K': escape$K(params); break; + case 'M': escape$M(params); break; case 'm': escape$m(params); break; case 's': escape$s(params); break; case 'u': escape$u(params); break; @@ -390,23 +410,28 @@ void Terminal::execute_escape_sequence(byte final) m_intermediates.clear(); } -void Terminal::scroll_up() +void Terminal::newline() { word new_row = m_cursor_row; if (m_cursor_row == (rows() - 1)) { - // NOTE: We have to invalidate the cursor first. - invalidate_cursor(); - delete m_lines[0]; - for (word row = 1; row < rows(); ++row) - m_lines[row - 1] = m_lines[row]; - m_lines[m_rows - 1] = new Line(m_columns); - ++m_rows_to_scroll_backing_store; + scroll_up(); } else { ++new_row; } set_cursor(new_row, 0); } +void Terminal::scroll_up() +{ + // NOTE: We have to invalidate the cursor first. + invalidate_cursor(); + delete m_lines[0]; + for (word row = 1; row < rows(); ++row) + m_lines[row - 1] = m_lines[row]; + m_lines[m_rows - 1] = new Line(m_columns); + ++m_rows_to_scroll_backing_store; +} + void Terminal::set_cursor(unsigned a_row, unsigned a_column) { unsigned row = min(a_row, m_rows - 1u); @@ -427,9 +452,12 @@ void Terminal::put_character_at(unsigned row, unsigned column, byte ch) { ASSERT(row < rows()); ASSERT(column < columns()); - line(row).characters[column] = ch; - line(row).attributes[column] = m_current_attribute; - line(row).dirty = true; + auto& line = this->line(row); + if ((line.characters[column] == ch) && (line.attributes[column] == m_current_attribute)) + return; + line.characters[column] = ch; + line.attributes[column] = m_current_attribute; + line.dirty = true; } void Terminal::on_char(byte ch) @@ -521,7 +549,7 @@ void Terminal::on_char(byte ch) set_cursor(m_cursor_row, 0); return; case '\n': - scroll_up(); + newline(); return; } @@ -532,7 +560,7 @@ void Terminal::on_char(byte ch) } else { if (m_stomp) { m_stomp = false; - scroll_up(); + newline(); put_character_at(m_cursor_row, m_cursor_column, ch); set_cursor(m_cursor_row, 1); } else { @@ -635,8 +663,7 @@ void Terminal::paint() } m_rows_to_scroll_backing_store = 0; - // Always redraw the line with the cursor on it. - line(m_cursor_row).dirty = true; + invalidate_cursor(); for (word row = 0; row < m_rows; ++row) { auto& line = this->line(row); diff --git a/Terminal/Terminal.h b/Terminal/Terminal.h index 7bc816ae73..06d8caa484 100644 --- a/Terminal/Terminal.h +++ b/Terminal/Terminal.h @@ -23,6 +23,7 @@ public: private: Font& font() { return *m_font; } void scroll_up(); + void newline(); void set_cursor(unsigned row, unsigned column); void put_character_at(unsigned row, unsigned column, byte ch); void invalidate_cursor(); @@ -41,6 +42,7 @@ private: void escape$H(const Vector&); void escape$J(const Vector&); void escape$K(const Vector&); + void escape$M(const Vector&); void escape$m(const Vector&); void escape$s(const Vector&); void escape$u(const Vector&); @@ -64,6 +66,10 @@ private: unsigned foreground_color : 4; unsigned background_color : 4; //bool bold : 1; + bool operator==(const Attribute& other) const + { + return foreground_color == other.foreground_color && background_color == other.background_color; + } }; struct Line {