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