1 // daemon/Screen.hh 2 // This file is part of AnyTerm; see http://anyterm.org/ 3 // (C) 2006-2007 Philip Endecott 4 5 // This program is free software; you can redistribute it and/or modify 6 // it under the terms of the GNU General Public License as published by 7 // the Free Software Foundation; either version 2 of the License, or 8 // any later version. 9 // 10 // This program is distributed in the hope that it will be useful, 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 // GNU General Public License for more details. 14 // 15 // You should have received a copy of the GNU General Public License 16 // along with this program; if not, write to the Free Software 17 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 18 19 #ifndef Screen_hh 20 #define Screen_hh 21 22 #include <vector> 23 #include <algorithm> 24 25 #include "Cell.hh" 26 27 28 class Screen { 29 int rows_; 30 int cols_; 31 int scrollback_; 32 typedef std::vector<Cell> row_t; 33 typedef std::vector<row_t*> cells_t; 34 cells_t cells; 35 unsigned int wrap; 36 37 public: Screen(int rows,int cols,int scrollback=0)38 Screen(int rows, int cols, int scrollback=0): 39 rows_(rows), cols_(cols), scrollback_(scrollback), 40 wrap(0), 41 cursor_row(0), cursor_col(0), cursor_visible(true) 42 { 43 for (int r=0; r<scrollback; ++r) { 44 cells.push_back(new row_t(cols)); // leaks if it throws 45 } 46 for (int r=0; r<rows; ++r) { 47 cells.push_back(new row_t(cols)); // leaks if it throws 48 } 49 } 50 ~Screen()51 ~Screen() { 52 for (cells_t::iterator i = cells.begin(); 53 i != cells.end(); ++i) { 54 delete *i; 55 } 56 } 57 rows() const58 int rows() const { 59 return rows_; 60 } 61 cols() const62 int cols() const { 63 return cols_; 64 } 65 scrollback() const66 int scrollback() const { 67 return scrollback_; 68 } 69 operator ()(int r,int c)70 Cell& operator()(int r, int c) 71 { 72 return (*cells[row_idx(r)])[c]; 73 } 74 operator ()(int r,int c) const75 const Cell& operator()(int r, int c) const 76 { 77 return (*cells[row_idx(r)])[c]; 78 } 79 scroll_down(int top,int bottom,int n=1)80 void scroll_down(int top, int bottom, int n=1) 81 { 82 // If we're asked to scroll the whole visible screen down, we scroll 83 // into the scrollback region. Otherwise, the scrollback region is 84 // not changed. 85 if (top==0 && bottom==rows()-1) { 86 wrap = (wrap+n)%(rows()+scrollback()); 87 } else { 88 normalise_wrap(); 89 std::rotate(cells.begin()+scrollback()+top, cells.begin()+scrollback()+top+n, 90 cells.begin()+scrollback()+bottom+1); 91 } 92 for (int r=bottom+1-n; r<=bottom; ++r) { 93 clear_row(r); 94 } 95 } 96 scroll_up(int top,int bottom,int n=1)97 void scroll_up(int top, int bottom, int n=1) 98 { 99 // Never touch the scrollback region. 100 if (scrollback()==0 && top==0 && bottom==rows()-1) { 101 wrap = (wrap-n)%(rows()+scrollback()); 102 } else { 103 normalise_wrap(); 104 std::rotate(cells.begin()+scrollback()+top, cells.begin()+scrollback()+bottom+1-n, 105 cells.begin()+scrollback()+bottom+1); 106 } 107 for (int r=top; r<top+n; ++r) { 108 clear_row(r); 109 } 110 } 111 112 int cursor_row; 113 int cursor_col; 114 bool cursor_visible; 115 116 117 private: row_idx(int r) const118 int row_idx(int r) const { 119 return (r+scrollback()+wrap)%(rows()+scrollback()); 120 } 121 clear_row(int r)122 void clear_row(int r) { 123 row_t& row = *(cells[row_idx(r)]); 124 for (int c=0; c<cols(); ++c) { 125 row[c] = Cell(); // FIXME this should probably use the terminal's current attributes 126 // (e.g. background colour) 127 } 128 } 129 normalise_wrap()130 void normalise_wrap() { 131 if (wrap==0) { 132 return; 133 } 134 std::rotate(cells.begin(), cells.begin()+wrap, cells.end()); 135 wrap=0; 136 } 137 }; 138 139 140 #endif 141