* Some preparations for DEC private mode settings support.
* Implemented alternate screen buffer support. Not used by any program yet, since we still use the beterm termcap entry. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@26003 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
9c95cbf21f
commit
d04aae8b80
@ -120,6 +120,7 @@ BasicTerminalBuffer::Init(int32 width, int32 height, int32 historySize)
|
||||
fScreenOffset = 0;
|
||||
|
||||
fOverwriteMode = true;
|
||||
fAlternateScreenActive = false;
|
||||
|
||||
fScreen = _AllocateLines(width, height);
|
||||
if (fScreen == NULL)
|
||||
@ -162,12 +163,10 @@ BasicTerminalBuffer::ResizeTo(int32 width, int32 height, int32 historyCapacity)
|
||||
if (width == fWidth && height == fHeight)
|
||||
return SetHistoryCapacity(historyCapacity);
|
||||
|
||||
// TODO: When alternate screen support is implemented, do that only when
|
||||
// not using the alternate screen.
|
||||
if (true)
|
||||
return _ResizeRewrap(width, height, historyCapacity);
|
||||
if (fAlternateScreenActive)
|
||||
return _ResizeSimple(width, height, historyCapacity);
|
||||
|
||||
return _ResizeSimple(width, height, historyCapacity);
|
||||
return _ResizeRewrap(width, height, historyCapacity);
|
||||
}
|
||||
|
||||
|
||||
@ -179,11 +178,13 @@ BasicTerminalBuffer::SetHistoryCapacity(int32 historyCapacity)
|
||||
|
||||
|
||||
void
|
||||
BasicTerminalBuffer::Clear()
|
||||
BasicTerminalBuffer::Clear(bool resetCursor)
|
||||
{
|
||||
fScreenOffset = 0;
|
||||
_ClearLines(0, fHeight - 1);
|
||||
fCursor.SetTo(0, 0);
|
||||
|
||||
if (resetCursor)
|
||||
fCursor.SetTo(0, 0);
|
||||
|
||||
if (fHistory != NULL)
|
||||
fHistory->Clear();
|
||||
@ -585,7 +586,8 @@ BasicTerminalBuffer::InsertLF()
|
||||
if (fCursor.y == fScrollBottom) {
|
||||
_Scroll(fScrollTop, fScrollBottom, 1);
|
||||
} else {
|
||||
fCursor.y++;
|
||||
if (fCursor.y < fHeight - 1)
|
||||
fCursor.y++;
|
||||
_CursorChanged();
|
||||
}
|
||||
}
|
||||
@ -731,7 +733,7 @@ BasicTerminalBuffer::SetCursor(int32 x, int32 y)
|
||||
{
|
||||
//debug_printf("BasicTerminalBuffer::SetCursor(%d, %d)\n", x, y);
|
||||
x = restrict_value(x, 0, fWidth - 1);
|
||||
y = restrict_value(y, fScrollTop, fScrollBottom);
|
||||
y = restrict_value(y, 0, fHeight - 1);
|
||||
if (x != fCursor.x || y != fCursor.y) {
|
||||
fCursor.x = x;
|
||||
fCursor.y = y;
|
||||
@ -775,6 +777,18 @@ BasicTerminalBuffer::NotifyListener()
|
||||
// #pragma mark - private methods
|
||||
|
||||
|
||||
void
|
||||
BasicTerminalBuffer::_InvalidateAll()
|
||||
{
|
||||
fDirtyInfo.invalidateAll = true;
|
||||
|
||||
if (!fDirtyInfo.messageSent) {
|
||||
NotifyListener();
|
||||
fDirtyInfo.messageSent = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* static */ TerminalLine**
|
||||
BasicTerminalBuffer::_AllocateLines(int32 width, int32 count)
|
||||
{
|
||||
|
@ -21,6 +21,7 @@ struct TerminalBufferDirtyInfo {
|
||||
int32 linesScrolled; // number of lines added to the history
|
||||
int32 dirtyTop; // dirty line range
|
||||
int32 dirtyBottom; //
|
||||
bool invalidateAll;
|
||||
bool messageSent; // listener has been notified
|
||||
|
||||
bool IsDirtyRegionValid() const
|
||||
@ -41,6 +42,7 @@ struct TerminalBufferDirtyInfo {
|
||||
linesScrolled = 0;
|
||||
dirtyTop = INT_MAX;
|
||||
dirtyBottom = INT_MIN;
|
||||
invalidateAll = false;
|
||||
messageSent = false;
|
||||
}
|
||||
};
|
||||
@ -61,11 +63,11 @@ public:
|
||||
|
||||
TerminalBufferDirtyInfo& DirtyInfo() { return fDirtyInfo; }
|
||||
|
||||
status_t ResizeTo(int32 width, int32 height);
|
||||
status_t ResizeTo(int32 width, int32 height,
|
||||
virtual status_t ResizeTo(int32 width, int32 height);
|
||||
virtual status_t ResizeTo(int32 width, int32 height,
|
||||
int32 historyCapacity);
|
||||
status_t SetHistoryCapacity(int32 historyCapacity);
|
||||
void Clear();
|
||||
void Clear(bool resetCursor);
|
||||
|
||||
void SynchronizeWith(
|
||||
const BasicTerminalBuffer* other,
|
||||
@ -139,6 +141,7 @@ protected:
|
||||
|
||||
inline void _Invalidate(int32 top, int32 bottom);
|
||||
inline void _CursorChanged();
|
||||
void _InvalidateAll();
|
||||
|
||||
static TerminalLine** _AllocateLines(int32 width, int32 count);
|
||||
static void _FreeLines(TerminalLine** lines, int32 count);
|
||||
@ -182,6 +185,7 @@ protected:
|
||||
TermPos fSavedCursor;
|
||||
|
||||
bool fOverwriteMode; // false for insert
|
||||
bool fAlternateScreenActive;
|
||||
|
||||
int fEncoding;
|
||||
|
||||
|
@ -790,13 +790,15 @@ TermParse::EscParse()
|
||||
|
||||
case CASE_DECSET:
|
||||
/* DECSET */
|
||||
// dpmodes(term, bitset);
|
||||
for (int i = 0; i < nparam; i++)
|
||||
_DecPrivateModeSet(param[i]);
|
||||
parsestate = groundtable;
|
||||
break;
|
||||
|
||||
case CASE_DECRST:
|
||||
/* DECRST */
|
||||
// dpmodes(term, bitclr);
|
||||
for (int i = 0; i < nparam; i++)
|
||||
_DecPrivateModeReset(param[i]);
|
||||
parsestate = groundtable;
|
||||
break;
|
||||
|
||||
@ -1070,3 +1072,80 @@ TermParse::_DeviceStatusReport(int n)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TermParse::_DecPrivateModeSet(int value)
|
||||
{
|
||||
switch (value) {
|
||||
case 1:
|
||||
// Application Cursor Keys (whatever that means).
|
||||
// Not supported yet.
|
||||
break;
|
||||
case 5:
|
||||
// Reverse Video (inverses colors for the complete screen
|
||||
// -- when followed by normal video, that's shortly flashes the
|
||||
// screen).
|
||||
// Not supported yet.
|
||||
break;
|
||||
case 12:
|
||||
// Start Blinking Cursor.
|
||||
// Not supported yet.
|
||||
break;
|
||||
case 25:
|
||||
// Show Cursor
|
||||
// Not supported yet.
|
||||
break;
|
||||
case 1034:
|
||||
// Interpret "meta" key, sets eighth bit.
|
||||
// Not supported yet.
|
||||
break;
|
||||
case 1049:
|
||||
// Save cursor as in DECSC and use Alternate Screen Buffer, clearing
|
||||
// it first.
|
||||
fBuffer->SaveCursor();
|
||||
fBuffer->UseAlternateScreenBuffer();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TermParse::_DecPrivateModeReset(int value)
|
||||
{
|
||||
switch (value) {
|
||||
case 1:
|
||||
// Normal Cursor Keys (whatever that means).
|
||||
// Not supported yet.
|
||||
break;
|
||||
case 3:
|
||||
// 80 Column Mode.
|
||||
// Not supported yet.
|
||||
break;
|
||||
case 4:
|
||||
// Jump (Fast) Scroll.
|
||||
// Not supported yet.
|
||||
break;
|
||||
case 5:
|
||||
// Normal Video (Leaves Reverse Video, cf. there).
|
||||
// Not supported yet.
|
||||
break;
|
||||
case 12:
|
||||
// Stop Blinking Cursor.
|
||||
// Not supported yet.
|
||||
break;
|
||||
case 25:
|
||||
// Hide Cursor
|
||||
// Not supported yet.
|
||||
break;
|
||||
case 1034:
|
||||
// Don’t interpret "meta" key.
|
||||
// Not supported yet.
|
||||
break;
|
||||
case 1049:
|
||||
// Use Normal Screen Buffer and restore cursor as in DECRC.
|
||||
fBuffer->RestoreCursor();
|
||||
fBuffer->UseNormalScreenBuffer();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -76,6 +76,8 @@ private:
|
||||
status_t _ReadParserBuffer();
|
||||
|
||||
void _DeviceStatusReport(int n);
|
||||
void _DecPrivateModeSet(int value);
|
||||
void _DecPrivateModeReset(int value);
|
||||
|
||||
int fFd;
|
||||
|
||||
|
@ -710,9 +710,9 @@ TermView::Clear()
|
||||
|
||||
{
|
||||
BAutolock _(fTextBuffer);
|
||||
fTextBuffer->Clear();
|
||||
fTextBuffer->Clear(true);
|
||||
}
|
||||
fVisibleTextBuffer->Clear();
|
||||
fVisibleTextBuffer->Clear(true);
|
||||
|
||||
//debug_printf("Invalidate()\n");
|
||||
Invalidate();
|
||||
@ -1563,10 +1563,6 @@ TermView::_SynchronizeWithTextBuffer(int32 visibleDirtyTop,
|
||||
{
|
||||
TerminalBufferDirtyInfo& info = fTextBuffer->DirtyInfo();
|
||||
int32 linesScrolled = info.linesScrolled;
|
||||
BRect bounds = Bounds();
|
||||
int32 firstVisible = _LineAt(0);
|
||||
int32 lastVisible = _LineAt(bounds.bottom);
|
||||
int32 historySize = fTextBuffer->HistorySize();
|
||||
|
||||
//debug_printf("TermView::_SynchronizeWithTextBuffer(): dirty: %ld - %ld, "
|
||||
//"scrolled: %ld, visible dirty: %ld - %ld\n", info.dirtyTop, info.dirtyBottom,
|
||||
@ -1630,6 +1626,22 @@ TermView::_SynchronizeWithTextBuffer(int32 visibleDirtyTop,
|
||||
fScrolledSinceLastSync = 0;
|
||||
}
|
||||
|
||||
// Simple case first -- complete invalidation.
|
||||
if (info.invalidateAll) {
|
||||
Invalidate();
|
||||
_UpdateScrollBarRange();
|
||||
int32 offset = _LineAt(0);
|
||||
fVisibleTextBuffer->SynchronizeWith(fTextBuffer, offset, offset,
|
||||
offset + fTextBuffer->Height() + 2);
|
||||
info.Reset();
|
||||
return;
|
||||
}
|
||||
|
||||
BRect bounds = Bounds();
|
||||
int32 firstVisible = _LineAt(0);
|
||||
int32 lastVisible = _LineAt(bounds.bottom);
|
||||
int32 historySize = fTextBuffer->HistorySize();
|
||||
|
||||
bool doScroll = false;
|
||||
if (linesScrolled > 0) {
|
||||
_UpdateScrollBarRange();
|
||||
|
@ -5,6 +5,8 @@
|
||||
|
||||
#include "TerminalBuffer.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include <Message.h>
|
||||
|
||||
#include "Coding.h"
|
||||
@ -18,6 +20,9 @@ TerminalBuffer::TerminalBuffer()
|
||||
:
|
||||
BLocker("terminal buffer"),
|
||||
fEncoding(M_UTF8),
|
||||
fAlternateScreen(NULL),
|
||||
fAlternateHistory(NULL),
|
||||
fAlternateScreenOffset(0),
|
||||
fListenerValid(false)
|
||||
{
|
||||
}
|
||||
@ -25,6 +30,8 @@ TerminalBuffer::TerminalBuffer()
|
||||
|
||||
TerminalBuffer::~TerminalBuffer()
|
||||
{
|
||||
delete fAlternateScreen;
|
||||
delete fAlternateHistory;
|
||||
}
|
||||
|
||||
|
||||
@ -34,6 +41,10 @@ TerminalBuffer::Init(int32 width, int32 height, int32 historySize)
|
||||
if (Sem() < 0)
|
||||
return Sem();
|
||||
|
||||
fAlternateScreen = _AllocateLines(width, height);
|
||||
if (fAlternateScreen == NULL)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
return BasicTerminalBuffer::Init(width, height, historySize);
|
||||
}
|
||||
|
||||
@ -95,3 +106,100 @@ TerminalBuffer::NotifyListener()
|
||||
if (fListenerValid)
|
||||
fListener.SendMessage(MSG_TERMINAL_BUFFER_CHANGED);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
TerminalBuffer::ResizeTo(int32 width, int32 height)
|
||||
{
|
||||
int32 historyCapacity = 0;
|
||||
if (!fAlternateScreenActive)
|
||||
historyCapacity = HistoryCapacity();
|
||||
else if (fAlternateHistory != NULL)
|
||||
historyCapacity = fAlternateHistory->Capacity();
|
||||
|
||||
return ResizeTo(width, height, historyCapacity);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
TerminalBuffer::ResizeTo(int32 width, int32 height, int32 historyCapacity)
|
||||
{
|
||||
// switch to the normal screen buffer first
|
||||
bool alternateScreenActive = fAlternateScreenActive;
|
||||
if (alternateScreenActive)
|
||||
_SwitchScreenBuffer();
|
||||
|
||||
int32 oldWidth = fWidth;
|
||||
int32 oldHeight = fHeight;
|
||||
|
||||
// Resize the normal screen buffer/history.
|
||||
status_t error = BasicTerminalBuffer::ResizeTo(width, height,
|
||||
historyCapacity);
|
||||
if (error != B_OK) {
|
||||
if (alternateScreenActive)
|
||||
_SwitchScreenBuffer();
|
||||
return error;
|
||||
}
|
||||
|
||||
TermPos cursor = fCursor;
|
||||
|
||||
// Switch to the alternate screen buffer and resize it.
|
||||
if (fAlternateScreen != NULL) {
|
||||
_SwitchScreenBuffer();
|
||||
|
||||
fWidth = oldWidth;
|
||||
fHeight = oldHeight;
|
||||
fCursor.SetTo(0, 0);
|
||||
|
||||
error = BasicTerminalBuffer::ResizeTo(width, height, 0);
|
||||
if (error != B_OK) {
|
||||
// This sucks -- we can't do anything about it. Delete the
|
||||
// alternate screen buffer.
|
||||
_FreeLines(fAlternateScreen, oldHeight);
|
||||
fAlternateScreen = NULL;
|
||||
}
|
||||
|
||||
// Switch back.
|
||||
if (!alternateScreenActive)
|
||||
_SwitchScreenBuffer();
|
||||
|
||||
fWidth = width;
|
||||
fHeight = height;
|
||||
fCursor = cursor;
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TerminalBuffer::UseAlternateScreenBuffer()
|
||||
{
|
||||
if (fAlternateScreenActive || fAlternateScreen == NULL)
|
||||
return;
|
||||
|
||||
_SwitchScreenBuffer();
|
||||
Clear(false);
|
||||
_InvalidateAll();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TerminalBuffer::UseNormalScreenBuffer()
|
||||
{
|
||||
if (!fAlternateScreenActive)
|
||||
return;
|
||||
|
||||
_SwitchScreenBuffer();
|
||||
_InvalidateAll();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TerminalBuffer::_SwitchScreenBuffer()
|
||||
{
|
||||
std::swap(fScreen, fAlternateScreen);
|
||||
std::swap(fHistory, fAlternateHistory);
|
||||
std::swap(fScreenOffset, fAlternateScreenOffset);
|
||||
fAlternateScreenActive = !fAlternateScreenActive;
|
||||
}
|
||||
|
@ -28,12 +28,26 @@ public:
|
||||
void SetTitle(const char* title);
|
||||
void NotifyQuit(int32 reason);
|
||||
|
||||
virtual status_t ResizeTo(int32 width, int32 height);
|
||||
virtual status_t ResizeTo(int32 width, int32 height,
|
||||
int32 historyCapacity);
|
||||
|
||||
void UseAlternateScreenBuffer();
|
||||
void UseNormalScreenBuffer();
|
||||
|
||||
protected:
|
||||
virtual void NotifyListener();
|
||||
|
||||
private:
|
||||
void _SwitchScreenBuffer();
|
||||
|
||||
private:
|
||||
int fEncoding;
|
||||
|
||||
TerminalLine** fAlternateScreen;
|
||||
HistoryBuffer* fAlternateHistory;
|
||||
int32 fAlternateScreenOffset;
|
||||
|
||||
// listener/dirty region management
|
||||
BMessenger fListener;
|
||||
bool fListenerValid;
|
||||
|
Loading…
Reference in New Issue
Block a user