xref: /haiku/src/apps/terminal/BasicTerminalBuffer.h (revision 0d452c8f34013b611a54c746a71c05e28796eae2)
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