diff --git a/src/apps/terminal/BasicTerminalBuffer.cpp b/src/apps/terminal/BasicTerminalBuffer.cpp index 19f4416e8e..e70c2098c5 100644 --- a/src/apps/terminal/BasicTerminalBuffer.cpp +++ b/src/apps/terminal/BasicTerminalBuffer.cpp @@ -6,6 +6,7 @@ #include "BasicTerminalBuffer.h" #include +#include #include #include #include @@ -106,6 +107,8 @@ BasicTerminalBuffer::BasicTerminalBuffer() fScreen(NULL), fScreenOffset(0), fHistory(NULL), + fAttributes(0), + fSavedAttributes(0), fSoftWrappedCursor(false), fOverwriteMode(false), fAlternateScreenActive(false), @@ -268,7 +271,7 @@ BasicTerminalBuffer::SynchronizeWith(const BasicTerminalBuffer* other, // directly into destLine. } } else - destLine->Clear(); + destLine->Clear(fAttributes, fWidth); } } @@ -304,6 +307,28 @@ BasicTerminalBuffer::GetChar(int32 row, int32 column, UTF8Char& character, return A_CHAR; } +void +BasicTerminalBuffer::GetCellAttributes(int32 row, int32 column, + uint32& attributes, uint32& count) const +{ + count = 0; + TerminalLine* lineBuffer = ALLOC_LINE_ON_STACK(fWidth); + TerminalLine* line = _HistoryLineAt(row, lineBuffer); + if (line == NULL || column < 0) + return; + + uint32 c = column; + for (; c < fWidth; c++) { + TerminalCell& cell = line->cells[c]; + if (c > column && attributes != cell.attributes) { + break; + } + attributes = cell.attributes; + } + count = c - column; +// printf("r:%d c:%d count:%d a:%x\n", row, column, count, attributes); +} + int32 BasicTerminalBuffer::GetString(int32 row, int32 firstColumn, int32 lastColumn, @@ -578,12 +603,12 @@ BasicTerminalBuffer::Find(const char* _pattern, const TermPos& start, void -BasicTerminalBuffer::InsertChar(UTF8Char c, uint32 width, uint32 attributes) +BasicTerminalBuffer::InsertChar(UTF8Char c, uint32 width) { //debug_printf("BasicTerminalBuffer::InsertChar('%.*s' (%d), %#lx)\n", //(int)c.ByteCount(), c.bytes, c.bytes[0], attributes); if ((int32)width == FULL_WIDTH) - attributes |= A_WIDTH; + fAttributes |= A_WIDTH; if (fSoftWrappedCursor || fCursor.x + (int32)width > fWidth) _SoftBreakLine(); @@ -597,7 +622,7 @@ BasicTerminalBuffer::InsertChar(UTF8Char c, uint32 width, uint32 attributes) TerminalLine* line = _LineAt(fCursor.y); line->cells[fCursor.x].character = c; - line->cells[fCursor.x].attributes = attributes; + line->cells[fCursor.x].attributes = fAttributes; if (line->length < fCursor.x + width) line->length = fCursor.x + width; @@ -638,14 +663,15 @@ BasicTerminalBuffer::FillScreen(UTF8Char c, uint32 width, uint32 attributes) void -BasicTerminalBuffer::InsertCR(uint32 attributes) +BasicTerminalBuffer::InsertCR() { TerminalLine* line = _LineAt(fCursor.y); - line->attributes = attributes; + line->attributes = fAttributes; line->softBreak = false; fSoftWrappedCursor = false; fCursor.x = 0; + _Invalidate(fCursor.y, fCursor.y); _CursorChanged(); } @@ -685,7 +711,7 @@ BasicTerminalBuffer::InsertRI() void -BasicTerminalBuffer::InsertTab(uint32 attributes) +BasicTerminalBuffer::InsertTab() { int32 x; @@ -701,7 +727,7 @@ BasicTerminalBuffer::InsertTab(uint32 attributes) TerminalLine* line = _LineAt(fCursor.y); for (int32 i = fCursor.x; i <= x; i++) { line->cells[i].character = ' '; - line->cells[i].attributes = attributes; + line->cells[i].attributes = fAttributes; } fCursor.x = x; if (line->length < fCursor.x) @@ -745,6 +771,7 @@ BasicTerminalBuffer::InsertSpace(int32 num) line->cells[i].character = kSpaceChar; line->cells[i].attributes = line->cells[fCursor.x - 1].attributes; } + line->attributes = fAttributes; _Invalidate(fCursor.y, fCursor.y); } @@ -755,23 +782,35 @@ void BasicTerminalBuffer::EraseCharsFrom(int32 first, int32 numChars) { TerminalLine* line = _LineAt(fCursor.y); - if (fCursor.y >= line->length) - return; + +/* if (IsAlternateScreenActive())*/ { + int32 end = min_c(first + numChars, fWidth); + for (int32 i = first; i < end; i++) + line->cells[i].attributes = fAttributes; + } + + line->attributes = fAttributes; + + _Invalidate(fCursor.y, fCursor.y); + +// if (fCursor.x >= line->length) +// return; fSoftWrappedCursor = false; int32 end = min_c(first + numChars, line->length); +// printf("%d:%d - %d|", fCursor.y, first, end); if (first > 0 && IS_WIDTH(line->cells[first - 1].attributes)) first--; if (end > 0 && IS_WIDTH(line->cells[end - 1].attributes)) end++; +// printf("%d - %d\n", first, end); for (int32 i = first; i < end; i++) { line->cells[i].character = kSpaceChar; - line->cells[i].attributes = 0; + line->cells[i].attributes = fAttributes; } - _Invalidate(fCursor.y, fCursor.y); } @@ -791,11 +830,11 @@ BasicTerminalBuffer::EraseAbove() if (IS_WIDTH(line->cells[fCursor.x].attributes)) to++; for (int32 i = 0; i <= to; i++) { - line->cells[i].attributes = 0; + line->cells[i].attributes = fAttributes; line->cells[i].character = kSpaceChar; } } else - line->Clear(); + line->Clear(fAttributes, fWidth); _Invalidate(fCursor.y, fCursor.y); } @@ -835,11 +874,19 @@ BasicTerminalBuffer::DeleteChars(int32 numChars) memmove(line->cells + fCursor.x, line->cells + fCursor.x + numChars, left * sizeof(TerminalCell)); line->length = fCursor.x + left; + // process BCE on freed tail cells + for (int i = 0; i < numChars; i++) + line->cells[fCursor.x + left + i].attributes = fAttributes; } else { + // process BCE on freed tail cells + for (int i = 0; i < line->length - fCursor.x; i++) + line->cells[fCursor.x + i].attributes = fAttributes; // remove all remaining chars line->length = fCursor.x; } +// line->attributes = fAttributes; + _Invalidate(fCursor.y, fCursor.y); } } @@ -851,10 +898,15 @@ BasicTerminalBuffer::DeleteColumnsFrom(int32 first) fSoftWrappedCursor = false; TerminalLine* line = _LineAt(fCursor.y); - if (first < line->length) { + + for (int32 i = first; i < fWidth; i++) + line->cells[i].attributes = fAttributes; + + if (first <= line->length) { line->length = first; - _Invalidate(fCursor.y, fCursor.y); + line->attributes = fAttributes; } + _Invalidate(fCursor.y, fCursor.y); } @@ -991,12 +1043,14 @@ BasicTerminalBuffer::_AllocateLines(int32 width, int32 count) return NULL; for (int32 i = 0; i < count; i++) { - lines[i] = (TerminalLine*)malloc(sizeof(TerminalLine) - + sizeof(TerminalCell) * (width - 1)); + const int32 size = sizeof(TerminalLine) + + sizeof(TerminalCell) * (width - 1); + lines[i] = (TerminalLine*)malloc(size); if (lines[i] == NULL) { _FreeLines(lines, i); return NULL; } + memset(lines[i], 0, size); } return lines; @@ -1029,7 +1083,7 @@ BasicTerminalBuffer::_ClearLines(int32 first, int32 last) lastCleared = i; } - line->Clear(); + line->Clear(fAttributes, fWidth); } if (firstCleared >= 0) @@ -1133,7 +1187,7 @@ BasicTerminalBuffer::_ResizeSimple(int32 width, int32 height, // clear the remaining lines for (int32 i = endLine - firstLine; i < height; i++) - lines[i]->Clear(); + lines[i]->Clear(fAttributes, width); _FreeLines(fScreen, fHeight); fScreen = lines; @@ -1223,7 +1277,7 @@ BasicTerminalBuffer::_ResizeRewrap(int32 width, int32 height, // history first, though. if (history != NULL && destTotalLines >= height) history->AddLine(screen[destIndex]); - destLine->Clear(); + destLine->Clear(fAttributes, width); newDestLine = false; } @@ -1273,6 +1327,8 @@ BasicTerminalBuffer::_ResizeRewrap(int32 width, int32 height, sourceLine->cells + sourceX, toCopy * sizeof(TerminalCell)); destLine->length += toCopy; } + + destLine->attributes = sourceLine->attributes; bool nextDestLine = false; if (toCopy == sourceLeft) { @@ -1319,7 +1375,7 @@ BasicTerminalBuffer::_ResizeRewrap(int32 width, int32 height, TerminalLine* line = screen[i % height]; if (history != NULL && i >= height) history->AddLine(line); - line->Clear(); + line->Clear(fAttributes, width); } // Update the values @@ -1401,7 +1457,7 @@ BasicTerminalBuffer::_Scroll(int32 top, int32 bottom, int32 numLines) // lines fScreenOffset = (fScreenOffset + numLines) % fHeight; for (int32 i = bottom - numLines + 1; i <= bottom; i++) - _LineAt(i)->Clear(); + _LineAt(i)->Clear(fAttributes, fWidth); } else { // Partial screen scroll. We move the screen offset anyway, but // have to move the unscrolled lines to their new location. @@ -1416,7 +1472,7 @@ BasicTerminalBuffer::_Scroll(int32 top, int32 bottom, int32 numLines) // update the screen offset and clear the new lines fScreenOffset = (fScreenOffset + numLines) % fHeight; for (int32 i = bottom - numLines + 1; i <= bottom; i++) - _LineAt(i)->Clear(); + _LineAt(i)->Clear(fAttributes, fWidth); } // scroll/extend dirty range @@ -1456,12 +1512,12 @@ BasicTerminalBuffer::_Scroll(int32 top, int32 bottom, int32 numLines) for (int32 i = top + numLines; i <= bottom; i++) { int32 lineToDrop = _LineIndex(i - numLines); int32 lineToKeep = _LineIndex(i); - fScreen[lineToDrop]->Clear(); + fScreen[lineToDrop]->Clear(fAttributes, fWidth); std::swap(fScreen[lineToDrop], fScreen[lineToKeep]); } // clear any lines between the two swapped ranges above for (int32 i = bottom - numLines + 1; i < top + numLines; i++) - _LineAt(i)->Clear(); + _LineAt(i)->Clear(fAttributes, fWidth); _Invalidate(top, bottom); } @@ -1481,12 +1537,12 @@ BasicTerminalBuffer::_Scroll(int32 top, int32 bottom, int32 numLines) for (int32 i = bottom - numLines; i >= top; i--) { int32 lineToKeep = _LineIndex(i); int32 lineToDrop = _LineIndex(i + numLines); - fScreen[lineToDrop]->Clear(); + fScreen[lineToDrop]->Clear(fAttributes, fWidth); std::swap(fScreen[lineToDrop], fScreen[lineToKeep]); } // clear any lines between the two swapped ranges above for (int32 i = bottom - numLines + 1; i < top + numLines; i++) - _LineAt(i)->Clear(); + _LineAt(i)->Clear(fAttributes, fWidth); _Invalidate(top, bottom); } @@ -1515,8 +1571,7 @@ BasicTerminalBuffer::_PadLineToCursor() if (line->length < fCursor.x) { for (int32 i = line->length; i < fCursor.x; i++) { line->cells[i].character = kSpaceChar; - line->cells[i].attributes = 0; - // TODO: Other attributes? +// line->cells[i].attributes = line->attributes; } } } diff --git a/src/apps/terminal/BasicTerminalBuffer.h b/src/apps/terminal/BasicTerminalBuffer.h index 2be3efe833..e84847afa4 100644 --- a/src/apps/terminal/BasicTerminalBuffer.h +++ b/src/apps/terminal/BasicTerminalBuffer.h @@ -86,6 +86,8 @@ public: int GetChar(int32 row, int32 column, UTF8Char& character, uint32& attributes) const; + void GetCellAttributes(int32 row, int32 column, + uint32& attributes, uint32& count) const; int32 GetString(int32 row, int32 firstColumn, int32 lastColumn, char* buffer, uint32& attributes) const; @@ -104,6 +106,10 @@ public: bool matchWord, TermPos& matchStart, TermPos& matchEnd) const; + inline uint32 GetAttributes(); + inline void SetAttributes(uint32 attributes); + inline void PreserveAttributes(bool store); + // snapshots and data capture for debugging void MakeLinesSnapshots(time_t timeStamp, const char* fileName); @@ -111,19 +117,17 @@ public: /*inline*/ void CaptureChar(char ch); // insert chars/lines - inline void InsertChar(UTF8Char c, uint32 attributes); - void InsertChar(UTF8Char c, uint32 width, - uint32 attributes); + inline void InsertChar(UTF8Char c); + void InsertChar(UTF8Char c, uint32 width); + inline void InsertChar(const char* c, int32 length); inline void InsertChar(const char* c, int32 length, - uint32 attributes); - inline void InsertChar(const char* c, int32 length, - uint32 width, uint32 attributes); + uint32 width); void FillScreen(UTF8Char c, uint32 width, uint32 attr); - void InsertCR(uint32 attrs); + void InsertCR(); void InsertLF(); void InsertRI(); - void InsertTab(uint32 attr); + void InsertTab(); void SetInsertMode(int flag); void InsertSpace(int32 num); void InsertLines(int32 numLines); @@ -178,7 +182,7 @@ protected: static TerminalLine** _AllocateLines(int32 width, int32 count); static void _FreeLines(TerminalLine** lines, int32 count); - void _ClearLines(int32 first, int32 last); + void _ClearLines(int32 first, int32 last/*, uint32 attr = 0*/); //TODO attr status_t _ResizeHistory(int32 width, int32 historyCapacity); @@ -214,6 +218,9 @@ protected: int32 fScreenOffset; // index of screen line 0 HistoryBuffer* fHistory; + uint32 fAttributes; + uint32 fSavedAttributes; + // cursor position (origin: (0, 0)) TermPos fCursor; TermPos fSavedCursor; @@ -247,24 +254,48 @@ BasicTerminalBuffer::HistoryCapacity() const } -void -BasicTerminalBuffer::InsertChar(UTF8Char c, uint32 attributes) +uint32 +BasicTerminalBuffer::GetAttributes() { - return InsertChar(c, 1, attributes); + return fAttributes; } void -BasicTerminalBuffer::InsertChar(const char* c, int32 length, uint32 attributes) +BasicTerminalBuffer::SetAttributes(uint32 attributes) { - return InsertChar(UTF8Char(c, length), 1, attributes); + fAttributes = attributes; } void -BasicTerminalBuffer::InsertChar(const char* c, int32 length, uint32 width, uint32 attributes) +BasicTerminalBuffer::PreserveAttributes(bool store) { - return InsertChar(UTF8Char(c, length), width, attributes); + if (store) + fSavedAttributes = fAttributes; + else + fAttributes = fSavedAttributes; +} + + +void +BasicTerminalBuffer::InsertChar(UTF8Char c) +{ + return InsertChar(c, 1); +} + + +void +BasicTerminalBuffer::InsertChar(const char* c, int32 length) +{ + return InsertChar(UTF8Char(c, length), 1); +} + + +void +BasicTerminalBuffer::InsertChar(const char* c, int32 length, uint32 width) +{ + return InsertChar(UTF8Char(c, length), width); } diff --git a/src/apps/terminal/Shell.cpp b/src/apps/terminal/Shell.cpp index 12c3c92689..2209f072d4 100644 --- a/src/apps/terminal/Shell.cpp +++ b/src/apps/terminal/Shell.cpp @@ -68,7 +68,10 @@ #define CSWTCH 0 #endif +// TODO: should extract from /etc/passwd instead??? const char *kDefaultShell = "/bin/sh"; +const char *kTerminalType = "xterm-256color"; +//const char *kTerminalType = "xterm"; /* * Set environment variable. @@ -539,7 +542,7 @@ Shell::_Spawn(int row, int col, const ShellParameters& parameters) /* * setenv TERM and TTY. */ - setenv("TERM", "xterm", true); + setenv("TERM", kTerminalType, true); setenv("TTY", ttyName, true); setenv("TTYPE", parameters.Encoding(), true); diff --git a/src/apps/terminal/TermParse.cpp b/src/apps/terminal/TermParse.cpp index e892f47e1b..4078679138 100644 --- a/src/apps/terminal/TermParse.cpp +++ b/src/apps/terminal/TermParse.cpp @@ -72,8 +72,6 @@ TermParse::_NextParseChar() TermParse::TermParse(int fd) : fFd(fd), - fAttr(BACKCOLOR), - fSavedAttr(BACKCOLOR), fParseThread(-1), fReaderThread(-1), fReaderSem(-1), @@ -393,8 +391,6 @@ TermParse::EscParse() int width = 1; BAutolock locker(fBuffer); - fAttr = fSavedAttr = BACKCOLOR; - while (!fQuitting) { try { uchar c = _NextParseChar(); @@ -416,7 +412,7 @@ TermParse::EscParse() switch (parsestate[c]) { case CASE_PRINT: - fBuffer->InsertChar((char)c, fAttr); + fBuffer->InsertChar((char)c); break; case CASE_PRINT_GR: @@ -470,7 +466,7 @@ TermParse::EscParse() dstbuf, &dstLen, &dummyState, '?'); } - fBuffer->InsertChar(dstbuf, dstLen, width, fAttr); + fBuffer->InsertChar(dstbuf, dstLen, width); break; case CASE_PRINT_CS96: @@ -482,50 +478,50 @@ TermParse::EscParse() dstLen = sizeof(dstbuf); convert_to_utf8(B_EUC_CONVERSION, cbuf, &srcLen, dstbuf, &dstLen, &dummyState, '?'); - fBuffer->InsertChar(dstbuf, dstLen, fAttr); + fBuffer->InsertChar(dstbuf, dstLen); break; case CASE_PRINT_GRA: /* "Special characters and line drawing" enabled by \E(0 */ switch (c) { case 'a': - fBuffer->InsertChar("\xE2\x96\x92",3,fAttr); + fBuffer->InsertChar("\xE2\x96\x92",3); break; case 'j': - fBuffer->InsertChar("\xE2\x94\x98",3,fAttr); + fBuffer->InsertChar("\xE2\x94\x98",3); break; case 'k': - fBuffer->InsertChar("\xE2\x94\x90",3,fAttr); + fBuffer->InsertChar("\xE2\x94\x90",3); break; case 'l': - fBuffer->InsertChar("\xE2\x94\x8C",3,fAttr); + fBuffer->InsertChar("\xE2\x94\x8C",3); break; case 'm': - fBuffer->InsertChar("\xE2\x94\x94",3,fAttr); + fBuffer->InsertChar("\xE2\x94\x94",3); break; case 'n': - fBuffer->InsertChar("\xE2\x94\xBC",3,fAttr); + fBuffer->InsertChar("\xE2\x94\xBC",3); break; case 'q': - fBuffer->InsertChar("\xE2\x94\x80",3,fAttr); + fBuffer->InsertChar("\xE2\x94\x80",3); break; case 't': - fBuffer->InsertChar("\xE2\x94\x9C",3,fAttr); + fBuffer->InsertChar("\xE2\x94\x9C",3); break; case 'u': - fBuffer->InsertChar("\xE2\x94\xA4",3,fAttr); + fBuffer->InsertChar("\xE2\x94\xA4",3); break; case 'v': - fBuffer->InsertChar("\xE2\x94\xB4",3,fAttr); + fBuffer->InsertChar("\xE2\x94\xB4",3); break; case 'w': - fBuffer->InsertChar("\xE2\x94\xAC",3,fAttr); + fBuffer->InsertChar("\xE2\x94\xAC",3); break; case 'x': - fBuffer->InsertChar("\xE2\x94\x82",3,fAttr); + fBuffer->InsertChar("\xE2\x94\x82",3); break; default: - fBuffer->InsertChar((char)c, fAttr); + fBuffer->InsertChar((char)c); } break; @@ -534,7 +530,7 @@ TermParse::EscParse() break; case CASE_CR: - fBuffer->InsertCR(fAttr); + fBuffer->InsertCR(); break; case CASE_SJIS_KANA: @@ -544,7 +540,7 @@ TermParse::EscParse() dstLen = sizeof(dstbuf); convert_to_utf8(currentEncoding, cbuf, &srcLen, dstbuf, &dstLen, &dummyState, '?'); - fBuffer->InsertChar(dstbuf, dstLen, fAttr); + fBuffer->InsertChar(dstbuf, dstLen); break; case CASE_SJIS_INSTRING: @@ -556,7 +552,7 @@ TermParse::EscParse() dstLen = sizeof(dstbuf); convert_to_utf8(currentEncoding, cbuf, &srcLen, dstbuf, &dstLen, &dummyState, '?'); - fBuffer->InsertChar(dstbuf, dstLen, fAttr); + fBuffer->InsertChar(dstbuf, dstLen); break; case CASE_UTF8_2BYTE: @@ -567,7 +563,7 @@ TermParse::EscParse() cbuf[1] = c; cbuf[2] = '\0'; - fBuffer->InsertChar(cbuf, 2, fAttr); + fBuffer->InsertChar(cbuf, 2); break; case CASE_UTF8_3BYTE: @@ -582,7 +578,7 @@ TermParse::EscParse() break; cbuf[2] = c; cbuf[3] = '\0'; - fBuffer->InsertChar(cbuf, 3, fAttr); + fBuffer->InsertChar(cbuf, 3); break; case CASE_MBCS: @@ -635,7 +631,7 @@ TermParse::EscParse() break; case CASE_TAB: - fBuffer->InsertTab(fAttr); + fBuffer->InsertTab(); break; case CASE_ESC: @@ -833,38 +829,48 @@ TermParse::EscParse() case CASE_SGR: { /* SGR */ + uint32 attributes = fBuffer->GetAttributes(); for (row = 0; row < nparam; ++row) { switch (param[row]) { case DEFAULT: case 0: /* Reset attribute */ - fAttr = 0; + attributes = 0; break; case 1: /* Bold */ case 5: - fAttr |= BOLD; + attributes |= BOLD; break; case 4: /* Underline */ - fAttr |= UNDERLINE; + attributes |= UNDERLINE; break; case 7: /* Inverse */ - fAttr |= INVERSE; + attributes |= INVERSE; break; case 22: /* Not Bold */ - fAttr &= ~BOLD; + attributes &= ~BOLD; break; case 24: /* Not Underline */ - fAttr &= ~UNDERLINE; + attributes &= ~UNDERLINE; break; case 27: /* Not Inverse */ - fAttr &= ~INVERSE; + attributes &= ~INVERSE; break; + case 90: + case 91: + case 92: + case 93: + case 94: + case 95: + case 96: + case 97: + param[row] -= 60; case 30: case 31: case 32: @@ -873,18 +879,21 @@ TermParse::EscParse() case 35: case 36: case 37: - fAttr &= ~FORECOLOR; - fAttr |= FORECOLORED(param[row] - 30); - fAttr |= FORESET; + attributes &= ~FORECOLOR; + attributes |= FORECOLORED(param[row] - 30); + attributes |= FORESET; break; case 38: { - if (nparam != 3 || param[1] != 5) - break; - fAttr &= ~FORECOLOR; - fAttr |= FORECOLORED(param[2]); - fAttr |= FORESET; + if (nparam == 3 && param[1] == 5) { + attributes &= ~FORECOLOR; + attributes |= FORECOLORED(param[2]); + attributes |= FORESET; + + } else if (nparam == 5) { + // TODO lookup + } row = nparam; // force exit of the parsing @@ -892,9 +901,18 @@ TermParse::EscParse() } case 39: - fAttr &= ~FORESET; + attributes &= ~FORESET; break; + case 100: + case 101: + case 102: + case 103: + case 104: + case 105: + case 106: + case 107: + param[row] -= 60; case 40: case 41: case 42: @@ -903,18 +921,21 @@ TermParse::EscParse() case 45: case 46: case 47: - fAttr &= ~BACKCOLOR; - fAttr |= BACKCOLORED(param[row] - 40); - fAttr |= BACKSET; + attributes &= ~BACKCOLOR; + attributes |= BACKCOLORED(param[row] - 40); + attributes |= BACKSET; break; case 48: { - if (nparam != 3 || param[1] != 5) - break; - fAttr &= ~BACKCOLOR; - fAttr |= BACKCOLORED(param[2]); - fAttr |= BACKSET; + if (nparam == 3 && param[1] == 5) { + attributes &= ~BACKCOLOR; + attributes |= BACKCOLORED(param[2]); + attributes |= BACKSET; + + } else if (nparam == 5) { + // TODO lookup + } row = nparam; // force exit of the parsing @@ -922,10 +943,11 @@ TermParse::EscParse() } case 49: - fAttr &= ~BACKSET; + attributes &= ~BACKSET; break; } } + fBuffer->SetAttributes(attributes); parsestate = groundtable; break; } @@ -1446,7 +1468,7 @@ TermParse::_DecSaveCursor() { fBuffer->SaveCursor(); fBuffer->SaveOriginMode(); - fSavedAttr = fAttr; + fBuffer->PreserveAttributes(true); } @@ -1455,7 +1477,7 @@ TermParse::_DecRestoreCursor() { fBuffer->RestoreCursor(); fBuffer->RestoreOriginMode(); - fAttr = fSavedAttr; + fBuffer->PreserveAttributes(false); } diff --git a/src/apps/terminal/TermParse.h b/src/apps/terminal/TermParse.h index 01a9cf3a7d..625457322a 100644 --- a/src/apps/terminal/TermParse.h +++ b/src/apps/terminal/TermParse.h @@ -86,9 +86,6 @@ private: int fFd; - uint32 fAttr; - uint32 fSavedAttr; - thread_id fParseThread; thread_id fReaderThread; sem_id fReaderSem; diff --git a/src/apps/terminal/TermView.cpp b/src/apps/terminal/TermView.cpp index 5cb6f8c7b0..160b5c985b 100644 --- a/src/apps/terminal/TermView.cpp +++ b/src/apps/terminal/TermView.cpp @@ -1012,17 +1012,30 @@ TermView::_DrawCursor() _DrawLinePart(fCursor.x * fFontWidth, (int32)rect.top, attr, buffer, width, selected, cursorVisible, this); } else { + if (selected) SetHighColor(fSelectBackColor); + else if (cursorVisible ) + SetHighColor(fCursorBackColor ); else { - if (cursorVisible) - SetHighColor(fCursorBackColor); + uint32 count = 0; + rgb_color rgb_back = fTextBackColor; + if (fTextBuffer->IsAlternateScreenActive()) + // alternate screen uses cell attributes beyond the line ends + fTextBuffer->GetCellAttributes( + fCursor.y, fCursor.x, attr, count); else - SetHighColor(cursorVisible ? fCursorBackColor : fTextBackColor); + attr = fVisibleTextBuffer->GetLineColor( + fCursor.y - firstVisible); + + if (IS_BACKSET(attr)) + rgb_back = fTermColorTable[IS_BACKCOLOR(attr)]; + SetHighColor(rgb_back); } FillRect(rect); } + } @@ -1215,29 +1228,31 @@ TermView::Draw(BRect updateRect) if (count == 0) { // No chars to draw : we just fill the rectangle with the // back color of the last char at the left + int nextColumn = lastColumn + 1; BRect rect(fFontWidth * i, _LineOffset(j), - fFontWidth * (lastColumn + 1) - 1, 0); + fFontWidth * nextColumn - 1, 0); rect.bottom = rect.top + fFontHeight - 1; - if (insideSelection) { - // This area is selected, fill it with the select color - SetHighColor(fSelectBackColor); - FillRect(rect); - } else { - rgb_color rgb_back = fTextBackColor; + rgb_color rgb_back = insideSelection + ? fSelectBackColor : fTextBackColor; - int lineIndexInHistory = j + fTextBuffer->HistorySize(); - uint32 attr = fVisibleTextBuffer->GetLineColor( - lineIndexInHistory); + if (fTextBuffer->IsAlternateScreenActive()) { + // alternate screen uses cell attributes beyond the line ends + uint32 count = 0; + fTextBuffer->GetCellAttributes(j, i, attr, count); + rect.right = rect.left + fFontWidth * count - 1; + nextColumn = i + count; + } else + attr = fVisibleTextBuffer->GetLineColor(j - firstVisible); - if (IS_BACKSET(attr)) - rgb_back = fTermColorTable[IS_BACKCOLOR(attr)]; - SetHighColor(rgb_back); - FillRect(rect); - } + if (IS_BACKSET(attr)) + rgb_back = fTermColorTable[IS_BACKCOLOR(attr)]; + SetHighColor(rgb_back); + rgb_back = HighColor(); + FillRect(rect); // Go on to the next block - i = lastColumn + 1; + i = nextColumn; continue; } diff --git a/src/apps/terminal/TerminalLine.h b/src/apps/terminal/TerminalLine.h index dcbca0e5ec..5f2e4a7d9c 100644 --- a/src/apps/terminal/TerminalLine.h +++ b/src/apps/terminal/TerminalLine.h @@ -24,11 +24,13 @@ struct TerminalLine { uint32 attributes; TerminalCell cells[1]; - inline void Clear() + inline void Clear(uint32 attr = 0, size_t count = 0) { length = 0; - attributes = 0; + attributes = attr; softBreak = false; + for (size_t i = 0; i < count; i++) + cells[i].attributes = attr; } };