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