256 colors support in terminal (compatible with xterm)

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@38090 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Adrien Destugues
2010-08-13 16:23:21 +00:00
parent 6100b6aa33
commit dbf7fa8716
2 changed files with 475 additions and 198 deletions
+223 -197
View File
@@ -389,10 +389,10 @@ TermParse::EscParse()
/* case iso8859 gr character, or euc */ /* case iso8859 gr character, or euc */
ptr = cbuf; ptr = cbuf;
if (currentEncoding == B_EUC_CONVERSION if (currentEncoding == B_EUC_CONVERSION
|| currentEncoding == B_EUC_KR_CONVERSION || currentEncoding == B_EUC_KR_CONVERSION
|| currentEncoding == B_JIS_CONVERSION || currentEncoding == B_JIS_CONVERSION
|| currentEncoding == B_GBK_CONVERSION || currentEncoding == B_GBK_CONVERSION
|| currentEncoding == B_BIG5_CONVERSION) { || currentEncoding == B_BIG5_CONVERSION) {
switch (parsestate[curess]) { switch (parsestate[curess]) {
case CASE_SS2: /* JIS X 0201 */ case CASE_SS2: /* JIS X 0201 */
width = 1; width = 1;
@@ -429,10 +429,10 @@ TermParse::EscParse()
srcLen = strlen(cbuf); srcLen = strlen(cbuf);
if (currentEncoding != B_JIS_CONVERSION) { if (currentEncoding != B_JIS_CONVERSION) {
convert_to_utf8(currentEncoding, cbuf, &srcLen, convert_to_utf8(currentEncoding, cbuf, &srcLen,
dstbuf, &dstLen, &dummyState, '?'); dstbuf, &dstLen, &dummyState, '?');
} else { } else {
convert_to_utf8(B_EUC_CONVERSION, cbuf, &srcLen, convert_to_utf8(B_EUC_CONVERSION, cbuf, &srcLen,
dstbuf, &dstLen, &dummyState, '?'); dstbuf, &dstLen, &dummyState, '?');
} }
fBuffer->InsertChar(dstbuf, dstLen, width, fAttr); fBuffer->InsertChar(dstbuf, dstLen, width, fAttr);
@@ -446,7 +446,7 @@ TermParse::EscParse()
srcLen = 2; srcLen = 2;
dstLen = 0; dstLen = 0;
convert_to_utf8(B_EUC_CONVERSION, cbuf, &srcLen, convert_to_utf8(B_EUC_CONVERSION, cbuf, &srcLen,
dstbuf, &dstLen, &dummyState, '?'); dstbuf, &dstLen, &dummyState, '?');
fBuffer->InsertChar(dstbuf, dstLen, fAttr); fBuffer->InsertChar(dstbuf, dstLen, fAttr);
break; break;
@@ -488,7 +488,7 @@ TermParse::EscParse()
srcLen = 1; srcLen = 1;
dstLen = 0; dstLen = 0;
convert_to_utf8(currentEncoding, cbuf, &srcLen, convert_to_utf8(currentEncoding, cbuf, &srcLen,
dstbuf, &dstLen, &dummyState, '?'); dstbuf, &dstLen, &dummyState, '?');
fBuffer->InsertChar(dstbuf, dstLen, fAttr); fBuffer->InsertChar(dstbuf, dstLen, fAttr);
break; break;
@@ -500,7 +500,7 @@ TermParse::EscParse()
srcLen = 2; srcLen = 2;
dstLen = 0; dstLen = 0;
convert_to_utf8(currentEncoding, cbuf, &srcLen, convert_to_utf8(currentEncoding, cbuf, &srcLen,
dstbuf, &dstLen, &dummyState, '?'); dstbuf, &dstLen, &dummyState, '?');
fBuffer->InsertChar(dstbuf, dstLen, fAttr); fBuffer->InsertChar(dstbuf, dstLen, fAttr);
break; break;
@@ -746,7 +746,9 @@ TermParse::EscParse()
break; break;
case CASE_SGR: case CASE_SGR:
{
/* SGR */ /* SGR */
char xterm256_mode = 0;
for (row = 0; row < nparam; ++row) { for (row = 0; row < nparam; ++row) {
switch (param[row]) { switch (param[row]) {
case DEFAULT: case DEFAULT:
@@ -754,8 +756,11 @@ TermParse::EscParse()
fAttr = 0; fAttr = 0;
break; break;
case 1: case 5: /* Bold or validation of xterm 256 col*/
case 5: /* Bold */ if (xterm256_mode)
xterm256_mode |= 4;
// falthrough
case 1: /* Bold */
fAttr |= BOLD; fAttr |= BOLD;
break; break;
@@ -792,6 +797,10 @@ TermParse::EscParse()
fAttr |= FORESET; fAttr |= FORESET;
break; break;
case 38:
xterm256_mode = 1;
break;
case 39: case 39:
fAttr &= ~FORESET; fAttr &= ~FORESET;
break; break;
@@ -809,149 +818,166 @@ TermParse::EscParse()
fAttr |= BACKSET; fAttr |= BACKSET;
break; break;
case 48:
xterm256_mode = 2;
break;
case 49: case 49:
fAttr &= ~BACKSET; fAttr &= ~BACKSET;
break; break;
} }
if (xterm256_mode == 5) {
fAttr &= ~FORECOLOR;
fAttr |= FORECOLORED(param[row]);
fAttr |= FORESET;
}
if (xterm256_mode == 6) {
fAttr &= ~BACKCOLOR;
fAttr |= BACKCOLORED(param[row]);
fAttr |= BACKSET;
}
} }
parsestate = groundtable; parsestate = groundtable;
break; break;
}
case CASE_CPR: case CASE_CPR:
// Q & D hack by Y.Hayakawa ([email protected]) // Q & D hack by Y.Hayakawa ([email protected])
// 21-JUL-99 // 21-JUL-99
_DeviceStatusReport(param[0]); _DeviceStatusReport(param[0]);
parsestate = groundtable; parsestate = groundtable;
break; break;
case CASE_DA1: case CASE_DA1:
// DA - report device attributes // DA - report device attributes
if (param[0] < 1) { if (param[0] < 1) {
// claim to be a VT102 // claim to be a VT102
write(fFd, "\033[?6c", 5); write(fFd, "\033[?6c", 5);
} }
parsestate = groundtable; parsestate = groundtable;
break; break;
case CASE_DECSTBM: case CASE_DECSTBM:
/* DECSTBM - set scrolling region */ /* DECSTBM - set scrolling region */
if ((top = param[0]) < 1) if ((top = param[0]) < 1)
top = 1; top = 1;
if (nparam < 2) if (nparam < 2)
bottom = fBuffer->Height(); bottom = fBuffer->Height();
else else
bottom = param[1]; bottom = param[1];
top--; top--;
bottom--; bottom--;
if (bottom > top) if (bottom > top)
fBuffer->SetScrollRegion(top, bottom); fBuffer->SetScrollRegion(top, bottom);
parsestate = groundtable; parsestate = groundtable;
break; break;
case CASE_DECREQTPARM: case CASE_DECREQTPARM:
// DEXREQTPARM - request terminal parameters // DEXREQTPARM - request terminal parameters
_DecReqTermParms(param[0]); _DecReqTermParms(param[0]);
parsestate = groundtable; parsestate = groundtable;
break; break;
case CASE_DECSET: case CASE_DECSET:
/* DECSET */ /* DECSET */
for (int i = 0; i < nparam; i++) for (int i = 0; i < nparam; i++)
_DecPrivateModeSet(param[i]); _DecPrivateModeSet(param[i]);
parsestate = groundtable; parsestate = groundtable;
break; break;
case CASE_DECRST: case CASE_DECRST:
/* DECRST */ /* DECRST */
for (int i = 0; i < nparam; i++) for (int i = 0; i < nparam; i++)
_DecPrivateModeReset(param[i]); _DecPrivateModeReset(param[i]);
parsestate = groundtable; parsestate = groundtable;
break; break;
case CASE_DECALN: case CASE_DECALN:
/* DECALN */ /* DECALN */
fBuffer->FillScreen(UTF8Char('E'), 1, 0); fBuffer->FillScreen(UTF8Char('E'), 1, 0);
parsestate = groundtable; parsestate = groundtable;
break; break;
// case CASE_GSETS: // case CASE_GSETS:
// screen->gsets[scstype] = GSET(c) | cs96; // screen->gsets[scstype] = GSET(c) | cs96;
// parsestate = groundtable; // parsestate = groundtable;
// break; // break;
case CASE_DECSC: case CASE_DECSC:
/* DECSC */ /* DECSC */
_DecSaveCursor(); _DecSaveCursor();
parsestate = groundtable; parsestate = groundtable;
break; break;
case CASE_DECRC: case CASE_DECRC:
/* DECRC */ /* DECRC */
_DecRestoreCursor(); _DecRestoreCursor();
parsestate = groundtable; parsestate = groundtable;
break; break;
case CASE_HTS: case CASE_HTS:
/* HTS */ /* HTS */
fBuffer->SetTabStop(fBuffer->Cursor().x); fBuffer->SetTabStop(fBuffer->Cursor().x);
parsestate = groundtable; parsestate = groundtable;
break; break;
case CASE_TBC: case CASE_TBC:
/* TBC */ /* TBC */
if (param[0] < 1) if (param[0] < 1)
fBuffer->ClearTabStop(fBuffer->Cursor().x); fBuffer->ClearTabStop(fBuffer->Cursor().x);
else if (param[0] == 3) else if (param[0] == 3)
fBuffer->ClearAllTabStops(); fBuffer->ClearAllTabStops();
parsestate = groundtable; parsestate = groundtable;
break; break;
case CASE_RI: case CASE_RI:
/* RI */ /* RI */
fBuffer->InsertRI(); fBuffer->InsertRI();
parsestate = groundtable; parsestate = groundtable;
break; break;
case CASE_SS2: case CASE_SS2:
/* SS2 */ /* SS2 */
curess = c; curess = c;
parsestate = groundtable; parsestate = groundtable;
break; break;
case CASE_SS3: case CASE_SS3:
/* SS3 */ /* SS3 */
curess = c; curess = c;
parsestate = groundtable; parsestate = groundtable;
break; break;
case CASE_CSI_STATE: case CASE_CSI_STATE:
/* enter csi state */ /* enter csi state */
nparam = 1; nparam = 1;
param[0] = DEFAULT; param[0] = DEFAULT;
parsestate = gCsiTable; parsestate = gCsiTable;
break; break;
case CASE_OSC: case CASE_OSC:
{ {
/* Operating System Command: ESC ] */ /* Operating System Command: ESC ] */
char string[512]; char string[512];
uint32 len = 0; uint32 len = 0;
uchar mode_char = _NextParseChar(); uchar mode_char = _NextParseChar();
if (mode_char != '0' if (mode_char != '0'
&& mode_char != '1' && mode_char != '1'
&& mode_char != '2') { && mode_char != '2') {
parsestate = groundtable; parsestate = groundtable;
break; break;
} }
uchar currentChar = _NextParseChar(); uchar currentChar = _NextParseChar();
while ((currentChar = _NextParseChar()) != 0x7) { while ((currentChar = _NextParseChar()) != 0x7) {
if (!isprint(currentChar & 0x7f) if (!isprint(currentChar & 0x7f)
|| len+2 >= sizeof(string)) || len+2 >= sizeof(string))
break; break;
string[len++] = currentChar; string[len++] = currentChar;
} }
@@ -970,84 +996,84 @@ TermParse::EscParse()
break; break;
} }
case CASE_RIS: // ESC c ... Reset terminal. case CASE_RIS: // ESC c ... Reset terminal.
break; break;
case CASE_LS2: case CASE_LS2:
/* LS2 */ /* LS2 */
// screen->curgl = 2; // screen->curgl = 2;
parsestate = groundtable; parsestate = groundtable;
break; break;
case CASE_LS3: case CASE_LS3:
/* LS3 */ /* LS3 */
// screen->curgl = 3; // screen->curgl = 3;
parsestate = groundtable; parsestate = groundtable;
break; break;
case CASE_LS3R: case CASE_LS3R:
/* LS3R */ /* LS3R */
// screen->curgr = 3; // screen->curgr = 3;
parsestate = groundtable; parsestate = groundtable;
break; break;
case CASE_LS2R: case CASE_LS2R:
/* LS2R */ /* LS2R */
// screen->curgr = 2; // screen->curgr = 2;
parsestate = groundtable; parsestate = groundtable;
break; break;
case CASE_LS1R: case CASE_LS1R:
/* LS1R */ /* LS1R */
// screen->curgr = 1; // screen->curgr = 1;
parsestate = groundtable; parsestate = groundtable;
break; break;
case CASE_VPA: // ESC [...d move cursor absolute vertical case CASE_VPA: // ESC [...d move cursor absolute vertical
/* VPA (CV) */ /* VPA (CV) */
if ((row = param[0]) < 1) if ((row = param[0]) < 1)
row = 1; row = 1;
// note beterm wants it 1-based unlike usual terminals // note beterm wants it 1-based unlike usual terminals
fBuffer->SetCursorY(row - 1); fBuffer->SetCursorY(row - 1);
parsestate = groundtable; parsestate = groundtable;
break; break;
case CASE_HPA: // ESC [...G move cursor absolute horizontal case CASE_HPA: // ESC [...G move cursor absolute horizontal
/* HPA (CH) */ /* HPA (CH) */
if ((column = param[0]) < 1) if ((column = param[0]) < 1)
column = 1; column = 1;
// note beterm wants it 1-based unlike usual terminals // note beterm wants it 1-based unlike usual terminals
fBuffer->SetCursorX(column - 1); fBuffer->SetCursorX(column - 1);
parsestate = groundtable; parsestate = groundtable;
break; break;
case CASE_SU: // scroll screen up case CASE_SU: // scroll screen up
if ((row = param[0]) < 1) if ((row = param[0]) < 1)
row = 1; row = 1;
fBuffer->ScrollBy(row); fBuffer->ScrollBy(row);
parsestate = groundtable; parsestate = groundtable;
break; break;
case CASE_SD: // scroll screen down case CASE_SD: // scroll screen down
if ((row = param[0]) < 1) if ((row = param[0]) < 1)
row = 1; row = 1;
fBuffer->ScrollBy(-row); fBuffer->ScrollBy(-row);
parsestate = groundtable; parsestate = groundtable;
break; break;
case CASE_ECH: // erase characters case CASE_ECH: // erase characters
if ((column = param[0]) < 1) if ((column = param[0]) < 1)
column = 1; column = 1;
fBuffer->EraseChars(column); fBuffer->EraseChars(column);
parsestate = groundtable; parsestate = groundtable;
break; break;
default: default:
break; break;
} }
} catch (...) { } catch (...) {
break; break;
} }
@@ -1057,21 +1083,21 @@ TermParse::EscParse()
} }
/*static*/ int32 /*static*/ int32
TermParse::_ptyreader_thread(void *data) TermParse::_ptyreader_thread(void *data)
{ {
return reinterpret_cast<TermParse *>(data)->PtyReader(); return reinterpret_cast<TermParse *>(data)->PtyReader();
} }
/*static*/ int32 /*static*/ int32
TermParse::_escparse_thread(void *data) TermParse::_escparse_thread(void *data)
{ {
return reinterpret_cast<TermParse *>(data)->EscParse(); return reinterpret_cast<TermParse *>(data)->EscParse();
} }
status_t status_t
TermParse::_ReadParserBuffer() TermParse::_ReadParserBuffer()
{ {
// We have to unlock the terminal buffer while waiting for data from the // We have to unlock the terminal buffer while waiting for data from the
@@ -1112,10 +1138,10 @@ TermParse::_ReadParserBuffer()
int32 bufferSize = atomic_add(&fReadBufferSize, -toRead); int32 bufferSize = atomic_add(&fReadBufferSize, -toRead);
// If the pty reader thread waits and we have made enough space in the // If the pty reader thread waits and we have made enough space in the
// buffer now, let it run again. // buffer now, let it run again.
if (bufferSize > READ_BUF_SIZE - MIN_PTY_BUFFER_SPACE if (bufferSize > READ_BUF_SIZE - MIN_PTY_BUFFER_SPACE
&& bufferSize - toRead <= READ_BUF_SIZE - MIN_PTY_BUFFER_SPACE) { && bufferSize - toRead <= READ_BUF_SIZE - MIN_PTY_BUFFER_SPACE) {
release_sem(fReaderLocker); release_sem(fReaderLocker);
} }
@@ -1127,7 +1153,7 @@ TermParse::_ReadParserBuffer()
} }
void void
TermParse::_DeviceStatusReport(int n) TermParse::_DeviceStatusReport(int n)
{ {
char sbuf[16] ; char sbuf[16] ;
@@ -1135,18 +1161,18 @@ TermParse::_DeviceStatusReport(int n)
switch (n) { switch (n) {
case 5: case 5:
{ {
// Device status report requested // Device status report requested
// reply with "no malfunction detected" // reply with "no malfunction detected"
const char* toWrite = "\033[0n"; const char* toWrite = "\033[0n";
write(fFd, toWrite, strlen(toWrite)); write(fFd, toWrite, strlen(toWrite));
break ; break ;
} }
case 6: case 6:
// Cursor position report requested // Cursor position report requested
len = sprintf(sbuf, "\033[%ld;%ldR", len = sprintf(sbuf, "\033[%ld;%ldR",
fBuffer->Cursor().y + 1, fBuffer->Cursor().y + 1,
fBuffer->Cursor().x + 1); fBuffer->Cursor().x + 1);
write(fFd, sbuf, len); write(fFd, sbuf, len);
break ; break ;
default: default:
@@ -1155,7 +1181,7 @@ TermParse::_DeviceStatusReport(int n)
} }
void void
TermParse::_DecReqTermParms(int value) TermParse::_DecReqTermParms(int value)
{ {
// Terminal parameters report: // Terminal parameters report:
@@ -1179,7 +1205,7 @@ TermParse::_DecReqTermParms(int value)
} }
void void
TermParse::_DecPrivateModeSet(int value) TermParse::_DecPrivateModeSet(int value)
{ {
switch (value) { switch (value) {
@@ -1248,7 +1274,7 @@ TermParse::_DecPrivateModeSet(int value)
} }
void void
TermParse::_DecPrivateModeReset(int value) TermParse::_DecPrivateModeReset(int value)
{ {
switch (value) { switch (value) {
@@ -1322,7 +1348,7 @@ TermParse::_DecPrivateModeReset(int value)
} }
void void
TermParse::_DecSaveCursor() TermParse::_DecSaveCursor()
{ {
fBuffer->SaveCursor(); fBuffer->SaveCursor();
@@ -1331,7 +1357,7 @@ TermParse::_DecSaveCursor()
} }
void void
TermParse::_DecRestoreCursor() TermParse::_DecRestoreCursor()
{ {
fBuffer->RestoreCursor(); fBuffer->RestoreCursor();
+252 -1
View File
@@ -62,7 +62,7 @@
extern int function_keycode_table[]; extern int function_keycode_table[];
extern char *function_key_char_table[]; extern char *function_key_char_table[];
const static rgb_color kTermColorTable[8] = { const static rgb_color kTermColorTable[256] = {
{ 40, 40, 40, 0}, // black { 40, 40, 40, 0}, // black
{204, 0, 0, 0}, // red {204, 0, 0, 0}, // red
{ 78, 154, 6, 0}, // green { 78, 154, 6, 0}, // green
@@ -71,6 +71,257 @@ const static rgb_color kTermColorTable[8] = {
{115, 68, 123, 0}, // magenta {115, 68, 123, 0}, // magenta
{ 6, 152, 154, 0}, // cyan { 6, 152, 154, 0}, // cyan
{245, 245, 245, 0}, // white {245, 245, 245, 0}, // white
{128, 128, 128, 0}, // black
{255, 0, 0, 0}, // red
{ 0, 255, 0, 0}, // green
{255, 255, 0, 0}, // yellow
{ 0, 0, 255, 0}, // blue
{255, 0, 255, 0}, // magenta
{ 0, 255, 255, 0}, // cyan
{255, 255, 255, 0}, // white
{ 0, 0, 0, 0},
{ 0, 0, 51, 0},
{ 0, 0, 102, 0},
{ 0, 0, 153, 0},
{ 0, 0, 204, 0},
{ 0, 0, 255, 0},
{ 0, 51, 0, 0},
{ 0, 51, 51, 0},
{ 0, 51, 102, 0},
{ 0, 51, 153, 0},
{ 0, 51, 204, 0},
{ 0, 51, 255, 0},
{ 0, 102, 0, 0},
{ 0, 102, 51, 0},
{ 0, 102, 102, 0},
{ 0, 102, 153, 0},
{ 0, 102, 204, 0},
{ 0, 102, 255, 0},
{ 0, 153, 0, 0},
{ 0, 153, 51, 0},
{ 0, 153, 102, 0},
{ 0, 153, 153, 0},
{ 0, 153, 204, 0},
{ 0, 153, 255, 0},
{ 0, 204, 0, 0},
{ 0, 204, 51, 0},
{ 0, 204, 102, 0},
{ 0, 204, 153, 0},
{ 0, 204, 204, 0},
{ 0, 204, 255, 0},
{ 0, 255, 0, 0},
{ 0, 255, 51, 0},
{ 0, 255, 102, 0},
{ 0, 255, 153, 0},
{ 0, 255, 204, 0},
{ 0, 255, 255, 0},
{ 51, 0, 0, 0},
{ 51, 0, 51, 0},
{ 51, 0, 102, 0},
{ 51, 0, 153, 0},
{ 51, 0, 204, 0},
{ 51, 0, 255, 0},
{ 51, 51, 0, 0},
{ 51, 51, 51, 0},
{ 51, 51, 102, 0},
{ 51, 51, 153, 0},
{ 51, 51, 204, 0},
{ 51, 51, 255, 0},
{ 51, 102, 0, 0},
{ 51, 102, 51, 0},
{ 51, 102, 102, 0},
{ 51, 102, 153, 0},
{ 51, 102, 204, 0},
{ 51, 102, 255, 0},
{ 51, 153, 0, 0},
{ 51, 153, 51, 0},
{ 51, 153, 102, 0},
{ 51, 153, 153, 0},
{ 51, 153, 204, 0},
{ 51, 153, 255, 0},
{ 51, 204, 0, 0},
{ 51, 204, 51, 0},
{ 51, 204, 102, 0},
{ 51, 204, 153, 0},
{ 51, 204, 204, 0},
{ 51, 204, 255, 0},
{ 51, 255, 0, 0},
{ 51, 255, 51, 0},
{ 51, 255, 102, 0},
{ 51, 255, 153, 0},
{ 51, 255, 204, 0},
{ 51, 255, 255, 0},
{102, 0, 0, 0},
{102, 0, 51, 0},
{102, 0, 102, 0},
{102, 0, 153, 0},
{102, 0, 204, 0},
{102, 0, 255, 0},
{102, 51, 0, 0},
{102, 51, 51, 0},
{102, 51, 102, 0},
{102, 51, 153, 0},
{102, 51, 204, 0},
{102, 51, 255, 0},
{102, 102, 0, 0},
{102, 102, 51, 0},
{102, 102, 102, 0},
{102, 102, 153, 0},
{102, 102, 204, 0},
{102, 102, 255, 0},
{102, 153, 0, 0},
{102, 153, 51, 0},
{102, 153, 102, 0},
{102, 153, 153, 0},
{102, 153, 204, 0},
{102, 153, 255, 0},
{102, 204, 0, 0},
{102, 204, 51, 0},
{102, 204, 102, 0},
{102, 204, 153, 0},
{102, 204, 204, 0},
{102, 204, 255, 0},
{102, 255, 0, 0},
{102, 255, 51, 0},
{102, 255, 102, 0},
{102, 255, 153, 0},
{102, 255, 204, 0},
{102, 255, 255, 0},
{153, 0, 0, 0},
{153, 0, 51, 0},
{153, 0, 102, 0},
{153, 0, 153, 0},
{153, 0, 204, 0},
{153, 0, 255, 0},
{153, 51, 0, 0},
{153, 51, 51, 0},
{153, 51, 102, 0},
{153, 51, 153, 0},
{153, 51, 204, 0},
{153, 51, 255, 0},
{153, 102, 0, 0},
{153, 102, 51, 0},
{153, 102, 102, 0},
{153, 102, 153, 0},
{153, 102, 204, 0},
{153, 102, 255, 0},
{153, 153, 0, 0},
{153, 153, 51, 0},
{153, 153, 102, 0},
{153, 153, 153, 0},
{153, 153, 204, 0},
{153, 153, 255, 0},
{153, 204, 0, 0},
{153, 204, 51, 0},
{153, 204, 102, 0},
{153, 204, 153, 0},
{153, 204, 204, 0},
{153, 204, 255, 0},
{153, 255, 0, 0},
{153, 255, 51, 0},
{153, 255, 102, 0},
{153, 255, 153, 0},
{153, 255, 204, 0},
{153, 255, 255, 0},
{204, 0, 0, 0},
{204, 0, 51, 0},
{204, 0, 102, 0},
{204, 0, 153, 0},
{204, 0, 204, 0},
{204, 0, 255, 0},
{204, 51, 0, 0},
{204, 51, 51, 0},
{204, 51, 102, 0},
{204, 51, 153, 0},
{204, 51, 204, 0},
{204, 51, 255, 0},
{204, 102, 0, 0},
{204, 102, 51, 0},
{204, 102, 102, 0},
{204, 102, 153, 0},
{204, 102, 204, 0},
{204, 102, 255, 0},
{204, 153, 0, 0},
{204, 153, 51, 0},
{204, 153, 102, 0},
{204, 153, 153, 0},
{204, 153, 204, 0},
{204, 153, 255, 0},
{204, 204, 0, 0},
{204, 204, 51, 0},
{204, 204, 102, 0},
{204, 204, 153, 0},
{204, 204, 204, 0},
{204, 204, 255, 0},
{204, 255, 0, 0},
{204, 255, 51, 0},
{204, 255, 102, 0},
{204, 255, 153, 0},
{204, 255, 204, 0},
{204, 255, 255, 0},
{255, 0, 0, 0},
{255, 0, 51, 0},
{255, 0, 102, 0},
{255, 0, 153, 0},
{255, 0, 204, 0},
{255, 0, 255, 0},
{255, 51, 0, 0},
{255, 51, 51, 0},
{255, 51, 102, 0},
{255, 51, 153, 0},
{255, 51, 204, 0},
{255, 51, 255, 0},
{255, 102, 0, 0},
{255, 102, 51, 0},
{255, 102, 102, 0},
{255, 102, 153, 0},
{255, 102, 204, 0},
{255, 102, 255, 0},
{255, 153, 0, 0},
{255, 153, 51, 0},
{255, 153, 102, 0},
{255, 153, 153, 0},
{255, 153, 204, 0},
{255, 153, 255, 0},
{255, 204, 0, 0},
{255, 204, 51, 0},
{255, 204, 102, 0},
{255, 204, 153, 0},
{255, 204, 204, 0},
{255, 204, 255, 0},
{255, 255, 0, 0},
{255, 255, 51, 0},
{255, 255, 102, 0},
{255, 255, 153, 0},
{255, 255, 204, 0},
{255, 255, 255, 0},
{ 0, 0, 0, 0},
{ 11, 11, 11, 0},
{ 22, 22, 22, 0},
{ 33, 33, 33, 0},
{ 44, 44, 44, 0},
{ 55, 55, 55, 0},
{ 66, 66, 66, 0},
{ 77, 77, 77, 0},
{ 88, 88, 88, 0},
{ 99, 99, 99, 0},
{110, 110, 110, 0},
{121, 121, 121, 0},
{132, 132, 132, 0},
{143, 143, 143, 0},
{154, 154, 154, 0},
{165, 165, 165, 0},
{176, 176, 176, 0},
{187, 187, 187, 0},
{198, 198, 198, 0},
{209, 209, 209, 0},
{220, 220, 220, 0},
{231, 231, 231, 0},
{242, 242, 242, 0},
{253, 253, 253, 0},
}; };
#define ROWS_DEFAULT 25 #define ROWS_DEFAULT 25