Support Background Color Erase, switch to xterm-256color

* Lot of fixes to add support of BCE (background color erase). Shell
  is switched to emulate xterm-256colors terminal, that is modern and
  declare the colors capabilities of our Terminal more precisely;
* Move current character attributes fAttr from TermView to
  BasicTerminalBuffer. This reduces count of function parameters on call
  various InsertXXX routines;
* In alternative screen buffer mode the whole cells "matrix" of the
  screen buffers is taken into account during drawing background of the
  cells in the view. In normal mode the "attributes" field of the
  TerminalLine is used to detect color of the area after the last
  character - there should be no changes with previous behaviour;
* Fix attributes on kSpaceChar-padding short lines. Current _line_
  attributes should be used instead of current _global_ attributes;
* Fixed pads and gaps attributes, more accurate handling of ESC[K and K°;
* _Invalidate strings just erased. Fix EraseChars DCH processing;
* Fixes for ESC[J erase lines control sequences;
* Added handling SGR 90-97, 100-107 codes;
* Clean the newly allocated TerminalLine lines;
* More precise cursor background [off-]color estimation at ends of
  lines. The current line attributes should be used instead of
  hard-coding it to fTextBackground;
* Fixed background color erase in normal screen buffer modes. Wrong
  line indexes calculation messed the drawing results or just returned
  0 [default] line attributes;
* Some more BCE support: TerminalLine::Clear() now honors current
  character attributes;
* Fixes #6143, #6510 and #6424.
This commit is contained in:
Siarzhuk Zharski
2013-03-14 07:44:42 +00:00
parent 718a28cead
commit b512213be6
7 changed files with 249 additions and 124 deletions
+85 -30
View File
@@ -6,6 +6,7 @@
#include "BasicTerminalBuffer.h"
#include <alloca.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <string.h>
@@ -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;
}
}
}
+47 -16
View File
@@ -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);
}
+4 -1
View File
@@ -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);
+75 -53
View File
@@ -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);
}
-3
View File
@@ -86,9 +86,6 @@ private:
int fFd;
uint32 fAttr;
uint32 fSavedAttr;
thread_id fParseThread;
thread_id fReaderThread;
sem_id fReaderSem;
+34 -19
View File
@@ -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;
}
+4 -2
View File
@@ -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;
}
};