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