浏览代码

Terminal: Implement scroll region termcodes

Christopher Dumas 6 年之前
父节点
当前提交
ce15a4021d
共有 3 个文件被更改,包括 80 次插入6 次删除
  1. 71 6
      Applications/Terminal/Terminal.cpp
  2. 6 0
      Applications/Terminal/Terminal.h
  3. 3 0
      LibC/unistd.h

+ 71 - 6
Applications/Terminal/Terminal.cpp

@@ -254,7 +254,13 @@ void Terminal::escape$r(const ParamVector& params)
         top = params[0];
     if (params.size() >= 2)
         bottom = params[1];
-    dbgprintf("FIXME: escape$r: Set scrolling region: %u-%u\n", top, bottom);
+    if ((bottom - top) < 2 || bottom > m_rows) {
+        dbgprintf("Error: escape: scrolling region invalid: %u-%u\n", top, bottom);
+        return;
+    }
+    m_scroll_region_top = top;
+    m_scroll_region_bottom = bottom;
+    set_cursor(0, 0);
 }
 
 void Terminal::escape$H(const ParamVector& params)
@@ -415,6 +421,42 @@ void Terminal::escape$J(const ParamVector& params)
     }
 }
 
+void Terminal::escape$S(const ParamVector& params)
+{
+    int count = 1;
+    if (params.size() >= 1)
+        count = params[0];
+    dbgprintf("Terminal: Scrolling up %d lines\n", count);
+
+    for (word i = 0; i < count; i++)
+        scroll_up();
+}
+
+void Terminal::escape$T(const ParamVector& params)
+{
+    int count = 1;
+    if (params.size() >= 1)
+        count = params[0];
+    dbgprintf("Terminal: Scrolling down %d lines\n", count);
+
+    for (word i = 0; i < count; i++)
+        scroll_down();
+}
+
+void Terminal::escape$L(const ParamVector& params)
+{
+    int count = 1;
+    if (params.size() >= 1)
+        count = params[0];
+    dbgprintf("Terminal: Adding %d lines below cursor (at line %d)\n", count, m_cursor_row);
+    invalidate_cursor();
+    for (word row = m_rows; row > m_cursor_row; --row)
+        m_lines[row] = m_lines[row - 1];
+    m_lines[m_cursor_row] = new Line(m_columns);
+    ++m_rows_to_scroll_backing_store;
+    m_need_full_flush = true;
+}
+
 void Terminal::escape$M(const ParamVector& params)
 {
     int count = 1;
@@ -430,8 +472,11 @@ void Terminal::escape$M(const ParamVector& params)
     count = min(count, max_count);
 
     dbgprintf("Delete %d line(s) starting from %d\n", count, m_cursor_row);
-    // FIXME: Implement.
-    ASSERT_NOT_REACHED();
+    for (word i = 0; i < count; ++i)
+        delete m_lines[m_cursor_row + i];
+    for (word row = m_cursor_row + count + 1; row < rows(); ++row)
+        m_lines[row - 1] = m_lines[row];
+    m_lines[m_rows - 1]->clear(m_current_attribute);
 }
 
 void Terminal::execute_xterm_command()
@@ -480,6 +525,9 @@ void Terminal::execute_escape_sequence(byte final)
     case 'J': escape$J(params); break;
     case 'K': escape$K(params); break;
     case 'M': escape$M(params); break;
+    case 'S': escape$S(params); break;
+    case 'T': escape$T(params); break;
+    case 'L': escape$L(params); break;
     case 'G': escape$G(params); break;
     case 'X': escape$X(params); break;
     case 'd': escape$d(params); break;
@@ -512,14 +560,25 @@ 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)
+    delete m_lines[m_scroll_region_top];
+    for (word row = m_scroll_region_top + 1; row < m_scroll_region_bottom; ++row)
         m_lines[row - 1] = m_lines[row];
-    m_lines[m_rows - 1] = new Line(m_columns);
+    m_lines[m_scroll_region_bottom - 1] = new Line(m_columns);
     ++m_rows_to_scroll_backing_store;
     m_need_full_flush = true;
 }
 
+void Terminal::scroll_down()
+{
+    // NOTE: We have to invalidate the cursor first.
+    invalidate_cursor();
+    for (word row = m_scroll_region_bottom; row > m_scroll_region_top; --row)
+        m_lines[row] = m_lines[row - 1];
+    m_lines[m_scroll_region_top] = new Line(m_columns);
+    --m_rows_to_scroll_backing_store;
+    m_need_full_flush = true;
+}
+
 void Terminal::set_cursor(unsigned a_row, unsigned a_column)
 {
     unsigned row = min(a_row, m_rows - 1u);
@@ -718,6 +777,9 @@ void Terminal::set_size(word columns, word rows)
     m_columns = columns;
     m_rows = rows;
 
+    m_scroll_region_top = 0;
+    m_scroll_region_bottom = rows;
+
     m_cursor_row = 0;
     m_cursor_column = 0;
     m_saved_cursor_row = 0;
@@ -825,6 +887,9 @@ void Terminal::keydown_event(GKeyEvent& event)
     case KeyCode::Key_End:
         write(m_ptm_fd, "\033[F", 3);
         break;
+    case KeyCode::Key_RightShift:
+        dbgprintf("Terminal: A wild Right Shift key is pressed. Not handled.\n");
+        break;
     default:
         write(m_ptm_fd, &ch, 1);
         break;

+ 6 - 0
Applications/Terminal/Terminal.h

@@ -42,6 +42,7 @@ private:
     virtual const char* class_name() const override { return "Terminal"; }
 
     void scroll_up();
+    void scroll_down();
     void newline();
     void set_cursor(unsigned row, unsigned column);
     void put_character_at(unsigned row, unsigned column, byte ch);
@@ -68,6 +69,9 @@ private:
     void escape$u(const ParamVector&);
     void escape$t(const ParamVector&);
     void escape$r(const ParamVector&);
+    void escape$S(const ParamVector&);
+    void escape$T(const ParamVector&);
+    void escape$L(const ParamVector&);
 
     void clear();
 
@@ -144,6 +148,8 @@ private:
     bool m_stomp { false };
 
     bool m_should_beep { false };
+    byte m_scroll_region_top { 0 };
+    byte m_scroll_region_bottom { 0 };
 
     Attribute m_current_attribute;
 

+ 3 - 0
LibC/unistd.h

@@ -109,4 +109,7 @@ enum
  */
 #define _POSIX_PRIORITY_SCHEDULING
 
+// Stifle an less error iirc
+#define _PC_VDISABLE 8
+
 __END_DECLS