diff --git a/src/apps/terminal/BasicTerminalBuffer.cpp b/src/apps/terminal/BasicTerminalBuffer.cpp index 06dfd6cad5..a971e89ca6 100644 --- a/src/apps/terminal/BasicTerminalBuffer.cpp +++ b/src/apps/terminal/BasicTerminalBuffer.cpp @@ -113,7 +113,7 @@ BasicTerminalBuffer::BasicTerminalBuffer() fScreen(NULL), fScreenOffset(0), fHistory(NULL), - fAttributes(0), + fAttributes(), fSoftWrappedCursor(false), fOverwriteMode(false), fAlternateScreenActive(false), @@ -287,13 +287,13 @@ BasicTerminalBuffer::IsFullWidthChar(int32 row, int32 column) const TerminalLine* lineBuffer = ALLOC_LINE_ON_STACK(fWidth); TerminalLine* line = _HistoryLineAt(row, lineBuffer); return line != NULL && column > 0 && column < line->length - && (line->cells[column - 1].attributes & A_WIDTH) != 0; + && line->cells[column - 1].attributes.IsWidth(); } int BasicTerminalBuffer::GetChar(int32 row, int32 column, UTF8Char& character, - uint32& attributes) const + Attributes& attributes) const { TerminalLine* lineBuffer = ALLOC_LINE_ON_STACK(fWidth); TerminalLine* line = _HistoryLineAt(row, lineBuffer); @@ -303,7 +303,7 @@ BasicTerminalBuffer::GetChar(int32 row, int32 column, UTF8Char& character, if (column < 0 || column >= line->length) return NO_CHAR; - if (column > 0 && (line->cells[column - 1].attributes & A_WIDTH) != 0) + if (column > 0 && line->cells[column - 1].attributes.IsWidth()) return IN_STRING; TerminalCell& cell = line->cells[column]; @@ -315,7 +315,7 @@ BasicTerminalBuffer::GetChar(int32 row, int32 column, UTF8Char& character, void BasicTerminalBuffer::GetCellAttributes(int32 row, int32 column, - uint32& attributes, uint32& count) const + Attributes& attributes, uint32& count) const { count = 0; TerminalLine* lineBuffer = ALLOC_LINE_ON_STACK(fWidth); @@ -336,7 +336,7 @@ BasicTerminalBuffer::GetCellAttributes(int32 row, int32 column, int32 BasicTerminalBuffer::GetString(int32 row, int32 firstColumn, int32 lastColumn, - char* buffer, uint32& attributes) const + char* buffer, Attributes& attributes) const { TerminalLine* lineBuffer = ALLOC_LINE_ON_STACK(fWidth); TerminalLine* line = _HistoryLineAt(row, lineBuffer); @@ -419,7 +419,7 @@ BasicTerminalBuffer::FindWord(const TermPos& pos, return true; } - if (x > 0 && IS_WIDTH(line->cells[x - 1].attributes)) + if (x > 0 && line->cells[x - 1].attributes.IsWidth()) x--; // get the char type at the given position @@ -431,7 +431,7 @@ BasicTerminalBuffer::FindWord(const TermPos& pos, // find the beginning TermPos start(x, y); - TermPos end(x + (IS_WIDTH(line->cells[x].attributes) + TermPos end(x + (line->cells[x].attributes.IsWidth() ? FULL_WIDTH : HALF_WIDTH), y); for (;;) { TermPos previousPos = start; @@ -455,7 +455,7 @@ BasicTerminalBuffer::FindWord(const TermPos& pos, if (classifier->Classify(line->cells[nextPos.x].character) != type) break; - nextPos.x += IS_WIDTH(line->cells[nextPos.x].attributes) + nextPos.x += line->cells[nextPos.x].attributes.IsWidth() ? FULL_WIDTH : HALF_WIDTH; end = nextPos; } @@ -489,7 +489,7 @@ BasicTerminalBuffer::NextLinePos(TermPos& pos, bool normalize) const if (!_NormalizeLinePos(lineBuffer, line, pos)) return false; - pos.x += IS_WIDTH(line->cells[pos.x].attributes) ? FULL_WIDTH : HALF_WIDTH; + pos.x += line->cells[pos.x].attributes.IsWidth() ? FULL_WIDTH : HALF_WIDTH; return !normalize || _NormalizeLinePos(lineBuffer, line, pos); } @@ -503,12 +503,15 @@ BasicTerminalBuffer::LineLength(int32 index) const } -int32 -BasicTerminalBuffer::GetLineColor(int32 index) const +void +BasicTerminalBuffer::GetLineColor(int32 index, Attributes& attr) const { TerminalLine* lineBuffer = ALLOC_LINE_ON_STACK(fWidth); TerminalLine* line = _HistoryLineAt(index, lineBuffer); - return line != NULL ? line->attributes : 0; + if (line != NULL) + attr = line->attributes; + else + attr.Reset(); } @@ -641,8 +644,8 @@ BasicTerminalBuffer::InsertChar(UTF8Char c) TerminalLine* line = _LineAt(fCursor.y); line->cells[fCursor.x].character = c; - line->cells[fCursor.x].attributes - = fAttributes | (width == FULL_WIDTH ? A_WIDTH : 0); + line->cells[fCursor.x].attributes = fAttributes; + line->cells[fCursor.x].attributes.state |= (width == FULL_WIDTH ? A_WIDTH : 0); if (line->length < fCursor.x + width) line->length = fCursor.x + width; @@ -662,7 +665,7 @@ BasicTerminalBuffer::InsertChar(UTF8Char c) void -BasicTerminalBuffer::FillScreen(UTF8Char c, uint32 attributes) +BasicTerminalBuffer::FillScreen(UTF8Char c, Attributes &attributes) { uint32 width = HALF_WIDTH; if (c.IsFullWidth()) { @@ -838,9 +841,9 @@ BasicTerminalBuffer::EraseCharsFrom(int32 first, int32 numChars) fSoftWrappedCursor = false; end = min_c(first + numChars, line->length); - if (first > 0 && IS_WIDTH(line->cells[first - 1].attributes)) + if (first > 0 && line->cells[first - 1].attributes.IsWidth()) first--; - if (end > 0 && IS_WIDTH(line->cells[end - 1].attributes)) + if (end > 0 && line->cells[end - 1].attributes.IsWidth()) end++; for (int32 i = first; i < end; i++) { @@ -865,7 +868,7 @@ BasicTerminalBuffer::EraseAbove() TerminalLine* line = _LineAt(fCursor.y); if (fCursor.x < line->length) { int32 to = fCursor.x; - if (IS_WIDTH(line->cells[fCursor.x].attributes)) + if (line->cells[fCursor.x].attributes.IsWidth()) to++; for (int32 i = 0; i <= to; i++) { line->cells[i].attributes = fAttributes; @@ -1090,7 +1093,7 @@ BasicTerminalBuffer::_AllocateLines(int32 width, int32 count) _FreeLines(lines, i); return NULL; } - lines[i]->Clear(0, width); + lines[i]->Clear(width); } return lines; @@ -1337,8 +1340,7 @@ BasicTerminalBuffer::_ResizeRewrap(int32 width, int32 height, int32 toCopy = min_c(sourceLeft, destLeft); // If the last cell to copy is the first cell of a // full-width char, don't copy it yet. - if (toCopy > 0 && IS_WIDTH( - sourceLine->cells[sourceX + toCopy - 1].attributes)) { + if (toCopy > 0 && sourceLine->cells[sourceX + toCopy - 1].attributes.IsWidth()) { //debug_printf(" -> last char is full-width -- don't copy it\n"); toCopy--; } @@ -1620,7 +1622,7 @@ BasicTerminalBuffer::_TruncateLine(TerminalLine* line, int32 length) if (line->length <= length) return; - if (length > 0 && IS_WIDTH(line->cells[length - 1].attributes)) + if (length > 0 && line->cells[length - 1].attributes.IsWidth()) length--; line->length = length; @@ -1661,7 +1663,7 @@ BasicTerminalBuffer::_GetPartialLineString(BString& string, int32 row, const TerminalCell& cell = line->cells[x]; string.Append(cell.character.bytes, cell.character.ByteCount()); - if (IS_WIDTH(cell.attributes)) + if (cell.attributes.IsWidth()) x++; } @@ -1745,7 +1747,7 @@ BasicTerminalBuffer::_PreviousLinePos(TerminalLine* lineBuffer, } pos.x = line->length - 1; } - if (pos.x > 0 && IS_WIDTH(line->cells[pos.x - 1].attributes)) + if (pos.x > 0 && line->cells[pos.x - 1].attributes.IsWidth()) pos.x--; return true; @@ -1805,7 +1807,7 @@ BasicTerminalBuffer::MakeLinesSnapshots(time_t timeStamp, const char* fileName) } fprintf(fileOut, "%02" B_PRId16 ":%02" B_PRId16 ":%08" B_PRIx32 ":\n", - i, line->length, line->attributes); + i, line->length, line->attributes.state); for (int j = 0; j < line->length; j++) if (line->cells[j].character.bytes[0] != 0) fwrite(line->cells[j].character.bytes, 1, @@ -1815,7 +1817,7 @@ BasicTerminalBuffer::MakeLinesSnapshots(time_t timeStamp, const char* fileName) for (int s = 28; s >= 0; s -= 4) { for (int j = 0; j < fWidth; j++) fprintf(fileOut, "%01" B_PRIx32, - (line->cells[j].attributes >> s) & 0x0F); + (line->cells[j].attributes.state >> s) & 0x0F); fprintf(fileOut, "\n"); } diff --git a/src/apps/terminal/BasicTerminalBuffer.h b/src/apps/terminal/BasicTerminalBuffer.h index 418f014a1c..0ae54054e7 100644 --- a/src/apps/terminal/BasicTerminalBuffer.h +++ b/src/apps/terminal/BasicTerminalBuffer.h @@ -91,12 +91,12 @@ public: bool IsFullWidthChar(int32 row, int32 column) const; int GetChar(int32 row, int32 column, UTF8Char& character, - uint32& attributes) const; + Attributes& attributes) const; void GetCellAttributes(int32 row, int32 column, - uint32& attributes, uint32& count) const; + Attributes& attributes, uint32& count) const; int32 GetString(int32 row, int32 firstColumn, int32 lastColumn, char* buffer, - uint32& attributes) const; + Attributes& attributes) const; void GetStringFromRegion(BString& string, const TermPos& start, const TermPos& end) const; @@ -105,7 +105,7 @@ public: bool findNonWords, TermPos& start, TermPos& end) const; int32 LineLength(int32 index) const; - int32 GetLineColor(int32 index) const; + void GetLineColor(int32 index, Attributes& attr) const; bool PreviousLinePos(TermPos& pos) const; bool NextLinePos(TermPos& pos, bool normalize) const; @@ -120,8 +120,8 @@ public: bool matchWord, TermPos& matchStart, TermPos& matchEnd) const; - inline uint32 GetAttributes(); - inline void SetAttributes(uint32 attributes); + inline Attributes GetAttributes(); + inline void SetAttributes(const Attributes& attributes); // snapshots and data capture for debugging void MakeLinesSnapshots(time_t timeStamp, @@ -131,7 +131,7 @@ public: // insert chars/lines void InsertChar(UTF8Char c); - void FillScreen(UTF8Char c, uint32 attr); + void FillScreen(UTF8Char c, Attributes &attr); void InsertCR(); void InsertLF(); @@ -235,7 +235,7 @@ protected: int32 fScreenOffset; // index of screen line 0 HistoryBuffer* fHistory; - uint32 fAttributes; + Attributes fAttributes; // cursor position (origin: (0, 0)) TermPos fCursor; @@ -272,7 +272,7 @@ BasicTerminalBuffer::HistoryCapacity() const } -uint32 +Attributes BasicTerminalBuffer::GetAttributes() { return fAttributes; @@ -280,7 +280,7 @@ BasicTerminalBuffer::GetAttributes() void -BasicTerminalBuffer::SetAttributes(uint32 attributes) +BasicTerminalBuffer::SetAttributes(const Attributes& attributes) { fAttributes = attributes; } diff --git a/src/apps/terminal/HistoryBuffer.cpp b/src/apps/terminal/HistoryBuffer.cpp index ada86f5deb..2a85e4823c 100644 --- a/src/apps/terminal/HistoryBuffer.cpp +++ b/src/apps/terminal/HistoryBuffer.cpp @@ -84,7 +84,7 @@ HistoryBuffer::GetTerminalLineAt(int32 index, TerminalLine* buffer) const int32 charCount = 0; const char* chars = line->Chars(); buffer->length = 0; - uint32 attributes = 0; + Attributes attributes; AttributesRun* attributesRun = line->AttributesRuns(); int32 attributesRunCount = line->attributesRunCount; int32 nextAttributesAt = attributesRunCount > 0 @@ -95,7 +95,7 @@ HistoryBuffer::GetTerminalLineAt(int32 index, TerminalLine* buffer) const if (charCount == nextAttributesAt) { if (charCount < attributesRun->offset) { // the "hole" in attributes run - attributes = 0; + attributes.Reset(); nextAttributesAt = attributesRun->offset; } else if (attributesRunCount > 0) { attributes = attributesRun->attributes; @@ -104,7 +104,7 @@ HistoryBuffer::GetTerminalLineAt(int32 index, TerminalLine* buffer) const attributesRun++; attributesRunCount--; } else { - attributes = 0; + attributes.Reset(); nextAttributesAt = INT_MAX; } } @@ -120,10 +120,10 @@ HistoryBuffer::GetTerminalLineAt(int32 index, TerminalLine* buffer) const // full width char? if (cell.character.IsFullWidth()) { - cell.attributes |= A_WIDTH; + cell.attributes.state |= A_WIDTH; // attributes of the second, "invisible" cell must be // cleared to let full-width chars detection work properly - buffer->cells[charCount++].attributes = 0; + buffer->cells[charCount++].attributes.Reset(); } } @@ -140,18 +140,18 @@ HistoryBuffer::AddLine(const TerminalLine* line) { //debug_printf("HistoryBuffer::AddLine(%p): length: %d\n", line, line->length); // determine the amount of memory we need for the line - uint32 attributes = 0; + Attributes attributes; int32 attributesRuns = 0; int32 byteLength = 0; for (int32 i = 0; i < line->length; i++) { const TerminalCell& cell = line->cells[i]; byteLength += cell.character.ByteCount(); - if ((cell.attributes & CHAR_ATTRIBUTES) != attributes) { - attributes = cell.attributes & CHAR_ATTRIBUTES; - if (attributes != 0) + if ((cell.attributes.state & CHAR_ATTRIBUTES) != attributes.state) { + attributes.state = cell.attributes.state & CHAR_ATTRIBUTES; + if (attributes.state != 0) attributesRuns++; } - if (IS_WIDTH(cell.attributes)) + if (cell.attributes.IsWidth()) i++; } @@ -160,7 +160,7 @@ HistoryBuffer::AddLine(const TerminalLine* line) // allocate and translate the line HistoryLine* historyLine = _AllocateLine(attributesRuns, byteLength); - attributes = 0; + attributes.Reset(); AttributesRun* attributesRun = historyLine->AttributesRuns(); char* chars = historyLine->Chars(); @@ -173,28 +173,28 @@ HistoryBuffer::AddLine(const TerminalLine* line) chars += charLength; // deal with attributes - if ((cell.attributes & CHAR_ATTRIBUTES) != attributes) { + if ((cell.attributes.state & CHAR_ATTRIBUTES) != attributes.state) { // terminate the previous attributes run - if (attributes != 0) { + if (attributes.state != 0) { attributesRun->length = i - attributesRun->offset; attributesRun++; } - attributes = cell.attributes & CHAR_ATTRIBUTES; + attributes.state = cell.attributes.state & CHAR_ATTRIBUTES; // init the new one - if (attributes != 0) { + if (attributes.state != 0) { attributesRun->attributes = attributes; attributesRun->offset = i; } } - if (IS_WIDTH(cell.attributes)) + if (cell.attributes.IsWidth()) i++; } // set the last attributes run's length - if (attributes != 0) + if (attributes.state != 0) attributesRun->length = line->length - attributesRun->offset; historyLine->softBreak = line->softBreak; diff --git a/src/apps/terminal/Shell.cpp b/src/apps/terminal/Shell.cpp index a35b652d73..2da3406f12 100644 --- a/src/apps/terminal/Shell.cpp +++ b/src/apps/terminal/Shell.cpp @@ -74,7 +74,7 @@ // TODO: should extract from /etc/passwd instead??? const char *kDefaultShell = "/bin/sh"; -const char *kTerminalType = "xterm-256color"; +const char *kTerminalType = "xterm"; /* * Set environment variable. diff --git a/src/apps/terminal/TermConst.h b/src/apps/terminal/TermConst.h index 8f56b22785..6903a945bb 100644 --- a/src/apps/terminal/TermConst.h +++ b/src/apps/terminal/TermConst.h @@ -206,18 +206,6 @@ enum { #define BACKCOLOR 0xFF000000 #define CHAR_ATTRIBUTES 0xFFFF7700 -#define IS_WIDTH(x) (((x) & A_WIDTH) ) -#define IS_BOLD(x) (((x) & BOLD) ) -#define IS_UNDER(x) (((x) & UNDERLINE) ) -#define IS_INVERSE(x) (((x) & INVERSE) ) -#define IS_MOUSE(x) (((x) & MOUSE) ) -#define IS_FORESET(x) (((x) & FORESET) ) -#define IS_BACKSET(x) (((x) & BACKSET) ) -#define IS_FONT(x) (((x) & FONT) ) -#define IS_CR(x) (((x) & DUMPCR) ) -#define IS_FORECOLOR(x) (((x) & FORECOLOR) >> 16) -#define IS_BACKCOLOR(x) (((x) & BACKCOLOR) >> 24) - #define FORECOLORED(x) ((x) << 16) #define BACKCOLORED(x) ((x) << 24) diff --git a/src/apps/terminal/TermParse.cpp b/src/apps/terminal/TermParse.cpp index 4e1a291a65..c99e7c1726 100644 --- a/src/apps/terminal/TermParse.cpp +++ b/src/apps/terminal/TermParse.cpp @@ -781,12 +781,12 @@ TermParse::EscParse() case CASE_SGR: { /* SGR */ - uint32 attributes = fBuffer->GetAttributes(); + Attributes attributes = fBuffer->GetAttributes(); for (row = 0; row < nparam; ++row) { switch (param[row]) { case DEFAULT: case 0: /* Reset attribute */ - attributes = 0; + attributes.Reset(); break; case 1: /* Bold */ @@ -831,32 +831,22 @@ TermParse::EscParse() case 35: case 36: case 37: - attributes &= ~FORECOLOR; - attributes |= FORECOLORED(param[row] - 30); - attributes |= FORESET; + attributes.SetIndexedForeground(param[row] - 30); break; case 38: { - int color = -1; if (nparam == 3 && param[1] == 5) - color = param[2]; + attributes.SetIndexedForeground(param[2]); else if (nparam == 5 && param[1] == 2) - color = fBuffer->GuessPaletteColor( - param[2], param[3], param[4]); - - if (color >= 0) { - attributes &= ~FORECOLOR; - attributes |= FORECOLORED(color); - attributes |= FORESET; - } + attributes.SetDirectForeground(param[2], param[3], param[4]); row = nparam; // force exit of the parsing break; } case 39: - attributes &= ~FORESET; + attributes.UnsetForeground(); break; case 100: @@ -876,32 +866,22 @@ TermParse::EscParse() case 45: case 46: case 47: - attributes &= ~BACKCOLOR; - attributes |= BACKCOLORED(param[row] - 40); - attributes |= BACKSET; + attributes.SetIndexedBackground(param[row] - 40); break; case 48: { - int color = -1; if (nparam == 3 && param[1] == 5) - color = param[2]; + attributes.SetIndexedBackground(param[2]); else if (nparam == 5 && param[1] == 2) - color = fBuffer->GuessPaletteColor( - param[2], param[3], param[4]); - - if (color >= 0) { - attributes &= ~BACKCOLOR; - attributes |= BACKCOLORED(color); - attributes |= BACKSET; - } + attributes.SetDirectBackground(param[2], param[3], param[4]); row = nparam; // force exit of the parsing break; } case 49: - attributes &= ~BACKSET; + attributes.UnsetBackground(); break; } } @@ -996,8 +976,11 @@ TermParse::EscParse() case CASE_DECALN: /* DECALN */ - fBuffer->FillScreen(UTF8Char('E'), 0); - parsestate = groundtable; + { + Attributes attr; + fBuffer->FillScreen(UTF8Char('E'), attr); + parsestate = groundtable; + } break; // case CASE_GSETS: diff --git a/src/apps/terminal/TermView.cpp b/src/apps/terminal/TermView.cpp index e6d377a01c..6d2e77af0d 100644 --- a/src/apps/terminal/TermView.cpp +++ b/src/apps/terminal/TermView.cpp @@ -1028,13 +1028,13 @@ TermView::_Deactivate() //! Draw part of a line in the given view. void -TermView::_DrawLinePart(float x1, float y1, uint32 attr, char *buf, - int32 width, Highlight* highlight, bool cursor, BView *inView) +TermView::_DrawLinePart(float x1, float y1, Attributes attr, + char *buf, int32 width, Highlight* highlight, bool cursor, BView *inView) { if (highlight != NULL) - attr = highlight->Highlighter()->AdjustTextAttributes(attr); + attr.state = highlight->Highlighter()->AdjustTextAttributes(attr.state); - inView->SetFont(IS_BOLD(attr) && !fEmulateBold && fAllowBold + inView->SetFont(attr.IsBold() && !fEmulateBold && fAllowBold ? &fBoldFont : &fHalfFont); // Set pen point @@ -1045,13 +1045,10 @@ TermView::_DrawLinePart(float x1, float y1, uint32 attr, char *buf, rgb_color rgb_back = fTextBackColor; // color attribute - int forecolor = IS_FORECOLOR(attr); - int backcolor = IS_BACKCOLOR(attr); - - if (IS_FORESET(attr)) - rgb_fore = fTextBuffer->PaletteColor(forecolor); - if (IS_BACKSET(attr)) - rgb_back = fTextBuffer->PaletteColor(backcolor); + if (attr.IsForeSet()) + rgb_fore = attr.ForegroundColor(fTextBuffer->Palette()); + if (attr.IsBackSet()) + rgb_back = attr.BackgroundColor(fTextBuffer->Palette()); // Selection check. if (cursor) { @@ -1062,7 +1059,7 @@ TermView::_DrawLinePart(float x1, float y1, uint32 attr, char *buf, rgb_back = highlight->Highlighter()->BackgroundColor(); } else { // Reverse attribute(If selected area, don't reverse color). - if (IS_INVERSE(attr)) { + if (attr.IsInverse()) { rgb_color rgb_tmp = rgb_fore; rgb_fore = rgb_back; rgb_back = rgb_tmp; @@ -1076,7 +1073,7 @@ TermView::_DrawLinePart(float x1, float y1, uint32 attr, char *buf, inView->SetHighColor(rgb_fore); // Draw character. - if (IS_BOLD(attr)) { + if (attr.IsBold()) { if (fEmulateBold) { inView->MovePenTo(x1 - 1, y1 + fFontAscent - 1); inView->DrawString((char *)buf); @@ -1097,7 +1094,7 @@ TermView::_DrawLinePart(float x1, float y1, uint32 attr, char *buf, inView->SetDrawingMode(B_OP_COPY); // underline attribute - if (IS_UNDER(attr)) { + if (attr.IsUnder()) { inView->MovePenTo(x1, y1 + fFontAscent); inView->StrokeLine(BPoint(x1 , y1 + fFontAscent), BPoint(x2 , y1 + fFontAscent)); @@ -1116,7 +1113,7 @@ TermView::_DrawCursor() int32 firstVisible = _LineAt(0); UTF8Char character; - uint32 attr = 0; + Attributes attr; bool cursorVisible = _IsCursorVisible(); @@ -1139,7 +1136,7 @@ TermView::_DrawCursor() character, attr) == A_CHAR && (fCursorStyle == BLOCK_CURSOR || !cursorVisible)) { - int32 width = IS_WIDTH(attr) ? FULL_WIDTH : HALF_WIDTH; + int32 width = attr.IsWidth() ? FULL_WIDTH : HALF_WIDTH; char buffer[5]; int32 bytes = UTF8Char::ByteCount(character.bytes[0]); memcpy(buffer, character.bytes, bytes); @@ -1160,15 +1157,15 @@ TermView::_DrawCursor() fTextBuffer->GetCellAttributes( fCursor.y, fCursor.x, attr, count); else - attr = fVisibleTextBuffer->GetLineColor( - fCursor.y - firstVisible); + fVisibleTextBuffer->GetLineColor(fCursor.y - firstVisible, attr); + + if (attr.IsBackSet()) + rgb_back = attr.BackgroundColor(fTextBuffer->Palette()); - if (IS_BACKSET(attr)) - rgb_back = fTextBuffer->PaletteColor(IS_BACKCOLOR(attr)); SetHighColor(rgb_back); } - if (IS_WIDTH(attr) && fCursorStyle != IBEAM_CURSOR) + if (attr.IsWidth() && fCursorStyle != IBEAM_CURSOR) rect.right += fFontWidth; FillRect(rect); @@ -1339,7 +1336,7 @@ TermView::Draw(BRect updateRect) // draw the affected line parts if (x1 <= x2) { - uint32 attr = 0; + Attributes attr; for (int32 j = y1; j <= y2; j++) { int32 k = x1; @@ -1383,12 +1380,10 @@ TermView::Draw(BRect updateRect) rect.right = rect.left + fFontWidth * count - 1; nextColumn = i + count; } else - attr = fVisibleTextBuffer->GetLineColor(j - firstVisible); + fVisibleTextBuffer->GetLineColor(j - firstVisible, attr); - if (IS_BACKSET(attr)) { - int backcolor = IS_BACKCOLOR(attr); - rgb_back = fTextBuffer->PaletteColor(backcolor); - } + if (attr.IsBackSet()) + rgb_back = attr.BackgroundColor(fTextBuffer->Palette()); SetHighColor(rgb_back); rgb_back = HighColor(); @@ -1404,7 +1399,7 @@ TermView::Draw(BRect updateRect) // side - drawing the whole string with one call render the // characters not aligned to cells grid - that looks much more // inaccurate for full-width strings than for half-width ones. - if (IS_WIDTH(attr)) + if (attr.IsWidth()) count = FULL_WIDTH; _DrawLinePart(fFontWidth * i, (int32)_LineOffset(j), diff --git a/src/apps/terminal/TermView.h b/src/apps/terminal/TermView.h index 9836831ddc..7220fef11c 100644 --- a/src/apps/terminal/TermView.h +++ b/src/apps/terminal/TermView.h @@ -23,6 +23,7 @@ #include #include +#include "TerminalLine.h" #include "TermPos.h" #include "TermViewHighlight.h" @@ -202,7 +203,7 @@ private: void _Activate(); void _Deactivate(); - void _DrawLinePart(float x1, float y1, uint32 attr, + void _DrawLinePart(float x1, float y1, Attributes attr, char* buffer, int32 width, Highlight* highlight, bool cursor, BView* inView); @@ -315,7 +316,7 @@ private: BScrollBar* fScrollBar; InlineInput* fInline; - // Color and Attribute. + // Color and Attributes. rgb_color fTextForeColor; rgb_color fTextBackColor; rgb_color fCursorForeColor; diff --git a/src/apps/terminal/TerminalBuffer.cpp b/src/apps/terminal/TerminalBuffer.cpp index ccec6fed30..d05abdf32c 100644 --- a/src/apps/terminal/TerminalBuffer.cpp +++ b/src/apps/terminal/TerminalBuffer.cpp @@ -30,7 +30,7 @@ TerminalBuffer::TerminalBuffer() fAlternateScreen(NULL), fAlternateHistory(NULL), fAlternateScreenOffset(0), - fAlternateAttributes(0), + fAlternateAttributes(), fColorsPalette(NULL), fListenerValid(false) { @@ -280,34 +280,6 @@ TerminalBuffer::SetPaletteColor(uint8 index, rgb_color color) } -rgb_color -TerminalBuffer::PaletteColor(uint8 index) -{ - return fColorsPalette[index]; -} - - -int -TerminalBuffer::GuessPaletteColor(int red, int green, int blue) -{ - int distance = 255 * 100; - int index = -1; - for (uint32 i = 0; i < kTermColorCount && distance > 0; i++) { - rgb_color color = fColorsPalette[i]; - int r = 30 * abs(color.red - red); - int g = 59 * abs(color.green - green); - int b = 11 * abs(color.blue - blue); - int d = r + g + b; - if (distance > d) { - index = i; - distance = d; - } - } - - return min_c(index, int(kTermColorCount - 1)); -} - - void TerminalBuffer::NotifyQuit(int32 reason) { diff --git a/src/apps/terminal/TerminalBuffer.h b/src/apps/terminal/TerminalBuffer.h index 2004ab02a9..3894de7426 100644 --- a/src/apps/terminal/TerminalBuffer.h +++ b/src/apps/terminal/TerminalBuffer.h @@ -42,8 +42,8 @@ public: void SetCursorBlinking(bool blinking); void SetCursorHidden(bool hidden); void SetPaletteColor(uint8 index, rgb_color color); - rgb_color PaletteColor(uint8 index); - int GuessPaletteColor(int red, int green, int blue); + inline const rgb_color* + Palette() const { return fColorsPalette; } void NotifyQuit(int32 reason); @@ -75,7 +75,7 @@ private: TerminalLine** fAlternateScreen; HistoryBuffer* fAlternateHistory; int32 fAlternateScreenOffset; - uint32 fAlternateAttributes; + Attributes fAlternateAttributes; rgb_color* fColorsPalette; // listener/dirty region management diff --git a/src/apps/terminal/TerminalLine.h b/src/apps/terminal/TerminalLine.h index 044cce7d99..abdc25a276 100644 --- a/src/apps/terminal/TerminalLine.h +++ b/src/apps/terminal/TerminalLine.h @@ -10,6 +10,7 @@ #ifndef TERMINAL_LINE_H #define TERMINAL_LINE_H +#include #include #include "TermConst.h" @@ -17,19 +18,142 @@ #include "UTF8Char.h" +struct Attributes { + uint32 state; + uint32 foreground; + uint32 background; + + Attributes() : state(0), foreground(0), background(0) {} + + inline void Reset() { state = 0; foreground = 0; background = 0; } + + inline bool IsWidth() const { return (state & A_WIDTH) == A_WIDTH; } + inline bool IsBold() const { return (state & BOLD) == BOLD; } + inline bool IsUnder() const { return (state & UNDERLINE) == UNDERLINE; } + inline bool IsInverse() const { return (state & INVERSE) == INVERSE; } + inline bool IsMouse() const { return (state & MOUSE) == MOUSE; } + inline bool IsForeSet() const { return (state & FORESET) == FORESET; } + inline bool IsBackSet() const { return (state & BACKSET) == BACKSET; } + inline bool IsFont() const { return (state & FONT) == FONT; } + inline bool IsCR() const { return (state & DUMPCR) == DUMPCR; } + + inline void SetDirectForeground(uint8 red, uint8 green, uint8 blue) + { + foreground = 0x80000000 | (red << 16) | (green << 8) | blue; + state &= ~FORECOLOR; + state |= FORESET; + } + + inline void SetDirectBackground(uint8 red, uint8 green, uint8 blue) + { + background = 0x80000000 | (red << 16) | (green << 8) | blue; + state &= ~BACKCOLOR; + state |= BACKSET; + } + + inline void SetIndexedForeground(uint32 index) + { + state &= ~FORECOLOR; + state |= FORESET; + state |= FORECOLORED(index); + foreground = 0; + } + + inline void SetIndexedBackground(uint32 index) + { + state &= ~BACKCOLOR; + state |= BACKSET; + state |= BACKCOLORED(index); + background = 0; + } + + inline void UnsetForeground() + { + state &= ~FORESET; + foreground = 0; + } + + inline void UnsetBackground() + { + state &= ~BACKSET; + background = 0; + } + + inline rgb_color + ForegroundColor(const rgb_color* indexedColors) const + { + if ((foreground & 0x80000000) != 0) + return make_color((foreground >> 16) & 0xFF, + (foreground >> 8) & 0xFF, + foreground & 0xFF); + else + return indexedColors[(state & FORECOLOR) >> 16]; + } + + inline rgb_color + BackgroundColor(const rgb_color* indexedColors) const + { + if ((background & 0x80000000) != 0) + return make_color((background >> 16) & 0xFF, + (background >> 8) & 0xFF, + background & 0xFF); + else + return indexedColors[(state & BACKCOLOR) >> 24]; + } + + inline Attributes& + operator&=(uint32 value) { state &= value; return *this; } + + inline Attributes& + operator|=(uint32 value) { state |= value; return *this; } + + inline uint32 + operator|(uint32 value) { return state | value; } + + inline uint32 + operator&(uint32 value) { return state & value; } + + inline bool + operator==(const Attributes& other) const + { + return state == other.state + && foreground == other.foreground + && background == other.background; + } + + inline bool + operator!=(const Attributes& other) const + { + return state != other.state + || foreground != other.foreground + || background != other.background; + } +}; + + struct TerminalCell { - UTF8Char character; - uint32 attributes; + UTF8Char character; + Attributes attributes; }; struct TerminalLine { uint16 length; bool softBreak; // soft line break - uint32 attributes; + Attributes attributes; TerminalCell cells[1]; - inline void Clear(uint32 attr = 0, size_t count = 0) + inline void Clear() + { + Clear(Attributes()); + } + + inline void Clear(size_t count) + { + Clear(Attributes(), count); + } + + inline void Clear(Attributes attr, size_t count = 0) { length = 0; attributes = attr; @@ -41,7 +165,7 @@ struct TerminalLine { struct AttributesRun { - uint32 attributes; + Attributes attributes; uint16 offset; // character offset uint16 length; // length of the run in characters }; @@ -52,7 +176,7 @@ struct HistoryLine { uint16 attributesRunCount; // number of attribute runs uint16 byteLength : 15; // number of bytes in the line bool softBreak : 1; // soft line break; - uint32 attributes; + Attributes attributes; AttributesRun* AttributesRuns() const {