1 /* 2 * Copyright 2008, Ingo Weinhold, ingo_weinhold@gmx.de. 3 * Distributed under the terms of the MIT License. 4 */ 5 #ifndef BASIC_TERMINAL_BUFFER_H 6 #define BASIC_TERMINAL_BUFFER_H 7 8 #include <limits.h> 9 10 #include "HistoryBuffer.h" 11 #include "TermPos.h" 12 #include "UTF8Char.h" 13 14 15 class BString; 16 class TerminalCharClassifier; 17 struct TerminalLine; 18 19 20 struct TerminalBufferDirtyInfo { 21 int32 linesScrolled; // number of lines added to the history 22 int32 dirtyTop; // dirty line range 23 int32 dirtyBottom; // 24 bool messageSent; // listener has been notified 25 26 bool IsDirtyRegionValid() const 27 { 28 return dirtyTop <= dirtyBottom; 29 } 30 31 void ExtendDirtyRegion(int32 top, int32 bottom) 32 { 33 if (top < dirtyTop) 34 dirtyTop = top; 35 if (bottom > dirtyBottom) 36 dirtyBottom = bottom; 37 } 38 39 void Reset() 40 { 41 linesScrolled = 0; 42 dirtyTop = INT_MAX; 43 dirtyBottom = INT_MIN; 44 messageSent = false; 45 } 46 }; 47 48 49 class BasicTerminalBuffer { 50 public: 51 BasicTerminalBuffer(); 52 virtual ~BasicTerminalBuffer(); 53 54 status_t Init(int32 width, int32 height, 55 int32 historyCapacity); 56 57 int32 Width() const { return fWidth; } 58 int32 Height() const { return fHeight; } 59 inline int32 HistorySize() const; 60 inline int32 HistoryCapacity() const; 61 62 TerminalBufferDirtyInfo& DirtyInfo() { return fDirtyInfo; } 63 64 status_t ResizeTo(int32 width, int32 height); 65 status_t ResizeTo(int32 width, int32 height, 66 int32 historyCapacity); 67 status_t SetHistoryCapacity(int32 historyCapacity); 68 void Clear(); 69 70 void SynchronizeWith( 71 const BasicTerminalBuffer* other, 72 int32 offset, int32 dirtyTop, 73 int32 dirtyBottom); 74 75 bool IsFullWidthChar(int32 row, int32 column) const; 76 int GetChar(int32 row, int32 column, 77 UTF8Char& character, 78 uint16& attributes) const; 79 int32 GetString(int32 row, int32 firstColumn, 80 int32 lastColumn, char* buffer, 81 uint16& attributes) const; 82 void GetStringFromRegion(BString& string, 83 const TermPos& start, 84 const TermPos& end) const; 85 bool FindWord(const TermPos& pos, 86 TerminalCharClassifier* classifier, 87 bool findNonWords, TermPos& start, 88 TermPos& end) const; 89 int32 LineLength(int32 index) const; 90 91 bool Find(const char* pattern, const TermPos& start, 92 bool forward, bool caseSensitive, 93 bool matchWord, TermPos& matchStart, 94 TermPos& matchEnd) const; 95 96 // insert chars/lines 97 void InsertChar(UTF8Char c, uint32 attributes); 98 inline void InsertChar(const char* c, int32 length, 99 uint32 attributes); 100 void InsertCR(); 101 void InsertLF(); 102 void SetInsertMode(int flag); 103 void InsertSpace(int32 num); 104 void InsertLines(int32 numLines); 105 106 // delete chars/lines 107 void EraseBelow(); 108 void DeleteChars(int32 numChars); 109 void DeleteColumns(); 110 void DeleteLines(int32 numLines); 111 112 // get and set cursor position 113 void SetCursor(int32 x, int32 y); 114 inline void SetCursorX(int32 x); 115 inline void SetCursorY(int32 y); 116 inline TermPos Cursor() const { return fCursor; } 117 void SaveCursor(); 118 void RestoreCursor(); 119 120 // move cursor 121 inline void MoveCursorRight(int32 num); 122 inline void MoveCursorLeft(int32 num); 123 inline void MoveCursorUp(int32 num); 124 inline void MoveCursorDown(int32 num); 125 126 // scroll region 127 inline void ScrollBy(int32 numLines); 128 void SetScrollRegion(int32 top, int32 bot); 129 130 protected: 131 virtual void NotifyListener(); 132 133 inline int32 _LineIndex(int32 index) const; 134 inline TerminalLine* _LineAt(int32 index) const; 135 inline TerminalLine* _HistoryLineAt(int32 index, 136 TerminalLine* lineBuffer) const; 137 138 inline void _Invalidate(int32 top, int32 bottom); 139 inline void _CursorChanged(); 140 141 static TerminalLine** _AllocateLines(int32 width, int32 count); 142 static void _FreeLines(TerminalLine** lines, int32 count); 143 void _ClearLines(int32 first, int32 last); 144 145 status_t _ResizeHistory(int32 width, 146 int32 historyCapacity); 147 status_t _ResizeSimple(int32 width, int32 height, 148 int32 historyCapacity); 149 status_t _ResizeRewrap(int32 width, int32 height, 150 int32 historyCapacity); 151 152 void _Scroll(int32 top, int32 bottom, 153 int32 numLines); 154 void _SoftBreakLine(); 155 void _PadLineToCursor(); 156 static void _TruncateLine(TerminalLine* line, int32 length); 157 void _InsertGap(int32 width); 158 bool _GetPartialLineString(BString& string, 159 int32 row, int32 startColumn, 160 int32 endColumn) const; 161 bool _PreviousChar(TermPos& pos, UTF8Char& c) const; 162 bool _NextChar(TermPos& pos, UTF8Char& c) const; 163 164 protected: 165 // screen width/height 166 int32 fWidth; 167 int32 fHeight; 168 169 // scroll region top/bottom 170 int32 fScrollTop; // first line to scroll 171 int32 fScrollBottom; // last line to scroll (incl.) 172 173 // line buffers for the history (ring buffer) 174 TerminalLine** fScreen; 175 int32 fScreenOffset; // index of screen line 0 176 HistoryBuffer* fHistory; 177 178 // cursor position (origin: (0, 0)) 179 TermPos fCursor; 180 TermPos fSavedCursor; 181 182 bool fOverwriteMode; // false for insert 183 184 int fEncoding; 185 186 // listener/dirty region management 187 TerminalBufferDirtyInfo fDirtyInfo; 188 }; 189 190 191 int32 192 BasicTerminalBuffer::HistorySize() const 193 { 194 return fHistory != NULL ? fHistory->Size() : 0; 195 } 196 197 198 int32 199 BasicTerminalBuffer::HistoryCapacity() const 200 { 201 return fHistory != NULL ? fHistory->Capacity() : 0; 202 } 203 204 205 void 206 BasicTerminalBuffer::InsertChar(const char* c, int32 length, uint32 attributes) 207 { 208 return InsertChar(UTF8Char(c, length), attributes); 209 } 210 211 212 void 213 BasicTerminalBuffer::SetCursorX(int32 x) 214 { 215 SetCursor(x, fCursor.y); 216 } 217 218 219 void 220 BasicTerminalBuffer::SetCursorY(int32 y) 221 { 222 SetCursor(fCursor.x, y); 223 } 224 225 226 void 227 BasicTerminalBuffer::MoveCursorRight(int32 num) 228 { 229 SetCursor(fCursor.x + num, fCursor.y); 230 } 231 232 233 void 234 BasicTerminalBuffer::MoveCursorLeft(int32 num) 235 { 236 SetCursor(fCursor.x - num, fCursor.y); 237 } 238 239 240 void 241 BasicTerminalBuffer::MoveCursorUp(int32 num) 242 { 243 SetCursor(fCursor.x, fCursor.y - num); 244 } 245 246 247 void 248 BasicTerminalBuffer::MoveCursorDown(int32 num) 249 { 250 SetCursor(fCursor.x, fCursor.y + num); 251 } 252 253 254 void 255 BasicTerminalBuffer::ScrollBy(int32 numLines) 256 { 257 _Scroll(fScrollTop, fScrollBottom, numLines); 258 } 259 260 261 #endif // BASIC_TERMINAL_BUFFER_H 262