14386ce02SIngo Weinhold/*
25b41331fSSiarzhuk Zharski * Copyright 2013, Haiku, Inc. All rights reserved.
34386ce02SIngo Weinhold * Copyright 2008, Ingo Weinhold, ingo_weinhold@gmx.de.
44386ce02SIngo Weinhold * Distributed under the terms of the MIT License.
55b41331fSSiarzhuk Zharski *
65b41331fSSiarzhuk Zharski * Authors:
75b41331fSSiarzhuk Zharski *		Ingo Weinhold, ingo_weinhold@gmx.de
88840b3dbSSimon South *		Simon South, simon@simonsouth.net
95b41331fSSiarzhuk Zharski *		Siarzhuk Zharski, zharik@gmx.li
104386ce02SIngo Weinhold */
114386ce02SIngo Weinhold
124386ce02SIngo Weinhold#include "TerminalBuffer.h"
134386ce02SIngo Weinhold
14d04aae8bSIngo Weinhold#include <algorithm>
15d04aae8bSIngo Weinhold
1652b1d543SIngo Weinhold#include <Message.h>
1752b1d543SIngo Weinhold
18fe256869SSiarzhuk Zharski#include "Colors.h"
19fe256869SSiarzhuk Zharski#include "TermApp.h"
2052b1d543SIngo Weinhold#include "TermConst.h"
2152b1d543SIngo Weinhold
2252b1d543SIngo Weinhold
2352b1d543SIngo Weinhold// #pragma mark - public methods
2452b1d543SIngo Weinhold
254386ce02SIngo Weinhold
264386ce02SIngo WeinholdTerminalBuffer::TerminalBuffer()
2752b1d543SIngo Weinhold	:
2852b1d543SIngo Weinhold	BLocker("terminal buffer"),
29ecd79a2cSIngo Weinhold	fEncoding(M_UTF8),
30d04aae8bSIngo Weinhold	fAlternateScreen(NULL),
31d04aae8bSIngo Weinhold	fAlternateHistory(NULL),
32d04aae8bSIngo Weinhold	fAlternateScreenOffset(0),
331dd3b537SSiarzhuk Zharski	fAlternateAttributes(0),
34fe256869SSiarzhuk Zharski	fColorsPalette(NULL),
35ecd79a2cSIngo Weinhold	fListenerValid(false)
364386ce02SIngo Weinhold{
374386ce02SIngo Weinhold}
384386ce02SIngo Weinhold
394386ce02SIngo Weinhold
404386ce02SIngo WeinholdTerminalBuffer::~TerminalBuffer()
414386ce02SIngo Weinhold{
427ddb9624SMurai Takashi	free(fAlternateScreen);
43d04aae8bSIngo Weinhold	delete fAlternateHistory;
44fe256869SSiarzhuk Zharski	delete[] fColorsPalette;
4552b1d543SIngo Weinhold}
4652b1d543SIngo Weinhold
4752b1d543SIngo Weinhold
4852b1d543SIngo Weinholdstatus_t
4952b1d543SIngo WeinholdTerminalBuffer::Init(int32 width, int32 height, int32 historySize)
5052b1d543SIngo Weinhold{
51565155afSAugustin Cavalier	if (BLocker::InitCheck() < 0)
52565155afSAugustin Cavalier		return BLocker::InitCheck();
5352b1d543SIngo Weinhold
54d04aae8bSIngo Weinhold	fAlternateScreen = _AllocateLines(width, height);
55d04aae8bSIngo Weinhold	if (fAlternateScreen == NULL)
56d04aae8bSIngo Weinhold		return B_NO_MEMORY;
57d04aae8bSIngo Weinhold
587f6f9ddbSIngo Weinhold	for (int32 i = 0; i < height; i++)
597f6f9ddbSIngo Weinhold		fAlternateScreen[i]->Clear();
607f6f9ddbSIngo Weinhold
61fe256869SSiarzhuk Zharski	fColorsPalette = new(std::nothrow) rgb_color[kTermColorCount];
62fe256869SSiarzhuk Zharski	if (fColorsPalette == NULL)
63fe256869SSiarzhuk Zharski		return B_NO_MEMORY;
64fe256869SSiarzhuk Zharski
65e998f2e4SMurai Takashi	for (uint i = 0; i < kTermColorCount; i++)
66e998f2e4SMurai Takashi		fColorsPalette[i] = TermApp::DefaultPalette()[i];
67fe256869SSiarzhuk Zharski
6823450280SIngo Weinhold	return BasicTerminalBuffer::Init(width, height, historySize);
6952b1d543SIngo Weinhold}
7052b1d543SIngo Weinhold
7152b1d543SIngo Weinhold
7252b1d543SIngo Weinholdvoid
7352b1d543SIngo WeinholdTerminalBuffer::SetListener(BMessenger listener)
7452b1d543SIngo Weinhold{
7552b1d543SIngo Weinhold	fListener = listener;
76ecd79a2cSIngo Weinhold	fListenerValid = true;
77ecd79a2cSIngo Weinhold}
78ecd79a2cSIngo Weinhold
79ecd79a2cSIngo Weinhold
80ecd79a2cSIngo Weinholdvoid
81ecd79a2cSIngo WeinholdTerminalBuffer::UnsetListener()
82ecd79a2cSIngo Weinhold{
83ecd79a2cSIngo Weinhold	fListenerValid = false;
8452b1d543SIngo Weinhold}
8552b1d543SIngo Weinhold
8652b1d543SIngo Weinhold
8752b1d543SIngo Weinholdint
8852b1d543SIngo WeinholdTerminalBuffer::Encoding() const
8952b1d543SIngo Weinhold{
90cbe6d01cSIngo Weinhold	return fEncoding;
91cbe6d01cSIngo Weinhold}
92cbe6d01cSIngo Weinhold
93cbe6d01cSIngo Weinhold
948840b3dbSSimon Southvoid
958840b3dbSSimon SouthTerminalBuffer::EnableInterpretMetaKey(bool enable)
968840b3dbSSimon South{
978840b3dbSSimon South	if (fListenerValid) {
988840b3dbSSimon South		BMessage message(MSG_ENABLE_META_KEY);
998840b3dbSSimon South		message.AddBool("enableInterpretMetaKey", enable);
1008840b3dbSSimon South		fListener.SendMessage(&message);
1018840b3dbSSimon South	}
1028840b3dbSSimon South}
1038840b3dbSSimon South
1048840b3dbSSimon South
1058840b3dbSSimon Southvoid
1068840b3dbSSimon SouthTerminalBuffer::EnableMetaKeySendsEscape(bool enable)
1078840b3dbSSimon South{
1088840b3dbSSimon South	if (fListenerValid) {
1098840b3dbSSimon South		BMessage message(MSG_ENABLE_META_KEY);
1108840b3dbSSimon South		message.AddBool("enableMetaKeySendsEscape", enable);
1118840b3dbSSimon South		fListener.SendMessage(&message);
1128840b3dbSSimon South	}
1138840b3dbSSimon South}
1148840b3dbSSimon South
1158840b3dbSSimon South
11611efbf01SAxel Dörflervoid
11711efbf01SAxel DörflerTerminalBuffer::ReportX10MouseEvent(bool reportX10MouseEvent)
11811efbf01SAxel Dörfler{
11911efbf01SAxel Dörfler	if (fListenerValid) {
12011efbf01SAxel Dörfler		BMessage message(MSG_REPORT_MOUSE_EVENT);
12111efbf01SAxel Dörfler		message.AddBool("reportX10MouseEvent", reportX10MouseEvent);
12211efbf01SAxel Dörfler		fListener.SendMessage(&message);
12311efbf01SAxel Dörfler	}
12411efbf01SAxel Dörfler}
12511efbf01SAxel Dörfler
12611efbf01SAxel Dörfler
12711efbf01SAxel Dörflervoid
12811efbf01SAxel DörflerTerminalBuffer::ReportNormalMouseEvent(bool reportNormalMouseEvent)
12911efbf01SAxel Dörfler{
13011efbf01SAxel Dörfler	if (fListenerValid) {
13111efbf01SAxel Dörfler		BMessage message(MSG_REPORT_MOUSE_EVENT);
13211efbf01SAxel Dörfler		message.AddBool("reportNormalMouseEvent", reportNormalMouseEvent);
13311efbf01SAxel Dörfler		fListener.SendMessage(&message);
13411efbf01SAxel Dörfler	}
13511efbf01SAxel Dörfler}
13611efbf01SAxel Dörfler
13711efbf01SAxel Dörfler
13811efbf01SAxel Dörflervoid
13911efbf01SAxel DörflerTerminalBuffer::ReportButtonMouseEvent(bool report)
14011efbf01SAxel Dörfler{
14111efbf01SAxel Dörfler	if (fListenerValid) {
14211efbf01SAxel Dörfler		BMessage message(MSG_REPORT_MOUSE_EVENT);
14311efbf01SAxel Dörfler		message.AddBool("reportButtonMouseEvent", report);
14411efbf01SAxel Dörfler		fListener.SendMessage(&message);
14511efbf01SAxel Dörfler	}
14611efbf01SAxel Dörfler}
14711efbf01SAxel Dörfler
14811efbf01SAxel Dörfler
14921543141SAxel Dörflervoid
15021543141SAxel DörflerTerminalBuffer::ReportAnyMouseEvent(bool reportAnyMouseEvent)
15121543141SAxel Dörfler{
15221543141SAxel Dörfler	if (fListenerValid) {
15311efbf01SAxel Dörfler		BMessage message(MSG_REPORT_MOUSE_EVENT);
15421543141SAxel Dörfler		message.AddBool("reportAnyMouseEvent", reportAnyMouseEvent);
15521543141SAxel Dörfler		fListener.SendMessage(&message);
15611efbf01SAxel Dörfler	}
15721543141SAxel Dörfler}
15821543141SAxel Dörfler
15921543141SAxel Dörfler
160e3c74f40SLukasz Towarekvoid
161e3c74f40SLukasz TowarekTerminalBuffer::EnableExtendedMouseCoordinates(bool enable)
162e3c74f40SLukasz Towarek{
163e3c74f40SLukasz Towarek	if (fListenerValid) {
164e3c74f40SLukasz Towarek		BMessage message(MSG_REPORT_MOUSE_EVENT);
165e3c74f40SLukasz Towarek		message.AddBool("enableExtendedMouseCoordinates", enable);
166e3c74f40SLukasz Towarek		fListener.SendMessage(&message);
167e3c74f40SLukasz Towarek	}
168e3c74f40SLukasz Towarek}
169e3c74f40SLukasz Towarek
170e3c74f40SLukasz Towarek
171cbe6d01cSIngo Weinholdvoid
172cbe6d01cSIngo WeinholdTerminalBuffer::SetEncoding(int encoding)
173cbe6d01cSIngo Weinhold{
174cbe6d01cSIngo Weinhold	fEncoding = encoding;
17552b1d543SIngo Weinhold}
17652b1d543SIngo Weinhold
17752b1d543SIngo Weinhold
17852b1d543SIngo Weinholdvoid
17952b1d543SIngo WeinholdTerminalBuffer::SetTitle(const char* title)
18052b1d543SIngo Weinhold{
181ecd79a2cSIngo Weinhold	if (fListenerValid) {
18202f3baa0SSiarzhuk Zharski		BMessage message(MSG_SET_TERMINAL_TITLE);
183ecd79a2cSIngo Weinhold		message.AddString("title", title);
184ecd79a2cSIngo Weinhold		fListener.SendMessage(&message);
185ecd79a2cSIngo Weinhold	}
18652b1d543SIngo Weinhold}
18752b1d543SIngo Weinhold
18852b1d543SIngo Weinhold
18968ea9ce5SSiarzhuk Zharskivoid
19068ea9ce5SSiarzhuk ZharskiTerminalBuffer::SetColors(uint8* indexes, rgb_color* colors,
19168ea9ce5SSiarzhuk Zharski		int32 count, bool dynamic)
19268ea9ce5SSiarzhuk Zharski{
19368ea9ce5SSiarzhuk Zharski	if (fListenerValid) {
19468ea9ce5SSiarzhuk Zharski		BMessage message(MSG_SET_TERMINAL_COLORS);
19568ea9ce5SSiarzhuk Zharski		message.AddInt32("count", count);
19668ea9ce5SSiarzhuk Zharski		message.AddBool("dynamic", dynamic);
19768ea9ce5SSiarzhuk Zharski		message.AddData("index", B_UINT8_TYPE,
19868ea9ce5SSiarzhuk Zharski					indexes, sizeof(uint8), true, count);
19968ea9ce5SSiarzhuk Zharski		message.AddData("color", B_RGB_COLOR_TYPE,
20068ea9ce5SSiarzhuk Zharski					colors, sizeof(rgb_color), true, count);
20168ea9ce5SSiarzhuk Zharski
20268ea9ce5SSiarzhuk Zharski		for (int i = 1; i < count; i++) {
20368ea9ce5SSiarzhuk Zharski			message.AddData("index", B_UINT8_TYPE, &indexes[i], sizeof(uint8));
20468ea9ce5SSiarzhuk Zharski			message.AddData("color", B_RGB_COLOR_TYPE, &colors[i],
20568ea9ce5SSiarzhuk Zharski					sizeof(rgb_color));
20668ea9ce5SSiarzhuk Zharski		}
20768ea9ce5SSiarzhuk Zharski
20868ea9ce5SSiarzhuk Zharski		fListener.SendMessage(&message);
20968ea9ce5SSiarzhuk Zharski	}
21068ea9ce5SSiarzhuk Zharski}
21168ea9ce5SSiarzhuk Zharski
21268ea9ce5SSiarzhuk Zharski
21368ea9ce5SSiarzhuk Zharskivoid
21468ea9ce5SSiarzhuk ZharskiTerminalBuffer::ResetColors(uint8* indexes, int32 count, bool dynamic)
21568ea9ce5SSiarzhuk Zharski{
21668ea9ce5SSiarzhuk Zharski	if (fListenerValid) {
21768ea9ce5SSiarzhuk Zharski		BMessage message(MSG_RESET_TERMINAL_COLORS);
21868ea9ce5SSiarzhuk Zharski		message.AddInt32("count", count);
21968ea9ce5SSiarzhuk Zharski		message.AddBool("dynamic", dynamic);
22068ea9ce5SSiarzhuk Zharski		message.AddData("index", B_UINT8_TYPE,
22168ea9ce5SSiarzhuk Zharski					indexes, sizeof(uint8), true, count);
22268ea9ce5SSiarzhuk Zharski
22368ea9ce5SSiarzhuk Zharski		for (int i = 1; i < count; i++)
22468ea9ce5SSiarzhuk Zharski			message.AddData("index", B_UINT8_TYPE, &indexes[i], sizeof(uint8));
22568ea9ce5SSiarzhuk Zharski
22668ea9ce5SSiarzhuk Zharski		fListener.SendMessage(&message);
22768ea9ce5SSiarzhuk Zharski	}
22868ea9ce5SSiarzhuk Zharski}
22968ea9ce5SSiarzhuk Zharski
23068ea9ce5SSiarzhuk Zharski
2316d30b376SSiarzhuk Zharskivoid
2326d30b376SSiarzhuk ZharskiTerminalBuffer::SetCursorStyle(int32 style, bool blinking)
2336d30b376SSiarzhuk Zharski{
2346d30b376SSiarzhuk Zharski	if (fListenerValid) {
2356d30b376SSiarzhuk Zharski		BMessage message(MSG_SET_CURSOR_STYLE);
2366d30b376SSiarzhuk Zharski		message.AddInt32("style", style);
2376d30b376SSiarzhuk Zharski		message.AddBool("blinking", blinking);
2386d30b376SSiarzhuk Zharski		fListener.SendMessage(&message);
2396d30b376SSiarzhuk Zharski	}
2406d30b376SSiarzhuk Zharski}
2416d30b376SSiarzhuk Zharski
2426d30b376SSiarzhuk Zharski
2436d30b376SSiarzhuk Zharskivoid
2446d30b376SSiarzhuk ZharskiTerminalBuffer::SetCursorBlinking(bool blinking)
2456d30b376SSiarzhuk Zharski{
2466d30b376SSiarzhuk Zharski	if (fListenerValid) {
2476d30b376SSiarzhuk Zharski		BMessage message(MSG_SET_CURSOR_STYLE);
2486d30b376SSiarzhuk Zharski		message.AddBool("blinking", blinking);
2496d30b376SSiarzhuk Zharski		fListener.SendMessage(&message);
2506d30b376SSiarzhuk Zharski	}
2516d30b376SSiarzhuk Zharski}
2526d30b376SSiarzhuk Zharski
2536d30b376SSiarzhuk Zharski
2546d30b376SSiarzhuk Zharskivoid
2556d30b376SSiarzhuk ZharskiTerminalBuffer::SetCursorHidden(bool hidden)
2566d30b376SSiarzhuk Zharski{
2576d30b376SSiarzhuk Zharski	if (fListenerValid) {
2586d30b376SSiarzhuk Zharski		BMessage message(MSG_SET_CURSOR_STYLE);
2596d30b376SSiarzhuk Zharski		message.AddBool("hidden", hidden);
2606d30b376SSiarzhuk Zharski		fListener.SendMessage(&message);
2616d30b376SSiarzhuk Zharski	}
2626d30b376SSiarzhuk Zharski}
2636d30b376SSiarzhuk Zharski
2646d30b376SSiarzhuk Zharski
265fe256869SSiarzhuk Zharskivoid
266fe256869SSiarzhuk ZharskiTerminalBuffer::SetPaletteColor(uint8 index, rgb_color color)
267fe256869SSiarzhuk Zharski{
26885477b78SMurai Takashi	fColorsPalette[index] = color;
269fe256869SSiarzhuk Zharski}
270fe256869SSiarzhuk Zharski
271fe256869SSiarzhuk Zharski
272fe256869SSiarzhuk Zharskirgb_color
273fe256869SSiarzhuk ZharskiTerminalBuffer::PaletteColor(uint8 index)
274fe256869SSiarzhuk Zharski{
27585477b78SMurai Takashi	return fColorsPalette[index];
276fe256869SSiarzhuk Zharski}
277fe256869SSiarzhuk Zharski
278fe256869SSiarzhuk Zharski
279fe256869SSiarzhuk Zharskiint
280fe256869SSiarzhuk ZharskiTerminalBuffer::GuessPaletteColor(int red, int green, int blue)
281fe256869SSiarzhuk Zharski{
282fe256869SSiarzhuk Zharski	int distance = 255 * 100;
283fe256869SSiarzhuk Zharski	int index = -1;
2845b41331fSSiarzhuk Zharski	for (uint32 i = 0; i < kTermColorCount && distance > 0; i++) {
285fe256869SSiarzhuk Zharski		rgb_color color = fColorsPalette[i];
286fe256869SSiarzhuk Zharski		int r = 30 * abs(color.red - red);
287fe256869SSiarzhuk Zharski		int g = 59 * abs(color.green - green);
288fe256869SSiarzhuk Zharski		int b = 11 * abs(color.blue - blue);
289fe256869SSiarzhuk Zharski		int d = r + g + b;
290fe256869SSiarzhuk Zharski		if (distance > d) {
291fe256869SSiarzhuk Zharski			index = i;
292fe256869SSiarzhuk Zharski			distance = d;
293fe256869SSiarzhuk Zharski		}
294fe256869SSiarzhuk Zharski	}
295fe256869SSiarzhuk Zharski
2965b41331fSSiarzhuk Zharski	return min_c(index, int(kTermColorCount - 1));
297fe256869SSiarzhuk Zharski}
298fe256869SSiarzhuk Zharski
299fe256869SSiarzhuk Zharski
30052b1d543SIngo Weinholdvoid
30152b1d543SIngo WeinholdTerminalBuffer::NotifyQuit(int32 reason)
30252b1d543SIngo Weinhold{
303ecd79a2cSIngo Weinhold	if (fListenerValid) {
304ecd79a2cSIngo Weinhold		BMessage message(MSG_QUIT_TERMNAL);
305ecd79a2cSIngo Weinhold		message.AddInt32("reason", reason);
306ecd79a2cSIngo Weinhold		fListener.SendMessage(&message);
307ecd79a2cSIngo Weinhold	}
30852b1d543SIngo Weinhold}
30952b1d543SIngo Weinhold
31052b1d543SIngo Weinhold
31152b1d543SIngo Weinholdvoid
31223450280SIngo WeinholdTerminalBuffer::NotifyListener()
31352b1d543SIngo Weinhold{
314ecd79a2cSIngo Weinhold	if (fListenerValid)
315ecd79a2cSIngo Weinhold		fListener.SendMessage(MSG_TERMINAL_BUFFER_CHANGED);
3164386ce02SIngo Weinhold}
317d04aae8bSIngo Weinhold
318d04aae8bSIngo Weinhold
319d04aae8bSIngo Weinholdstatus_t
320d04aae8bSIngo WeinholdTerminalBuffer::ResizeTo(int32 width, int32 height)
321d04aae8bSIngo Weinhold{
322d04aae8bSIngo Weinhold	int32 historyCapacity = 0;
323d04aae8bSIngo Weinhold	if (!fAlternateScreenActive)
324d04aae8bSIngo Weinhold		historyCapacity = HistoryCapacity();
325d04aae8bSIngo Weinhold	else if (fAlternateHistory != NULL)
326d04aae8bSIngo Weinhold		historyCapacity = fAlternateHistory->Capacity();
327d04aae8bSIngo Weinhold
328d04aae8bSIngo Weinhold	return ResizeTo(width, height, historyCapacity);
329d04aae8bSIngo Weinhold}
330d04aae8bSIngo Weinhold
331d04aae8bSIngo Weinhold
332d04aae8bSIngo Weinholdstatus_t
333d04aae8bSIngo WeinholdTerminalBuffer::ResizeTo(int32 width, int32 height, int32 historyCapacity)
334d04aae8bSIngo Weinhold{
335d04aae8bSIngo Weinhold	// switch to the normal screen buffer first
336d04aae8bSIngo Weinhold	bool alternateScreenActive = fAlternateScreenActive;
337d04aae8bSIngo Weinhold	if (alternateScreenActive)
338d04aae8bSIngo Weinhold		_SwitchScreenBuffer();
339d04aae8bSIngo Weinhold
340d04aae8bSIngo Weinhold	int32 oldWidth = fWidth;
341d04aae8bSIngo Weinhold	int32 oldHeight = fHeight;
342d04aae8bSIngo Weinhold
343d04aae8bSIngo Weinhold	// Resize the normal screen buffer/history.
344d04aae8bSIngo Weinhold	status_t error = BasicTerminalBuffer::ResizeTo(width, height,
345d04aae8bSIngo Weinhold		historyCapacity);
346d04aae8bSIngo Weinhold	if (error != B_OK) {
347d04aae8bSIngo Weinhold		if (alternateScreenActive)
348d04aae8bSIngo Weinhold			_SwitchScreenBuffer();
349d04aae8bSIngo Weinhold		return error;
350d04aae8bSIngo Weinhold	}
351d04aae8bSIngo Weinhold
352d04aae8bSIngo Weinhold	// Switch to the alternate screen buffer and resize it.
353d04aae8bSIngo Weinhold	if (fAlternateScreen != NULL) {
3547f6f9ddbSIngo Weinhold		TermPos cursor = fCursor;
3557f6f9ddbSIngo Weinhold		fCursor.SetTo(0, 0);
356d04aae8bSIngo Weinhold		fWidth = oldWidth;
357d04aae8bSIngo Weinhold		fHeight = oldHeight;
3587f6f9ddbSIngo Weinhold
3597f6f9ddbSIngo Weinhold		_SwitchScreenBuffer();
360d04aae8bSIngo Weinhold
361d04aae8bSIngo Weinhold		error = BasicTerminalBuffer::ResizeTo(width, height, 0);
3627f6f9ddbSIngo Weinhold
3637f6f9ddbSIngo Weinhold		fWidth = width;
3647f6f9ddbSIngo Weinhold		fHeight = height;
3657f6f9ddbSIngo Weinhold		fCursor = cursor;
3667f6f9ddbSIngo Weinhold
3677f6f9ddbSIngo Weinhold		// Switch back.
3687f6f9ddbSIngo Weinhold		if (!alternateScreenActive)
3697f6f9ddbSIngo Weinhold			_SwitchScreenBuffer();
3707f6f9ddbSIngo Weinhold
371d04aae8bSIngo Weinhold		if (error != B_OK) {
372d04aae8bSIngo Weinhold			// This sucks -- we can't do anything about it. Delete the
373d04aae8bSIngo Weinhold			// alternate screen buffer.
374d04aae8bSIngo Weinhold			_FreeLines(fAlternateScreen, oldHeight);
375d04aae8bSIngo Weinhold			fAlternateScreen = NULL;
376d04aae8bSIngo Weinhold		}
377d04aae8bSIngo Weinhold	}
378d04aae8bSIngo Weinhold
379d04aae8bSIngo Weinhold	return error;
380d04aae8bSIngo Weinhold}
381d04aae8bSIngo Weinhold
382d04aae8bSIngo Weinhold
383d04aae8bSIngo Weinholdvoid
3841291c38cSIngo WeinholdTerminalBuffer::UseAlternateScreenBuffer(bool clear)
385d04aae8bSIngo Weinhold{
386d04aae8bSIngo Weinhold	if (fAlternateScreenActive || fAlternateScreen == NULL)
387d04aae8bSIngo Weinhold		return;
388d04aae8bSIngo Weinhold
389d04aae8bSIngo Weinhold	_SwitchScreenBuffer();
3901291c38cSIngo Weinhold
3911291c38cSIngo Weinhold	if (clear)
3921291c38cSIngo Weinhold		Clear(false);
3931291c38cSIngo Weinhold
394d04aae8bSIngo Weinhold	_InvalidateAll();
395d04aae8bSIngo Weinhold}
396d04aae8bSIngo Weinhold
397d04aae8bSIngo Weinhold
398d04aae8bSIngo Weinholdvoid
399d04aae8bSIngo WeinholdTerminalBuffer::UseNormalScreenBuffer()
400d04aae8bSIngo Weinhold{
401d04aae8bSIngo Weinhold	if (!fAlternateScreenActive)
402d04aae8bSIngo Weinhold		return;
403d04aae8bSIngo Weinhold
404d04aae8bSIngo Weinhold	_SwitchScreenBuffer();
405d04aae8bSIngo Weinhold	_InvalidateAll();
406d04aae8bSIngo Weinhold}
407d04aae8bSIngo Weinhold
408d04aae8bSIngo Weinhold
409d04aae8bSIngo Weinholdvoid
410d04aae8bSIngo WeinholdTerminalBuffer::_SwitchScreenBuffer()
411d04aae8bSIngo Weinhold{
412d04aae8bSIngo Weinhold	std::swap(fScreen, fAlternateScreen);
413d04aae8bSIngo Weinhold	std::swap(fHistory, fAlternateHistory);
414d04aae8bSIngo Weinhold	std::swap(fScreenOffset, fAlternateScreenOffset);
415