diff --git a/src/apps/terminal/TermApp.cpp b/src/apps/terminal/TermApp.cpp index 002dd5dd78..b936d204ab 100644 --- a/src/apps/terminal/TermApp.cpp +++ b/src/apps/terminal/TermApp.cpp @@ -37,6 +37,7 @@ static bool sUsageRequested = false; //static bool sGeometryRequested = false; +rgb_color TermApp::fDefaultPalette[kTermColorCount]; int main() @@ -57,6 +58,8 @@ TermApp::TermApp() fArgs(NULL) { fArgs = new Arguments(0, NULL); + + _InitDefaultPalette(); } @@ -309,3 +312,43 @@ TermApp::_Usage(char *name) ); } + +void +TermApp::_InitDefaultPalette() +{ + // 0 - 15 are system ANSI colors + const char * keys[kANSIColorCount] = { + PREF_ANSI_BLACK_COLOR, + PREF_ANSI_RED_COLOR, + PREF_ANSI_GREEN_COLOR, + PREF_ANSI_YELLOW_COLOR, + PREF_ANSI_BLUE_COLOR, + PREF_ANSI_MAGENTA_COLOR, + PREF_ANSI_CYAN_COLOR, + PREF_ANSI_WHITE_COLOR, + PREF_ANSI_BLACK_HCOLOR, + PREF_ANSI_RED_HCOLOR, + PREF_ANSI_GREEN_HCOLOR, + PREF_ANSI_YELLOW_HCOLOR, + PREF_ANSI_BLUE_HCOLOR, + PREF_ANSI_MAGENTA_HCOLOR, + PREF_ANSI_CYAN_HCOLOR, + PREF_ANSI_WHITE_HCOLOR + }; + + rgb_color* color = fDefaultPalette; + PrefHandler* handler = PrefHandler::Default(); + for (uint i = 0; i < kANSIColorCount; i++) + *color++ = handler->getRGB(keys[i]); + + // 16 - 231 are 6x6x6 color "cubes" in xterm color model + for (uint red = 0; red < 256; red += (red == 0) ? 95 : 40) + for (uint green = 0; green < 256; green += (green == 0) ? 95 : 40) + for (uint blue = 0; blue < 256; blue += (blue == 0) ? 95 : 40) + (*color++).set_to(red, green, blue); + + // 232 - 255 are grayscale ramp in xterm color model + for (uint gray = 8; gray < 240; gray += 10) + (*color++).set_to(gray, gray, gray); +} + diff --git a/src/apps/terminal/TermApp.h b/src/apps/terminal/TermApp.h index 2f2d287e44..3fe12f1968 100644 --- a/src/apps/terminal/TermApp.h +++ b/src/apps/terminal/TermApp.h @@ -37,6 +37,7 @@ #include #include +#include "Colors.h" class Arguments; class BRect; @@ -48,6 +49,8 @@ public: TermApp(); virtual ~TermApp(); + static const rgb_color* DefaultPalette() + { return fDefaultPalette; } protected: virtual void ReadyToRun(); virtual bool QuitRequested(); @@ -64,13 +67,14 @@ private: static status_t _ChildCleanupThread(void* data); void _Usage(char *name); - + void _InitDefaultPalette(); private: bool fStartFullscreen; BString fWindowTitle; BWindow* fTermWindow; Arguments* fArgs; + static rgb_color fDefaultPalette[kTermColorCount]; }; diff --git a/src/apps/terminal/TermParse.cpp b/src/apps/terminal/TermParse.cpp index 92fb5e3c45..6f912ed2b8 100644 --- a/src/apps/terminal/TermParse.cpp +++ b/src/apps/terminal/TermParse.cpp @@ -892,17 +892,20 @@ TermParse::EscParse() case 38: { - if (nparam == 3 && param[1] == 5) { - attributes &= ~FORECOLOR; - attributes |= FORECOLORED(param[2]); - attributes |= FORESET; + int color = -1; + if (nparam == 3 && param[1] == 5) + color = param[2]; + else if (nparam == 5 && param[1] == 2) + color = fBuffer->GuessPaletteColor( + param[2], param[3], param[4]); - } else if (nparam == 5) { - // TODO lookup + if (color >= 0) { + attributes &= ~FORECOLOR; + attributes |= FORECOLORED(color); + attributes |= FORESET; } row = nparam; // force exit of the parsing - break; } @@ -934,17 +937,20 @@ TermParse::EscParse() case 48: { - if (nparam == 3 && param[1] == 5) { - attributes &= ~BACKCOLOR; - attributes |= BACKCOLORED(param[2]); - attributes |= BACKSET; + int color = -1; + if (nparam == 3 && param[1] == 5) + color = param[2]; + else if (nparam == 5 && param[1] == 2) + color = fBuffer->GuessPaletteColor( + param[2], param[3], param[4]); - } else if (nparam == 5) { - // TODO lookup + if (color >= 0) { + attributes &= ~BACKCOLOR; + attributes |= BACKCOLORED(color); + attributes |= BACKSET; } row = nparam; // force exit of the parsing - break; } diff --git a/src/apps/terminal/TermView.cpp b/src/apps/terminal/TermView.cpp index 33ae11c571..771890dc26 100644 --- a/src/apps/terminal/TermView.cpp +++ b/src/apps/terminal/TermView.cpp @@ -58,6 +58,7 @@ #include "PrefHandler.h" #include "Shell.h" #include "ShellParameters.h" +#include "TermApp.h" #include "TermConst.h" #include "TerminalBuffer.h" #include "TerminalCharClassifier.h" @@ -180,7 +181,6 @@ TermView::TermView(BRect frame, const ShellParameters& shellParameters, fRows(ROWS_DEFAULT), fEncoding(M_UTF8), fActive(false), - fTermColorTable(NULL), fScrBufSize(historySize), fReportX10MouseEvent(false), fReportNormalMouseEvent(false), @@ -204,7 +204,6 @@ TermView::TermView(int rows, int columns, fRows(rows), fEncoding(M_UTF8), fActive(false), - fTermColorTable(NULL), fScrBufSize(historySize), fReportX10MouseEvent(false), fReportNormalMouseEvent(false), @@ -238,7 +237,6 @@ TermView::TermView(BMessage* archive) fRows(ROWS_DEFAULT), fEncoding(M_UTF8), fActive(false), - fTermColorTable(NULL), fScrBufSize(1000), fReportX10MouseEvent(false), fReportNormalMouseEvent(false), @@ -335,17 +333,13 @@ TermView::_InitObject(const ShellParameters& shellParameters) if (fVisibleTextBuffer == NULL) return B_NO_MEMORY; - status_t error = _InitColorTable(); - if (error != B_OK) - return error; - // TODO: Make the special word chars user-settable! fCharClassifier = new(std::nothrow) CharClassifier( kDefaultSpecialWordChars); if (fCharClassifier == NULL) return B_NO_MEMORY; - error = fTextBuffer->Init(fColumns, fRows, fScrBufSize); + status_t error = fTextBuffer->Init(fColumns, fRows, fScrBufSize); if (error != B_OK) return error; fTextBuffer->SetEncoding(fEncoding); @@ -394,7 +388,6 @@ TermView::~TermView() delete fAutoScrollRunner; delete fCharClassifier; delete fVisibleTextBuffer; - delete[] fTermColorTable; delete fTextBuffer; delete shell; } @@ -657,7 +650,7 @@ TermView::SetTermColor(uint index, rgb_color color, bool dynamic) { if (!dynamic) { if (index < kTermColorCount) - fTermColorTable[index] = color; + fTextBuffer->SetPaletteColor(index, color); return; } @@ -670,12 +663,12 @@ TermView::SetTermColor(uint index, rgb_color color, bool dynamic) SetLowColor(fTextBackColor); break; case 110: - fTextForeColor = - PrefHandler::Default()->getRGB(PREF_TEXT_FORE_COLOR); + fTextForeColor = PrefHandler::Default()->getRGB( + PREF_TEXT_FORE_COLOR); break; case 111: - fTextBackColor = - PrefHandler::Default()->getRGB(PREF_TEXT_BACK_COLOR); + fTextBackColor = PrefHandler::Default()->getRGB( + PREF_TEXT_BACK_COLOR); SetLowColor(fTextBackColor); break; default: @@ -951,9 +944,9 @@ TermView::_DrawLinePart(int32 x1, int32 y1, uint32 attr, char *buf, int backcolor = IS_BACKCOLOR(attr); if (IS_FORESET(attr)) - rgb_fore = fTermColorTable[forecolor]; + rgb_fore = fTextBuffer->PaletteColor(forecolor); if (IS_BACKSET(attr)) - rgb_back = fTermColorTable[backcolor]; + rgb_back = fTextBuffer->PaletteColor(backcolor); // printf("DLP:[%03x %03x %03x]; [%03x %03x %03x];\n", // rgb_fore.red, rgb_fore.green, rgb_fore.blue, rgb_back.red, rgb_back.green, rgb_back.blue); @@ -1064,7 +1057,7 @@ TermView::_DrawCursor() fCursor.y - firstVisible); if (IS_BACKSET(attr)) - rgb_back = fTermColorTable[IS_BACKCOLOR(attr)]; + rgb_back = fTextBuffer->PaletteColor(IS_BACKCOLOR(attr)); SetHighColor(rgb_back); } @@ -1272,7 +1265,8 @@ TermView::Draw(BRect updateRect) ? fSelectBackColor : fTextBackColor; if (fTextBuffer->IsAlternateScreenActive()) { - // alternate screen uses cell attributes beyond the line ends + // 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; @@ -1280,8 +1274,11 @@ TermView::Draw(BRect updateRect) } else attr = fVisibleTextBuffer->GetLineColor(j - firstVisible); - if (IS_BACKSET(attr)) - rgb_back = fTermColorTable[IS_BACKCOLOR(attr)]; + if (IS_BACKSET(attr)) { + int backcolor = IS_BACKCOLOR(attr); + rgb_back = fTextBuffer->PaletteColor(backcolor); + } + SetHighColor(rgb_back); rgb_back = HighColor(); FillRect(rect); @@ -1893,7 +1890,8 @@ TermView::MessageReceived(BMessage *msg) break; if (index < kTermColorCount) - SetTermColor(index, fTermColorTable[index], dynamic); + SetTermColor(index, + TermApp::DefaultPalette()[index], dynamic); } break; @@ -3230,51 +3228,6 @@ TermView::_CancelInputMethod() } -status_t -TermView::_InitColorTable() -{ - fTermColorTable = new(std::nothrow) rgb_color[kTermColorCount]; - if (fTermColorTable == NULL) - return B_NO_MEMORY; - - // 0 - 15 are system ANSI colors - const char * keys[kANSIColorCount] = { - PREF_ANSI_BLACK_COLOR, - PREF_ANSI_RED_COLOR, - PREF_ANSI_GREEN_COLOR, - PREF_ANSI_YELLOW_COLOR, - PREF_ANSI_BLUE_COLOR, - PREF_ANSI_MAGENTA_COLOR, - PREF_ANSI_CYAN_COLOR, - PREF_ANSI_WHITE_COLOR, - PREF_ANSI_BLACK_HCOLOR, - PREF_ANSI_RED_HCOLOR, - PREF_ANSI_GREEN_HCOLOR, - PREF_ANSI_YELLOW_HCOLOR, - PREF_ANSI_BLUE_HCOLOR, - PREF_ANSI_MAGENTA_HCOLOR, - PREF_ANSI_CYAN_HCOLOR, - PREF_ANSI_WHITE_HCOLOR - }; - - rgb_color* color = fTermColorTable; - PrefHandler* handler = PrefHandler::Default(); - for (uint i = 0; i < kANSIColorCount; i++) - *color++ = handler->getRGB(keys[i]); - - // 16 - 231 are 6x6x6 color "cubes" in xterm color model - for (uint red = 0; red < 256; red += (red == 0) ? 95 : 40) - for (uint green = 0; green < 256; green += (green == 0) ? 95 : 40) - for (uint blue = 0; blue < 256; blue += (blue == 0) ? 95 : 40) - (*color++).set_to(red, green, blue); - - // 232 - 255 are grayscale ramp in xterm color model - for (uint gray = 8; gray < 240; gray += 10) - (*color++).set_to(gray, gray, gray); - - return B_OK; -} - // #pragma mark - Listener diff --git a/src/apps/terminal/TermView.h b/src/apps/terminal/TermView.h index c47e5cd2c5..ca90d987b4 100644 --- a/src/apps/terminal/TermView.h +++ b/src/apps/terminal/TermView.h @@ -153,7 +153,6 @@ private: status_t _InitObject( const ShellParameters& shellParameters); - status_t _InitColorTable(); status_t _AttachShell(Shell* shell); void _DetachShell(); @@ -274,8 +273,6 @@ private: rgb_color fSelectForeColor; rgb_color fSelectBackColor; - rgb_color* fTermColorTable; - // Scroll Region float fScrollOffset; int32 fScrBufSize; diff --git a/src/apps/terminal/TerminalBuffer.cpp b/src/apps/terminal/TerminalBuffer.cpp index 3f6e456758..e6dae771fd 100644 --- a/src/apps/terminal/TerminalBuffer.cpp +++ b/src/apps/terminal/TerminalBuffer.cpp @@ -9,6 +9,8 @@ #include +#include "Colors.h" +#include "TermApp.h" #include "TermConst.h" @@ -22,6 +24,7 @@ TerminalBuffer::TerminalBuffer() fAlternateScreen(NULL), fAlternateHistory(NULL), fAlternateScreenOffset(0), + fColorsPalette(NULL), fListenerValid(false) { } @@ -31,6 +34,7 @@ TerminalBuffer::~TerminalBuffer() { delete fAlternateScreen; delete fAlternateHistory; + delete[] fColorsPalette; } @@ -47,6 +51,13 @@ TerminalBuffer::Init(int32 width, int32 height, int32 historySize) for (int32 i = 0; i < height; i++) fAlternateScreen[i]->Clear(); + fColorsPalette = new(std::nothrow) rgb_color[kTermColorCount]; + if (fColorsPalette == NULL) + return B_NO_MEMORY; + + memcpy(fColorsPalette, TermApp::DefaultPalette(), + sizeof(rgb_color) * kTermColorCount); + return BasicTerminalBuffer::Init(width, height, historySize); } @@ -211,6 +222,42 @@ TerminalBuffer::SetCursorHidden(bool hidden) } +void +TerminalBuffer::SetPaletteColor(uint8 index, rgb_color color) +{ + if (index < kTermColorCount) + fColorsPalette[index] = color; +} + + +rgb_color +TerminalBuffer::PaletteColor(uint8 index) +{ + return fColorsPalette[min_c(index, kTermColorCount - 1)]; +} + + +int +TerminalBuffer::GuessPaletteColor(int red, int green, int blue) +{ + int distance = 255 * 100; + int index = -1; + for (int 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, kTermColorCount - 1); +} + + void TerminalBuffer::NotifyQuit(int32 reason) { diff --git a/src/apps/terminal/TerminalBuffer.h b/src/apps/terminal/TerminalBuffer.h index a505350f89..56fd38a111 100644 --- a/src/apps/terminal/TerminalBuffer.h +++ b/src/apps/terminal/TerminalBuffer.h @@ -34,6 +34,9 @@ public: void SetCursorStyle(int32 style, bool blinking); 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); void NotifyQuit(int32 reason); @@ -61,6 +64,7 @@ private: TerminalLine** fAlternateScreen; HistoryBuffer* fAlternateHistory; int32 fAlternateScreenOffset; + rgb_color* fColorsPalette; // listener/dirty region management BMessenger fListener;