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 bool IsAlternateScreenActive() const 65 { return fAlternateScreenActive; } 66 67 TerminalBufferDirtyInfo& DirtyInfo() { return fDirtyInfo; } 68 69 virtual status_t ResizeTo(int32 width, int32 height); 70 virtual status_t ResizeTo(int32 width, int32 height, 71 int32 historyCapacity); 72 status_t SetHistoryCapacity(int32 historyCapacity); 73 void Clear(bool resetCursor); 74 75 void SynchronizeWith( 76 const BasicTerminalBuffer* other, 77 int32 offset, int32 dirtyTop, 78 int32 dirtyBottom); 79 80 bool IsFullWidthChar(int32 row, int32 column) const; 81 int GetChar(int32 row, int32 column, 82 UTF8Char& character, 83 uint32& attributes) const; 84 int32 GetString(int32 row, int32 firstColumn, 85 int32 lastColumn, char* buffer, 86 uint32& attributes) const; 87 void GetStringFromRegion(BString& string, 88 const TermPos& start, 89 const TermPos& end) const; 90 bool FindWord(const TermPos& pos, 91 TerminalCharClassifier* classifier, 92 bool findNonWords, TermPos& start, 93 TermPos& end) const; 94 int32 LineLength(int32 index) const; 95 int32 GetLineColor(int32 index) const; 96 97 bool Find(const char* pattern, const TermPos& start, 98 bool forward, bool caseSensitive, 99 bool matchWord, TermPos& matchStart, 100 TermPos& matchEnd) const; 101 102 // insert chars/lines 103 inline void InsertChar(UTF8Char c, uint32 attributes); 104 void InsertChar(UTF8Char c, uint32 width, 105 uint32 attributes); 106 inline void InsertChar(const char* c, int32 length, 107 uint32 attributes); 108 inline void InsertChar(const char* c, int32 length, 109 uint32 width, uint32 attributes); 110 void FillScreen(UTF8Char c, uint32 width, uint32 attr); 111 112 void InsertCR(uint32 attrs); 113 void InsertLF(); 114 void InsertRI(); 115 void InsertTab(uint32 attr); 116 void SetInsertMode(int flag); 117 void InsertSpace(int32 num); 118 void InsertLines(int32 numLines); 119 120 // delete chars/lines 121 inline void EraseChars(int32 numChars); 122 void EraseCharsFrom(int32 first, int32 numChars); 123 void EraseAbove(); 124 void EraseBelow(); 125 void EraseAll(); 126 void DeleteChars(int32 numChars); 127 inline void DeleteColumns(); 128 void DeleteColumnsFrom(int32 first); 129 void DeleteLines(int32 numLines); 130 131 // get and set cursor position 132 inline void SetCursor(int32 x, int32 y); 133 inline void SetCursorX(int32 x); 134 inline void SetCursorY(int32 y); 135 inline TermPos Cursor() const { return fCursor; } 136 void SaveCursor(); 137 void RestoreCursor(); 138 139 // move cursor 140 inline void MoveCursorRight(int32 num); 141 inline void MoveCursorLeft(int32 num); 142 inline void MoveCursorUp(int32 num); 143 inline void MoveCursorDown(int32 num); 144 145 // scroll region 146 inline void ScrollBy(int32 numLines); 147 void SetScrollRegion(int32 top, int32 bottom); 148 void SetOriginMode(bool enabled); 149 void SaveOriginMode(); 150 void RestoreOriginMode(); 151 void SetTabStop(int32 x); 152 void ClearTabStop(int32 x); 153 void ClearAllTabStops(); 154 155 protected: 156 virtual void NotifyListener(); 157 158 inline int32 _LineIndex(int32 index) const; 159 inline TerminalLine* _LineAt(int32 index) const; 160 inline TerminalLine* _HistoryLineAt(int32 index, 161 TerminalLine* lineBuffer) const; 162 163 inline void _Invalidate(int32 top, int32 bottom); 164 inline void _CursorChanged(); 165 void _SetCursor(int32 x, int32 y, bool absolute); 166 void _InvalidateAll(); 167 168 static TerminalLine** _AllocateLines(int32 width, int32 count); 169 static void _FreeLines(TerminalLine** lines, int32 count); 170 void _ClearLines(int32 first, int32 last); 171 172 status_t _ResizeHistory(int32 width, 173 int32 historyCapacity); 174 status_t _ResizeSimple(int32 width, int32 height, 175 int32 historyCapacity); 176 status_t _ResizeRewrap(int32 width, int32 height, 177 int32 historyCapacity); 178 status_t _ResetTabStops(int32 width); 179 180 void _Scroll(int32 top, int32 bottom, 181 int32 numLines); 182 void _SoftBreakLine(); 183 void _PadLineToCursor(); 184 static void _TruncateLine(TerminalLine* line, int32 length); 185 void _InsertGap(int32 width); 186 TerminalLine* _GetPartialLineString(BString& string, 187 int32 row, int32 startColumn, 188 int32 endColumn) const; 189 bool _PreviousChar(TermPos& pos, UTF8Char& c) const; 190 bool _NextChar(TermPos& pos, UTF8Char& c) const; 191 192 protected: 193 // screen width/height 194 int32 fWidth; 195 int32 fHeight; 196 197 // scroll region top/bottom 198 int32 fScrollTop; // first line to scroll 199 int32 fScrollBottom; // last line to scroll (incl.) 200 201 // line buffers for the history (ring buffer) 202 TerminalLine** fScreen; 203 int32 fScreenOffset; // index of screen line 0 204 HistoryBuffer* fHistory; 205 206 // cursor position (origin: (0, 0)) 207 TermPos fCursor; 208 TermPos fSavedCursor; 209 bool fSoftWrappedCursor; 210 211 bool fOverwriteMode; // false for insert 212 bool fAlternateScreenActive; 213 bool fOriginMode; 214 bool fSavedOriginMode; 215 bool* fTabStops; 216 217 int fEncoding; 218 219 // listener/dirty region management 220 TerminalBufferDirtyInfo fDirtyInfo; 221 }; 222 223 224 int32 225 BasicTerminalBuffer::HistorySize() const 226 { 227 return fHistory != NULL ? fHistory->Size() : 0; 228 } 229 230 231 int32 232 BasicTerminalBuffer::HistoryCapacity() const 233 { 234 return fHistory != NULL ? fHistory->Capacity() : 0; 235 } 236 237 238 void 239 BasicTerminalBuffer::InsertChar(UTF8Char c, uint32 attributes) 240 { 241 return InsertChar(c, 1, attributes); 242 } 243 244 245 void 246 BasicTerminalBuffer::InsertChar(const char* c, int32 length, uint32 attributes) 247 { 248 return InsertChar(UTF8Char(c, length), 1, attributes); 249 } 250 251 252 void 253 BasicTerminalBuffer::InsertChar(const char* c, int32 length, uint32 width, uint32 attributes) 254 { 255 return InsertChar(UTF8Char(c, length), width, attributes); 256 } 257 258 259 void 260 BasicTerminalBuffer::EraseChars(int32 numChars) 261 { 262 EraseCharsFrom(fCursor.x, numChars); 263 } 264 265 void 266 BasicTerminalBuffer::DeleteColumns() 267 { 268 DeleteColumnsFrom(fCursor.x); 269 } 270 271 void 272 BasicTerminalBuffer::SetCursor(int32 x, int32 y) 273 { 274 _SetCursor(x, y, false); 275 } 276 277 void 278 BasicTerminalBuffer::SetCursorX(int32 x) 279 { 280 SetCursor(x, fCursor.y); 281 } 282 283 284 void 285 BasicTerminalBuffer::SetCursorY(int32 y) 286 { 287 SetCursor(fCursor.x, y); 288 } 289 290 291 void 292 BasicTerminalBuffer::MoveCursorRight(int32 num) 293 { 294 SetCursor(fCursor.x + num, fCursor.y); 295 } 296 297 298 void 299 BasicTerminalBuffer::MoveCursorLeft(int32 num) 300 { 301 SetCursor(fCursor.x - num, fCursor.y); 302 } 303 304 305 void 306 BasicTerminalBuffer::MoveCursorUp(int32 num) 307 { 308 SetCursor(fCursor.x, fCursor.y - num); 309 } 310 311 312 void 313 BasicTerminalBuffer::MoveCursorDown(int32 num) 314 { 315 SetCursor(fCursor.x, fCursor.y + num); 316 } 317 318 319 void 320 BasicTerminalBuffer::ScrollBy(int32 numLines) 321 { 322 _Scroll(fScrollTop, fScrollBottom, numLines); 323 } 324 325 326 #endif // BASIC_TERMINAL_BUFFER_H 327