Patch by Joshua R. Elsasser:

Implement origin mode.
    Save origin mode and text attributes when saving the cursor.
    Have RI respect the scroll region.
    When erasing the screen actually erase the screen, not just the scroll region.
    Implement all three variants of the EL (erase line) sequence.

    Thanks! Resolves ticket #4652.



git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@33319 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Rene Gollent
2009-09-27 15:54:02 +00:00
parent 8ea060d47f
commit ae29b1c3c2
4 changed files with 176 additions and 61 deletions
+71 -24
View File
@@ -122,6 +122,7 @@ BasicTerminalBuffer::Init(int32 width, int32 height, int32 historySize)
fOverwriteMode = true; fOverwriteMode = true;
fAlternateScreenActive = false; fAlternateScreenActive = false;
fOriginMode = fSavedOriginMode = false;
fScreen = _AllocateLines(width, height); fScreen = _AllocateLines(width, height);
if (fScreen == NULL) if (fScreen == NULL)
@@ -604,6 +605,22 @@ BasicTerminalBuffer::InsertLF()
} }
void
BasicTerminalBuffer::InsertRI()
{
fSoftWrappedCursor = false;
// If we're at the beginning of the scroll region, scroll. Otherwise just
// reverse the cursor.
if (fCursor.y == fScrollTop) {
_Scroll(fScrollTop, fScrollBottom, -1);
} else {
if (fCursor.y > 0)
fCursor.y--;
_CursorChanged();
}
}
void void
BasicTerminalBuffer::InsertLines(int32 numLines) BasicTerminalBuffer::InsertLines(int32 numLines)
{ {
@@ -645,7 +662,7 @@ BasicTerminalBuffer::InsertSpace(int32 num)
void void
BasicTerminalBuffer::EraseChars(int32 numChars) BasicTerminalBuffer::EraseCharsFrom(int32 first, int32 numChars)
{ {
TerminalLine* line = _LineAt(fCursor.y); TerminalLine* line = _LineAt(fCursor.y);
if (fCursor.y >= line->length) if (fCursor.y >= line->length)
@@ -653,8 +670,7 @@ BasicTerminalBuffer::EraseChars(int32 numChars)
fSoftWrappedCursor = false; fSoftWrappedCursor = false;
int32 first = fCursor.x; int32 end = min_c(first + numChars, line->length);
int32 end = min_c(fCursor.x + numChars, line->length);
if (first > 0 && IS_WIDTH(line->cells[first - 1].attributes)) if (first > 0 && IS_WIDTH(line->cells[first - 1].attributes))
first--; first--;
if (end > 0 && IS_WIDTH(line->cells[end - 1].attributes)) if (end > 0 && IS_WIDTH(line->cells[end - 1].attributes))
@@ -713,7 +729,7 @@ void
BasicTerminalBuffer::EraseAll() BasicTerminalBuffer::EraseAll()
{ {
fSoftWrappedCursor = false; fSoftWrappedCursor = false;
_Scroll(fScrollTop, fScrollBottom, fHeight); _Scroll(0, fHeight - 1, fHeight);
} }
@@ -740,13 +756,13 @@ BasicTerminalBuffer::DeleteChars(int32 numChars)
void void
BasicTerminalBuffer::DeleteColumns() BasicTerminalBuffer::DeleteColumnsFrom(int32 first)
{ {
fSoftWrappedCursor = false; fSoftWrappedCursor = false;
TerminalLine* line = _LineAt(fCursor.y); TerminalLine* line = _LineAt(fCursor.y);
if (fCursor.x < line->length) { if (first < line->length) {
line->length = fCursor.x; line->length = first;
_Invalidate(fCursor.y, fCursor.y); _Invalidate(fCursor.y, fCursor.y);
} }
} }
@@ -762,21 +778,6 @@ BasicTerminalBuffer::DeleteLines(int32 numLines)
} }
void
BasicTerminalBuffer::SetCursor(int32 x, int32 y)
{
//debug_printf("BasicTerminalBuffer::SetCursor(%d, %d)\n", x, y);
fSoftWrappedCursor = false;
x = restrict_value(x, 0, fWidth - 1);
y = restrict_value(y, 0, fHeight - 1);
if (x != fCursor.x || y != fCursor.y) {
fCursor.x = x;
fCursor.y = y;
_CursorChanged();
}
}
void void
BasicTerminalBuffer::SaveCursor() BasicTerminalBuffer::SaveCursor()
{ {
@@ -787,7 +788,7 @@ BasicTerminalBuffer::SaveCursor()
void void
BasicTerminalBuffer::RestoreCursor() BasicTerminalBuffer::RestoreCursor()
{ {
SetCursor(fSavedCursor.x, fSavedCursor.y); _SetCursor(fSavedCursor.x, fSavedCursor.y, true);
} }
@@ -798,7 +799,29 @@ BasicTerminalBuffer::SetScrollRegion(int32 top, int32 bottom)
fScrollBottom = restrict_value(bottom, fScrollTop, fHeight - 1); fScrollBottom = restrict_value(bottom, fScrollTop, fHeight - 1);
// also sets the cursor position // also sets the cursor position
SetCursor(0, 0); _SetCursor(0, 0, false);
}
void
BasicTerminalBuffer::SetOriginMode(bool enabled)
{
fOriginMode = enabled;
_SetCursor(0, 0, false);
}
void
BasicTerminalBuffer::SaveOriginMode()
{
fSavedOriginMode = fOriginMode;
}
void
BasicTerminalBuffer::RestoreOriginMode()
{
fOriginMode = fSavedOriginMode;
} }
@@ -812,6 +835,28 @@ BasicTerminalBuffer::NotifyListener()
// #pragma mark - private methods // #pragma mark - private methods
void
BasicTerminalBuffer::_SetCursor(int32 x, int32 y, bool absolute)
{
//debug_printf("BasicTerminalBuffer::_SetCursor(%d, %d)\n", x, y);
fSoftWrappedCursor = false;
x = restrict_value(x, 0, fWidth - 1);
if (fOriginMode && !absolute) {
y += fScrollTop;
y = restrict_value(y, fScrollTop, fScrollBottom);
} else {
y = restrict_value(y, 0, fHeight - 1);
}
if (x != fCursor.x || y != fCursor.y) {
fCursor.x = x;
fCursor.y = y;
_CursorChanged();
}
}
void void
BasicTerminalBuffer::_InvalidateAll() BasicTerminalBuffer::_InvalidateAll()
{ {
@@ -984,6 +1029,7 @@ BasicTerminalBuffer::_ResizeSimple(int32 width, int32 height,
fScrollTop = 0; fScrollTop = 0;
fScrollBottom = fHeight - 1; fScrollBottom = fHeight - 1;
fOriginMode = fSavedOriginMode = false;
fScreenOffset = 0; fScreenOffset = 0;
@@ -1177,6 +1223,7 @@ BasicTerminalBuffer::_ResizeRewrap(int32 width, int32 height,
fScrollTop = 0; fScrollTop = 0;
fScrollBottom = fHeight - 1; fScrollBottom = fHeight - 1;
fOriginMode = fSavedOriginMode = false;
return B_OK; return B_OK;
} }
+30 -3
View File
@@ -106,21 +106,24 @@ public:
void InsertCR(); void InsertCR();
void InsertLF(); void InsertLF();
void InsertRI();
void SetInsertMode(int flag); void SetInsertMode(int flag);
void InsertSpace(int32 num); void InsertSpace(int32 num);
void InsertLines(int32 numLines); void InsertLines(int32 numLines);
// delete chars/lines // delete chars/lines
void EraseChars(int32 numChars); inline void EraseChars(int32 numChars);
void EraseCharsFrom(int32 first, int32 numChars);
void EraseAbove(); void EraseAbove();
void EraseBelow(); void EraseBelow();
void EraseAll(); void EraseAll();
void DeleteChars(int32 numChars); void DeleteChars(int32 numChars);
void DeleteColumns(); inline void DeleteColumns();
void DeleteColumnsFrom(int32 first);
void DeleteLines(int32 numLines); void DeleteLines(int32 numLines);
// get and set cursor position // get and set cursor position
void SetCursor(int32 x, int32 y); inline void SetCursor(int32 x, int32 y);
inline void SetCursorX(int32 x); inline void SetCursorX(int32 x);
inline void SetCursorY(int32 y); inline void SetCursorY(int32 y);
inline TermPos Cursor() const { return fCursor; } inline TermPos Cursor() const { return fCursor; }
@@ -136,6 +139,9 @@ public:
// scroll region // scroll region
inline void ScrollBy(int32 numLines); inline void ScrollBy(int32 numLines);
void SetScrollRegion(int32 top, int32 bottom); void SetScrollRegion(int32 top, int32 bottom);
void SetOriginMode(bool enabled);
void SaveOriginMode();
void RestoreOriginMode();
protected: protected:
virtual void NotifyListener(); virtual void NotifyListener();
@@ -147,6 +153,7 @@ protected:
inline void _Invalidate(int32 top, int32 bottom); inline void _Invalidate(int32 top, int32 bottom);
inline void _CursorChanged(); inline void _CursorChanged();
void _SetCursor(int32 x, int32 y, bool absolute);
void _InvalidateAll(); void _InvalidateAll();
static TerminalLine** _AllocateLines(int32 width, int32 count); static TerminalLine** _AllocateLines(int32 width, int32 count);
@@ -193,6 +200,8 @@ protected:
bool fOverwriteMode; // false for insert bool fOverwriteMode; // false for insert
bool fAlternateScreenActive; bool fAlternateScreenActive;
bool fOriginMode;
bool fSavedOriginMode;
int fEncoding; int fEncoding;
@@ -236,6 +245,24 @@ BasicTerminalBuffer::InsertChar(const char* c, int32 length, uint32 width, uint3
} }
void
BasicTerminalBuffer::EraseChars(int32 numChars)
{
EraseCharsFrom(fCursor.x, numChars);
}
void
BasicTerminalBuffer::DeleteColumns()
{
DeleteColumnsFrom(fCursor.x);
}
void
BasicTerminalBuffer::SetCursor(int32 x, int32 y)
{
_SetCursor(x, y, false);
}
void void
BasicTerminalBuffer::SetCursorX(int32 x) BasicTerminalBuffer::SetCursorX(int32 x)
{ {
+70 -34
View File
@@ -311,8 +311,6 @@ TermParse::EscParse()
int now_coding = -1; int now_coding = -1;
ushort attr = BACKCOLOR;
int param[NPARAM]; int param[NPARAM];
int nparam = 1; int nparam = 1;
@@ -325,6 +323,8 @@ TermParse::EscParse()
int width = 1; int width = 1;
BAutolock locker(fBuffer); BAutolock locker(fBuffer);
fAttr = fSavedAttr = BACKCOLOR;
while (!fQuitting) { while (!fQuitting) {
uchar c; uchar c;
if (_NextParseChar(c) < B_OK) if (_NextParseChar(c) < B_OK)
@@ -371,7 +371,7 @@ TermParse::EscParse()
//debug_printf("TermParse: char: '%c' (%d), parse state: %d\n", c, c, parsestate[c]); //debug_printf("TermParse: char: '%c' (%d), parse state: %d\n", c, c, parsestate[c]);
switch (parsestate[c]) { switch (parsestate[c]) {
case CASE_PRINT: case CASE_PRINT:
fBuffer->InsertChar((char)c, attr); fBuffer->InsertChar((char)c, fAttr);
break; break;
case CASE_PRINT_GR: case CASE_PRINT_GR:
@@ -422,7 +422,7 @@ TermParse::EscParse()
B_EUC_CONVERSION); B_EUC_CONVERSION);
} }
fBuffer->InsertChar(dstbuf, 4, width, attr); fBuffer->InsertChar(dstbuf, 4, width, fAttr);
break; break;
case CASE_PRINT_CS96: case CASE_PRINT_CS96:
@@ -431,7 +431,7 @@ TermParse::EscParse()
cbuf[1] = c | 0x80; cbuf[1] = c | 0x80;
cbuf[2] = 0; cbuf[2] = 0;
CodeConv::ConvertToInternal(cbuf, 2, dstbuf, B_EUC_CONVERSION); CodeConv::ConvertToInternal(cbuf, 2, dstbuf, B_EUC_CONVERSION);
fBuffer->InsertChar(dstbuf, 4, attr); fBuffer->InsertChar(dstbuf, 4, fAttr);
break; break;
case CASE_LF: case CASE_LF:
@@ -446,7 +446,7 @@ TermParse::EscParse()
cbuf[0] = c; cbuf[0] = c;
cbuf[1] = '\0'; cbuf[1] = '\0';
CodeConv::ConvertToInternal(cbuf, 1, dstbuf, now_coding); CodeConv::ConvertToInternal(cbuf, 1, dstbuf, now_coding);
fBuffer->InsertChar(dstbuf, 4, attr); fBuffer->InsertChar(dstbuf, 4, fAttr);
break; break;
case CASE_SJIS_INSTRING: case CASE_SJIS_INSTRING:
@@ -455,7 +455,7 @@ TermParse::EscParse()
cbuf[1] = c; cbuf[1] = c;
cbuf[2] = '\0'; cbuf[2] = '\0';
CodeConv::ConvertToInternal(cbuf, 2, dstbuf, now_coding); CodeConv::ConvertToInternal(cbuf, 2, dstbuf, now_coding);
fBuffer->InsertChar(dstbuf, 4, attr); fBuffer->InsertChar(dstbuf, 4, fAttr);
break; break;
case CASE_UTF8_2BYTE: case CASE_UTF8_2BYTE:
@@ -466,7 +466,7 @@ TermParse::EscParse()
cbuf[1] = c; cbuf[1] = c;
cbuf[2] = '\0'; cbuf[2] = '\0';
fBuffer->InsertChar(cbuf, 2, attr); fBuffer->InsertChar(cbuf, 2, fAttr);
break; break;
case CASE_UTF8_3BYTE: case CASE_UTF8_3BYTE:
@@ -481,7 +481,7 @@ TermParse::EscParse()
break; break;
cbuf[2] = c; cbuf[2] = c;
cbuf[3] = '\0'; cbuf[3] = '\0';
fBuffer->InsertChar(cbuf, 3, attr); fBuffer->InsertChar(cbuf, 3, fAttr);
break; break;
case CASE_MBCS: case CASE_MBCS:
@@ -645,9 +645,22 @@ TermParse::EscParse()
parsestate = groundtable; parsestate = groundtable;
break; break;
case CASE_EL: // delete line case CASE_EL: // ESC [ ...K delete line
/* EL */ /* EL */
fBuffer->DeleteColumns(); switch (param[0]) {
case DEFAULT:
case 0:
fBuffer->DeleteColumns();
break;
case 1:
fBuffer->EraseCharsFrom(0, fBuffer->Cursor().x + 1);
break;
case 2:
fBuffer->DeleteColumnsFrom(0);
break;
}
parsestate = groundtable; parsestate = groundtable;
break; break;
@@ -695,32 +708,32 @@ TermParse::EscParse()
switch (param[row]) { switch (param[row]) {
case DEFAULT: case DEFAULT:
case 0: /* Reset attribute */ case 0: /* Reset attribute */
attr = 0; fAttr = 0;
break; break;
case 1: case 1:
case 5: /* Bold */ case 5: /* Bold */
attr |= BOLD; fAttr |= BOLD;
break; break;
case 4: /* Underline */ case 4: /* Underline */
attr |= UNDERLINE; fAttr |= UNDERLINE;
break; break;
case 7: /* Inverse */ case 7: /* Inverse */
attr |= INVERSE; fAttr |= INVERSE;
break; break;
case 22: /* Not Bold */ case 22: /* Not Bold */
attr &= ~BOLD; fAttr &= ~BOLD;
break; break;
case 24: /* Not Underline */ case 24: /* Not Underline */
attr &= ~UNDERLINE; fAttr &= ~UNDERLINE;
break; break;
case 27: /* Not Inverse */ case 27: /* Not Inverse */
attr &= ~INVERSE; fAttr &= ~INVERSE;
break; break;
case 30: case 30:
@@ -731,13 +744,13 @@ TermParse::EscParse()
case 35: case 35:
case 36: case 36:
case 37: case 37:
attr &= ~FORECOLOR; fAttr &= ~FORECOLOR;
attr |= FORECOLORED(param[row] - 30); fAttr |= FORECOLORED(param[row] - 30);
attr |= FORESET; fAttr |= FORESET;
break; break;
case 39: case 39:
attr &= ~FORESET; fAttr &= ~FORESET;
break; break;
case 40: case 40:
@@ -748,13 +761,13 @@ TermParse::EscParse()
case 45: case 45:
case 46: case 46:
case 47: case 47:
attr &= ~BACKCOLOR; fAttr &= ~BACKCOLOR;
attr |= BACKCOLORED(param[row] - 40); fAttr |= BACKCOLORED(param[row] - 40);
attr |= BACKSET; fAttr |= BACKSET;
break; break;
case 49: case 49:
attr &= ~BACKSET; fAttr &= ~BACKSET;
break; break;
} }
} }
@@ -822,13 +835,13 @@ TermParse::EscParse()
case CASE_DECSC: case CASE_DECSC:
/* DECSC */ /* DECSC */
fBuffer->SaveCursor(); _DecSaveCursor();
parsestate = groundtable; parsestate = groundtable;
break; break;
case CASE_DECRC: case CASE_DECRC:
/* DECRC */ /* DECRC */
fBuffer->RestoreCursor(); _DecRestoreCursor();
parsestate = groundtable; parsestate = groundtable;
break; break;
@@ -840,10 +853,7 @@ TermParse::EscParse()
case CASE_RI: case CASE_RI:
/* RI */ /* RI */
if (fBuffer->Cursor().y == 0) fBuffer->InsertRI();
fBuffer->ScrollBy(-1);
else
fBuffer->MoveCursorUp(1);
parsestate = groundtable; parsestate = groundtable;
break; break;
@@ -1095,6 +1105,10 @@ TermParse::_DecPrivateModeSet(int value)
// screen). // screen).
// Not supported yet. // Not supported yet.
break; break;
case 6:
// Set Origin Mode.
fBuffer->SetOriginMode(true);
break;
case 9: case 9:
// Set Mouse X and Y on button press. // Set Mouse X and Y on button press.
fBuffer->ReportX10MouseEvent(true); fBuffer->ReportX10MouseEvent(true);
@@ -1139,7 +1153,7 @@ TermParse::_DecPrivateModeSet(int value)
case 1049: case 1049:
// Save cursor as in DECSC and use Alternate Screen Buffer, clearing // Save cursor as in DECSC and use Alternate Screen Buffer, clearing
// it first. // it first.
fBuffer->SaveCursor(); _DecSaveCursor();
fBuffer->UseAlternateScreenBuffer(true); fBuffer->UseAlternateScreenBuffer(true);
break; break;
} }
@@ -1166,6 +1180,10 @@ TermParse::_DecPrivateModeReset(int value)
// Normal Video (Leaves Reverse Video, cf. there). // Normal Video (Leaves Reverse Video, cf. there).
// Not supported yet. // Not supported yet.
break; break;
case 6:
// Reset Origin Mode.
fBuffer->SetOriginMode(false);
break;
case 9: case 9:
// Disable Mouse X and Y on button press. // Disable Mouse X and Y on button press.
fBuffer->ReportX10MouseEvent(false); fBuffer->ReportX10MouseEvent(false);
@@ -1210,7 +1228,25 @@ TermParse::_DecPrivateModeReset(int value)
case 1049: case 1049:
// Use Normal Screen Buffer and restore cursor as in DECRC. // Use Normal Screen Buffer and restore cursor as in DECRC.
fBuffer->UseNormalScreenBuffer(); fBuffer->UseNormalScreenBuffer();
fBuffer->RestoreCursor(); _DecRestoreCursor();
break; break;
} }
} }
void
TermParse::_DecSaveCursor()
{
fBuffer->SaveCursor();
fBuffer->SaveOriginMode();
fSavedAttr = fAttr;
}
void
TermParse::_DecRestoreCursor()
{
fBuffer->RestoreCursor();
fBuffer->RestoreOriginMode();
fAttr = fSavedAttr;
}
+5
View File
@@ -78,9 +78,14 @@ private:
void _DeviceStatusReport(int n); void _DeviceStatusReport(int n);
void _DecPrivateModeSet(int value); void _DecPrivateModeSet(int value);
void _DecPrivateModeReset(int value); void _DecPrivateModeReset(int value);
void _DecSaveCursor();
void _DecRestoreCursor();
int fFd; int fFd;
ushort fAttr;
ushort fSavedAttr;
thread_id fParseThread; thread_id fParseThread;
thread_id fReaderThread; thread_id fReaderThread;
sem_id fReaderSem; sem_id fReaderSem;