소스 검색

Terminal: Add limited support for 'M' escape sequence (delete line.)

Andreas Kling 6 년 전
부모
커밋
3944c00f23
2개의 변경된 파일48개의 추가작업 그리고 15개의 파일을 삭제
  1. 42 15
      Terminal/Terminal.cpp
  2. 6 0
      Terminal/Terminal.h

+ 42 - 15
Terminal/Terminal.cpp

@@ -337,6 +337,25 @@ void Terminal::escape$J(const Vector<unsigned>& params)
     }
 }
 
+void Terminal::escape$M(const Vector<unsigned>& 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);

+ 6 - 0
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<unsigned>&);
     void escape$J(const Vector<unsigned>&);
     void escape$K(const Vector<unsigned>&);
+    void escape$M(const Vector<unsigned>&);
     void escape$m(const Vector<unsigned>&);
     void escape$s(const Vector<unsigned>&);
     void escape$u(const Vector<unsigned>&);
@@ -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 {