xref: /haiku/src/apps/terminal/BasicTerminalBuffer.h (revision 21258e2674226d6aa732321b6f8494841895af5f)
1 /*
2  * Copyright 2013, Haiku, Inc. All rights reserved.
3  * Copyright 2008, Ingo Weinhold, ingo_weinhold@gmx.de.
4  * Distributed under the terms of the MIT License.
5  *
6  * Authors:
7  *		Ingo Weinhold, ingo_weinhold@gmx.de
8  *		Siarzhuk Zharski, zharik@gmx.li
9  */
10 #ifndef BASIC_TERMINAL_BUFFER_H
11 #define BASIC_TERMINAL_BUFFER_H
12 
13 #include <limits.h>
14 #include <stack>
15 
16 #include "HistoryBuffer.h"
17 #include "TermPos.h"
18 #include "UTF8Char.h"
19 
20 
21 class BString;
22 class TerminalCharClassifier;
23 struct TerminalLine;
24 
25 
26 struct TerminalBufferDirtyInfo {
27 	int32	linesScrolled;			// number of lines added to the history
28 	int32	dirtyTop;				// dirty line range
29 	int32	dirtyBottom;			//
30 	bool	invalidateAll;
31 	bool	messageSent;			// listener has been notified
32 
33 	bool IsDirtyRegionValid() const
34 	{
35 		return dirtyTop <= dirtyBottom;
36 	}
37 
38 	void ExtendDirtyRegion(int32 top, int32 bottom)
39 	{
40 		if (top < dirtyTop)
41 			dirtyTop = top;
42 		if (bottom > dirtyBottom)
43 			dirtyBottom = bottom;
44 	}
45 
46 	void Reset()
47 	{
48 		linesScrolled = 0;
49 		dirtyTop = INT_MAX;
50 		dirtyBottom = INT_MIN;
51 		invalidateAll = false;
52 		messageSent = false;
53 	}
54 
55 	TerminalBufferDirtyInfo()
56 	{
57 		Reset();
58 	}
59 };
60 
61 
62 class BasicTerminalBuffer {
63 public:
64 								BasicTerminalBuffer();
65 	virtual						~BasicTerminalBuffer();
66 
67 			status_t			Init(int32 width, int32 height,
68 									int32 historyCapacity);
69 
70 			int32				Width() const		{ return fWidth; }
71 			int32				Height() const		{ return fHeight; }
72 	inline	int32				HistorySize() const;
73 	inline	int32				HistoryCapacity() const;
74 
75 			bool				IsAlternateScreenActive() const
76 									{ return fAlternateScreenActive; }
77 
78 			TerminalBufferDirtyInfo& DirtyInfo()	{ return fDirtyInfo; }
79 
80 	virtual	status_t			ResizeTo(int32 width, int32 height);
81 	virtual	status_t			ResizeTo(int32 width, int32 height,
82 									int32 historyCapacity);
83 			status_t			SetHistoryCapacity(int32 historyCapacity);
84 			void				Clear(bool resetCursor);
85 
86 			void				SynchronizeWith(
87 									const BasicTerminalBuffer* other,
88 									int32 offset, int32 dirtyTop,
89 									int32 dirtyBottom);
90 
91 			bool				IsFullWidthChar(int32 row, int32 column) const;
92 			int					GetChar(int32 row, int32 column,
93 									UTF8Char& character,
94 									uint32& attributes) const;
95 			void				GetCellAttributes(int32 row, int32 column,
96 									uint32& attributes, uint32& count) const;
97 			int32				GetString(int32 row, int32 firstColumn,
98 									int32 lastColumn, char* buffer,
99 									uint32& attributes) const;
100 			void				GetStringFromRegion(BString& string,
101 									const TermPos& start,
102 									const TermPos& end) const;
103 			bool				FindWord(const TermPos& pos,
104 									TerminalCharClassifier* classifier,
105 									bool findNonWords, TermPos& start,
106 									TermPos& end) const;
107 			int32				LineLength(int32 index) const;
108 			int32				GetLineColor(int32 index) const;
109 
110 			bool				PreviousLinePos(TermPos& pos) const;
111 			bool				NextLinePos(TermPos& pos, bool normalize) const;
112 									// normalize specifies that the returned
113 									// position must be a valid position, i.e.
114 									// actually point to a character (as opposed
115 									// to just pointing to the position after a
116 									// character).
117 
118 			bool				Find(const char* pattern, const TermPos& start,
119 									bool forward, bool caseSensitive,
120 									bool matchWord, TermPos& matchStart,
121 									TermPos& matchEnd) const;
122 
123 	inline	uint32				GetAttributes();
124 	inline	void				SetAttributes(uint32 attributes);
125 
126 			// snapshots and data capture for debugging
127 			void				MakeLinesSnapshots(time_t timeStamp,
128 									const char* fileName);
129 			void				StartStopDebugCapture();
130 			void				CaptureChar(char ch);
131 
132 			// insert chars/lines
133 			void				InsertChar(UTF8Char c);
134 			void				FillScreen(UTF8Char c, uint32 attr);
135 
136 			void				InsertCR();
137 			void				InsertLF();
138 			void				InsertRI();
139 			void				InsertTab();
140 			void				InsertCursorBackTab(int32 numTabs);
141 			void				SetInsertMode(int flag);
142 			void				InsertSpace(int32 num);
143 			void				InsertLines(int32 numLines);
144 
145 			// delete chars/lines
146 	inline	void				EraseChars(int32 numChars);
147 			void				EraseCharsFrom(int32 first, int32 numChars);
148 			void				EraseAbove();
149 			void				EraseBelow();
150 			void				EraseAll();
151 			void				DeleteChars(int32 numChars);
152 	inline	void				DeleteColumns();
153 			void				DeleteColumnsFrom(int32 first);
154 			void				DeleteLines(int32 numLines);
155 
156 			// get and set cursor position
157 	inline	void				SetCursor(int32 x, int32 y);
158 	inline	void				SetCursorX(int32 x);
159 	inline	void				SetCursorY(int32 y);
160 	inline	TermPos				Cursor() const			{ return fCursor; }
161 			void				SaveCursor();
162 			void				RestoreCursor();
163 
164 			// move cursor
165 	inline	void				MoveCursorRight(int32 num);
166 	inline	void				MoveCursorLeft(int32 num);
167 	inline	void				MoveCursorUp(int32 num);
168 	inline	void				MoveCursorDown(int32 num);
169 	inline	void				NextLine();
170 
171 			// scroll region
172 	inline	void				ScrollBy(int32 numLines);
173 			void				SetScrollRegion(int32 top, int32 bottom);
174 			void				SetOriginMode(bool enabled);
175 			void				SaveOriginMode();
176 			void				RestoreOriginMode();
177 			void				SetTabStop(int32 x);
178 			void				ClearTabStop(int32 x);
179 			void				ClearAllTabStops();
180 
181 protected:
182 	virtual	void				NotifyListener();
183 
184 	inline	int32				_LineIndex(int32 index) const;
185 	inline	TerminalLine*		_LineAt(int32 index) const;
186 	inline	TerminalLine*		_HistoryLineAt(int32 index,
187 									TerminalLine* lineBuffer) const;
188 
189 	inline	void				_Invalidate(int32 top, int32 bottom);
190 	inline	void				_CursorChanged();
191 			void				_SetCursor(int32 x, int32 y, bool absolute);
192 			void				_InvalidateAll();
193 
194 	static	TerminalLine**		_AllocateLines(int32 width, int32 count);
195 	static	void				_FreeLines(TerminalLine** lines, int32 count);
196 			void				_ClearLines(int32 first, int32 last);
197 
198 			status_t			_ResizeHistory(int32 width,
199 									int32 historyCapacity);
200 			status_t			_ResizeSimple(int32 width, int32 height,
201 									int32 historyCapacity);
202 			status_t			_ResizeRewrap(int32 width, int32 height,
203 									int32 historyCapacity);
204 			status_t			_ResetTabStops(int32 width);
205 
206 			void				_Scroll(int32 top, int32 bottom,
207 									int32 numLines);
208 			void				_SoftBreakLine();
209 			void				_PadLineToCursor();
210 	static	void				_TruncateLine(TerminalLine* line, int32 length);
211 			void				_InsertGap(int32 width);
212 			TerminalLine*		_GetPartialLineString(BString& string,
213 									int32 row, int32 startColumn,
214 									int32 endColumn) const;
215 			bool				_PreviousChar(TermPos& pos, UTF8Char& c) const;
216 			bool				_NextChar(TermPos& pos, UTF8Char& c) const;
217 
218 			bool				_PreviousLinePos(TerminalLine* lineBuffer,
219 									TerminalLine*& line, TermPos& pos) const;
220 			bool				_NormalizeLinePos(TerminalLine* lineBuffer,
221 									TerminalLine*& line, TermPos& pos) const;
222 
223 protected:
224 			// screen width/height
225 			int32				fWidth;
226 			int32				fHeight;
227 
228 			// scroll region top/bottom
229 			int32				fScrollTop;		// first line to scroll
230 			int32				fScrollBottom;	// last line to scroll (incl.)
231 
232 			// line buffers for the history (ring buffer)
233 			TerminalLine**		fScreen;
234 			int32				fScreenOffset;	// index of screen line 0
235 			HistoryBuffer*		fHistory;
236 
237 			uint32				fAttributes;
238 
239 			// cursor position (origin: (0, 0))
240 			TermPos				fCursor;
241 			std::stack<TermPos>	fSavedCursors;
242 			bool				fSoftWrappedCursor;
243 
244 			bool				fOverwriteMode;	// false for insert
245 			bool				fAlternateScreenActive;
246 			bool				fOriginMode;
247 			bool				fSavedOriginMode;
248 			bool*				fTabStops;
249 
250 			int					fEncoding;
251 			int					fCaptureFile;
252 
253 			// listener/dirty region management
254 			TerminalBufferDirtyInfo fDirtyInfo;
255 };
256 
257 
258 int32
259 BasicTerminalBuffer::HistorySize() const
260 {
261 	return fHistory != NULL ? fHistory->Size() : 0;
262 }
263 
264 
265 int32
266 BasicTerminalBuffer::HistoryCapacity() const
267 {
268 	return fHistory != NULL ? fHistory->Capacity() : 0;
269 }
270 
271 
272 uint32
273 BasicTerminalBuffer::GetAttributes()
274 {
275 	return fAttributes;
276 }
277 
278 
279 void
280 BasicTerminalBuffer::SetAttributes(uint32 attributes)
281 {
282 	fAttributes = attributes;
283 }
284 
285 
286 void
287 BasicTerminalBuffer::EraseChars(int32 numChars)
288 {
289 	EraseCharsFrom(fCursor.x, numChars);
290 }
291 
292 
293 void
294 BasicTerminalBuffer::DeleteColumns()
295 {
296 	DeleteColumnsFrom(fCursor.x);
297 }
298 
299 
300 void
301 BasicTerminalBuffer::SetCursor(int32 x, int32 y)
302 {
303 	_SetCursor(x, y, false);
304 }
305 
306 
307 void
308 BasicTerminalBuffer::SetCursorX(int32 x)
309 {
310 	SetCursor(x, fCursor.y);
311 }
312 
313 
314 void
315 BasicTerminalBuffer::SetCursorY(int32 y)
316 {
317 	SetCursor(fCursor.x, y);
318 }
319 
320 
321 void
322 BasicTerminalBuffer::MoveCursorRight(int32 num)
323 {
324 	SetCursor(fCursor.x + num, fCursor.y);
325 }
326 
327 
328 void
329 BasicTerminalBuffer::MoveCursorLeft(int32 num)
330 {
331 	SetCursor(fCursor.x - num, fCursor.y);
332 }
333 
334 
335 void
336 BasicTerminalBuffer::MoveCursorUp(int32 num)
337 {
338 	SetCursor(fCursor.x, fCursor.y - num);
339 }
340 
341 
342 void
343 BasicTerminalBuffer::MoveCursorDown(int32 num)
344 {
345 	SetCursor(fCursor.x, fCursor.y + num);
346 }
347 
348 
349 void
350 BasicTerminalBuffer::ScrollBy(int32 numLines)
351 {
352 	_Scroll(fScrollTop, fScrollBottom, numLines);
353 }
354 
355 
356 void
357 BasicTerminalBuffer::NextLine()
358 {
359 	SetCursor(0, fCursor.y + 1);
360 }
361 
362 #endif	// BASIC_TERMINAL_BUFFER_H
363