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