xref: /haiku/src/apps/terminal/BasicTerminalBuffer.h (revision a127b88ecbfab58f64944c98aa47722a18e363b2)
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 									Attributes& attributes) const;
95 			void				GetCellAttributes(int32 row, int32 column,
96 									Attributes& attributes, uint32& count) const;
97 			int32				GetString(int32 row, int32 firstColumn,
98 									int32 lastColumn, char* buffer,
99 									Attributes& 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 			void				GetLineColor(int32 index, Attributes& attr) 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	Attributes			GetAttributes();
124 	inline	void				SetAttributes(const Attributes& 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, Attributes &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 			void				InsertLastChar();
145 
146 			// delete chars/lines
147 	inline	void				EraseChars(int32 numChars);
148 			void				EraseCharsFrom(int32 first, int32 numChars);
149 			void				EraseAbove();
150 			void				EraseBelow();
151 			void				EraseAll();
152 			void				DeleteChars(int32 numChars);
153 	inline	void				DeleteColumns();
154 			void				DeleteColumnsFrom(int32 first);
155 			void				DeleteLines(int32 numLines);
156 
157 			// get and set cursor position
158 	inline	void				SetCursor(int32 x, int32 y);
159 	inline	void				SetCursorX(int32 x);
160 	inline	void				SetCursorY(int32 y);
161 	inline	TermPos				Cursor() const			{ return fCursor; }
162 			void				SaveCursor();
163 			void				RestoreCursor();
164 
165 			// move cursor
166 	inline	void				MoveCursorRight(int32 num);
167 	inline	void				MoveCursorLeft(int32 num);
168 	inline	void				MoveCursorUp(int32 num);
169 	inline	void				MoveCursorDown(int32 num);
170 	inline	void				NextLine();
171 
172 			// scroll region
173 	inline	void				ScrollBy(int32 numLines);
174 			void				SetScrollRegion(int32 top, int32 bottom);
175 			void				SetOriginMode(bool enabled);
176 			void				SaveOriginMode();
177 			void				RestoreOriginMode();
178 			void				SetTabStop(int32 x);
179 			void				ClearTabStop(int32 x);
180 			void				ClearAllTabStops();
181 
182 protected:
183 	virtual	void				NotifyListener();
184 
185 	inline	int32				_LineIndex(int32 index) const;
186 	inline	TerminalLine*		_LineAt(int32 index) const;
187 	inline	TerminalLine*		_HistoryLineAt(int32 index,
188 									TerminalLine* lineBuffer) const;
189 
190 	inline	void				_Invalidate(int32 top, int32 bottom);
191 	inline	void				_CursorChanged();
192 			void				_SetCursor(int32 x, int32 y, bool absolute);
193 			void				_InvalidateAll();
194 
195 	static	TerminalLine**		_AllocateLines(int32 width, int32 count);
196 	static	void				_FreeLines(TerminalLine** lines, int32 count);
197 			void				_ClearLines(int32 first, int32 last);
198 
199 			status_t			_ResizeHistory(int32 width,
200 									int32 historyCapacity);
201 			status_t			_ResizeSimple(int32 width, int32 height,
202 									int32 historyCapacity);
203 			status_t			_ResizeRewrap(int32 width, int32 height,
204 									int32 historyCapacity);
205 			status_t			_ResetTabStops(int32 width);
206 
207 			void				_Scroll(int32 top, int32 bottom,
208 									int32 numLines);
209 			void				_SoftBreakLine();
210 			void				_PadLineToCursor();
211 	static	void				_TruncateLine(TerminalLine* line, int32 length);
212 			void				_InsertGap(int32 width);
213 			TerminalLine*		_GetPartialLineString(BString& string,
214 									int32 row, int32 startColumn,
215 									int32 endColumn) const;
216 			bool				_PreviousChar(TermPos& pos, UTF8Char& c) const;
217 			bool				_NextChar(TermPos& pos, UTF8Char& c) const;
218 
219 			bool				_PreviousLinePos(TerminalLine* lineBuffer,
220 									TerminalLine*& line, TermPos& pos) const;
221 			bool				_NormalizeLinePos(TerminalLine* lineBuffer,
222 									TerminalLine*& line, TermPos& pos) const;
223 
224 protected:
225 			// screen width/height
226 			int32				fWidth;
227 			int32				fHeight;
228 
229 			// scroll region top/bottom
230 			int32				fScrollTop;		// first line to scroll
231 			int32				fScrollBottom;	// last line to scroll (incl.)
232 
233 			// line buffers for the history (ring buffer)
234 			TerminalLine**		fScreen;
235 			int32				fScreenOffset;	// index of screen line 0
236 			HistoryBuffer*		fHistory;
237 
238 			Attributes			fAttributes;
239 
240 			// cursor position (origin: (0, 0))
241 			TermPos				fCursor;
242 			std::stack<TermPos>	fSavedCursors;
243 			bool				fSoftWrappedCursor;
244 
245 			bool				fOverwriteMode;	// false for insert
246 			bool				fAlternateScreenActive;
247 			bool				fOriginMode;
248 			bool				fSavedOriginMode;
249 			bool*				fTabStops;
250 
251 			int					fEncoding;
252 			int					fCaptureFile;
253 
254 			UTF8Char			fLast;
255 
256 			// listener/dirty region management
257 			TerminalBufferDirtyInfo fDirtyInfo;
258 };
259 
260 
261 int32
262 BasicTerminalBuffer::HistorySize() const
263 {
264 	return fHistory != NULL ? fHistory->Size() : 0;
265 }
266 
267 
268 int32
269 BasicTerminalBuffer::HistoryCapacity() const
270 {
271 	return fHistory != NULL ? fHistory->Capacity() : 0;
272 }
273 
274 
275 Attributes
276 BasicTerminalBuffer::GetAttributes()
277 {
278 	return fAttributes;
279 }
280 
281 
282 void
283 BasicTerminalBuffer::SetAttributes(const Attributes& attributes)
284 {
285 	fAttributes = attributes;
286 }
287 
288 
289 void
290 BasicTerminalBuffer::EraseChars(int32 numChars)
291 {
292 	EraseCharsFrom(fCursor.x, numChars);
293 }
294 
295 
296 void
297 BasicTerminalBuffer::DeleteColumns()
298 {
299 	DeleteColumnsFrom(fCursor.x);
300 }
301 
302 
303 void
304 BasicTerminalBuffer::SetCursor(int32 x, int32 y)
305 {
306 	_SetCursor(x, y, false);
307 }
308 
309 
310 void
311 BasicTerminalBuffer::SetCursorX(int32 x)
312 {
313 	SetCursor(x, fCursor.y);
314 }
315 
316 
317 void
318 BasicTerminalBuffer::SetCursorY(int32 y)
319 {
320 	SetCursor(fCursor.x, y);
321 }
322 
323 
324 void
325 BasicTerminalBuffer::MoveCursorRight(int32 num)
326 {
327 	SetCursor(fCursor.x + num, fCursor.y);
328 }
329 
330 
331 void
332 BasicTerminalBuffer::MoveCursorLeft(int32 num)
333 {
334 	SetCursor(fCursor.x - num, fCursor.y);
335 }
336 
337 
338 void
339 BasicTerminalBuffer::MoveCursorUp(int32 num)
340 {
341 	SetCursor(fCursor.x, fCursor.y - num);
342 }
343 
344 
345 void
346 BasicTerminalBuffer::MoveCursorDown(int32 num)
347 {
348 	SetCursor(fCursor.x, fCursor.y + num);
349 }
350 
351 
352 void
353 BasicTerminalBuffer::ScrollBy(int32 numLines)
354 {
355 	_Scroll(fScrollTop, fScrollBottom, numLines);
356 }
357 
358 
359 void
360 BasicTerminalBuffer::NextLine()
361 {
362 	SetCursor(0, fCursor.y + 1);
363 }
364 
365 #endif	// BASIC_TERMINAL_BUFFER_H
366