/*************************************************************************** * * * _____ ____ * * | __ \ / __ \ _ _ _____ * * | | \ \ / / \_\ | | | | _ \ * * | | \ \| | | | | | |_| | * * | | | || | | | | | ___/ * * | | / /| | __ | | | | _ \ * * | |__/ / \ \__/ / | |___| | |_| | * * |_____/ \____/ |_____|_|_____/ * * * * Wiimms source code library * * * *************************************************************************** * * * Copyright (c) 2012-2020 by Dirk Clemens * * * *************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * See file gpl-2.0.txt or http://www.gnu.org/licenses/gpl-2.0.txt * * * ***************************************************************************/ #define _GNU_SOURCE 1 #include #include #include #include #include #include //#include //#include #include "dclib-color.h" #include "dclib-basics.h" #include "dclib-utf8.h" #ifdef DCLIB_TERMINAL #include "dclib-terminal.h" #endif // /////////////////////////////////////////////////////////////////////////////// /////////////// color modes /////////////// /////////////////////////////////////////////////////////////////////////////// const KeywordTab_t color_mode_keywords[] = { { COLMD_OFF, "OFF", "NONE", 0 }, { COLMD_OFF, "NO-COLORS", "NOCOLORS", 0 }, { COLMD_OFF, "0-COLORS", "0COLORS", 0 }, { COLMD_AUTO, "AUTO", 0, 0 }, { COLMD_ON, "ON", 0, 0 }, { COLMD_8_COLORS, "8-COLORS", "8COLORS", 0 }, { COLMD_256_COLORS, "256-COLORS", "256COLORS", 0 }, {0,0,0,0} }; ColorMode_t opt_colorize = COLMD_AUTO; /////////////////////////////////////////////////////////////////////////////// int ScanOptColorize ( ColorMode_t *opt, ccp arg, ccp err_prefix ) { if (!opt) opt = &opt_colorize; if (!arg) { if ( *opt < COLMD_ON ) *opt = COLMD_ON; return 0; } int abbrev; const KeywordTab_t *key = ScanKeyword(&abbrev,arg,color_mode_keywords); if (!key) return PrintKeywordError( color_mode_keywords, arg, abbrev, err_prefix ? err_prefix : "Option --color: ", "keyword"); *opt = key->id; return 0; } /////////////////////////////////////////////////////////////////////////////// ccp GetColorModeName ( ColorMode_t col_mode, ccp res_not_found ) { return GetKewordNameById(color_mode_keywords,col_mode,res_not_found); } /////////////////////////////////////////////////////////////////////////////// ColorMode_t NormalizeColorMode ( ColorMode_t col_mode, int n_colors ) { // returns COLMD_OFF or COLMD_8_COLORS or COLMD_256_COLORS switch (col_mode) { case COLMD_OFF: case COLMD_8_COLORS: case COLMD_256_COLORS: return col_mode; case COLMD_ON: return n_colors < 256 ? COLMD_8_COLORS : COLMD_256_COLORS; default: //case COLMD_AUTO: return n_colors < 8 ? COLMD_OFF : n_colors < 256 ? COLMD_8_COLORS : COLMD_256_COLORS; } } /////////////////////////////////////////////////////////////////////////////// ColorMode_t NormalizeColorModeByTermName ( ColorMode_t col_mode, // predefind mode ccp term_name // find "256color" in terminal name. // if NULL: use getenv("TERM") // assume 8 or 256 colors! ) { if (!term_name) term_name = getenv("TERM"); const int n_colors = term_name && strstr(term_name,"256color") ? 256 : 8; return NormalizeColorMode(col_mode,n_colors); } /////////////////////////////////////////////////////////////////////////////// ColorMode_t GetNextColorMode ( ColorMode_t col_mode ) { switch(col_mode) { case COLMD_8_COLORS: return COLMD_256_COLORS; case COLMD_256_COLORS: return COLMD_OFF; default: return COLMD_8_COLORS; } } /////////////////////////////////////////////////////////////////////////////// ColorMode_t GetPrevColorMode ( ColorMode_t col_mode ) { switch(col_mode) { case COLMD_8_COLORS: return COLMD_OFF; case COLMD_256_COLORS: return COLMD_8_COLORS; default: return COLMD_256_COLORS; } } // /////////////////////////////////////////////////////////////////////////////// /////////////// print lines with autobreak /////////////// /////////////////////////////////////////////////////////////////////////////// void PutLines ( FILE * f, // valid output stream int indent, // indent of output int fw, // field width of output int first_line, // length without prefix of already printed first line ccp prefix, // NULL or prefix for each line ccp text, // text to print ccp eol // End Of Line test. If NULL -> LF ) { DASSERT(f); DASSERT( indent >= 0 ); if (!prefix) prefix = ""; if (!eol) eol = "\n"; TRACE("PutLines(,%d,%d,%d,%.10s,%.20s)\n",indent,fw,first_line,prefix,text); fw -= strlen(prefix); if ( fw < 10 ) fw = 10; ccp prefix1 = ""; int indent1, fw1; if ( indent > first_line ) { indent1 = indent - first_line; fw1 = fw - indent; } else { indent1 = 0; fw1 = fw - first_line; } fw -= indent; if ( fw < 20 ) fw = 20; if ( fw1 < 20 ) { fputs(eol,f); indent1 = indent; fw1 = fw; prefix1 = prefix; } while ( *text ) { // skip blank and control if ( *text == '\n' ) { // don't skip spaces behind a LF ==> needed for tables while ( *text > 0 && *text < ' ' ) text++; } else { // but ignore spaces on an automatic line break while ( *text > 0 && *text <= ' ' ) text++; } // setup ccp start = text, last_blank = text; ccp max = text + fw1; while ( text < max && *text && *text != '\n' ) { if ( *text > 0 && *text <= ' ' ) last_blank = text; text++; } // set back to last blank if ( last_blank > start && (u8)*text > ' ' ) text = last_blank; // print out if ( *text || text > start ) fprintf(f,"%s%*s%.*s%s", prefix1, indent1, "", (int)(text-start), start, eol ); // use standard values for next lines indent1 = indent; fw1 = fw; prefix1 = prefix; } } /////////////////////////////////////////////////////////////////////////////// void PrintArgLines ( FILE * f, // valid output stream int indent, // indent of output int fw, // field width of output int first_line, // length without prefix of already printed first line ccp prefix, // NULL or prefix for each line ccp format, // format string for vsnprintf() va_list arg // parameters for 'format' ) { DASSERT(f); DASSERT(format); char buf[10000]; va_list arg2; va_copy(arg2,arg); int stat = vsnprintf(buf,sizeof(buf),format,arg2); va_end(arg2); if ( stat < sizeof(buf) ) { PutLines(f,indent,fw,first_line,prefix,buf,0); return; } //--- buffer too small, use dynamic memory noPRINT("PrintArgGrowBuffer() -> MALLOC(%u)\n",stat+1); char *temp = MALLOC(stat+1); vsnprintf(temp,stat+1,format,arg); va_end(arg); PutLines(f,indent,fw,first_line,prefix,temp,0); FREE(temp); } /////////////////////////////////////////////////////////////////////////////// void PrintLines ( FILE * f, // valid output stream int indent, // indent of output int fw, // field width of output int first_line, // length without prefix of already printed first line ccp prefix, // NULL or prefix for each line ccp format, // format string for vsnprintf() ... // arguments for 'vsnprintf(format,...)' ) { DASSERT(f); DASSERT(format); va_list arg; va_start(arg,format); PrintArgLines(f,indent,fw,first_line,prefix,format,arg); va_end(arg); } // /////////////////////////////////////////////////////////////////////////////// /////////////// print colored lines with autobreak /////////////// /////////////////////////////////////////////////////////////////////////////// uint PutColoredLines ( // returns the number of written lines FILE * f, // valid output stream const ColorSet_t *colset, // NULL or color set int indent, // indent of output int fw, // field width; indent+prefix+eol don't count ccp prefix, // NULL or prefix for each line ccp eol, // End Of Line test. If NULL -> LF ccp text // text to print ) { DASSERT(f); DASSERT(text); //--- normalize params indent = NormalizeIndent(indent); if ( fw < 1 || fw > 1000 ) fw = 1000; else if ( fw < 20 ) fw = 20; if (!eol) eol = "\n"; if (!prefix) prefix = ""; indent += strlen(prefix); if (!colset) colset = GetFileColorSet(f); //--- setup tabs u8 is_tab[200]; memset(is_tab,0,sizeof(is_tab)); //--- prepare output buffer char buf[10000]; char *buf_end = buf + 3*sizeof(buf)/4; int cont_indent = -1; uint n_lines = 0, n_space = 0; uint column = 0; //ccp col_begin = ""; enum { GB_NONE, GB_SIGN, GB_COMMA, GB_SPACE } gb_mode = GB_NONE; struct gb_save_t { ccp text; // text position before code assignment char *dest; // destination ccp col_active; // NULL or active color by last "{name}" ccp col_embed; // NULL or active color "{name|text}" }; struct gb_save_t cur = { text, buf, 0, 0 }; struct gb_save_t save = cur; // only valid if gb_mode != GB_NONE //--- main loop for(;;) { #ifdef TEST if ( n_lines > 1000 ) return n_lines; #endif cur.text = text; u32 code = ScanUTF8AnsiChar(&text); switch(code) { case 0: if (!column) return n_lines; // fall through case '\r': if ( *text == '\n' ) code = *text++; // fall through case '\n': cur.text = text; new_line: *cur.dest = 0; fprintf(f,"%-*s%s%s%s", indent,prefix, buf, cur.col_active || cur.col_embed ? colset->reset : "", eol ); cur.dest = buf; text = cur.text; n_lines++; column = 0; n_space = 0; gb_mode = GB_NONE; if ( code == '\n' ) cont_indent = -1; else if (!code) return n_lines; else if ( cont_indent > 0 ) n_space = cont_indent; if ( cur.col_embed ) cur.dest = StringCopyE(cur.dest,buf+sizeof(buf),cur.col_embed); else if ( cur.col_active ) cur.dest = StringCopyE(cur.dest,buf+sizeof(buf),cur.col_active); break; case '{': if ( *text == '{' ) { text++; goto is_char; } else if ( *text == '}' ) { cur.dest = StringCopyE(cur.dest,buf+sizeof(buf),colset->reset); cur.col_active = cur.col_embed = 0; text++; } else { ccp name = text; while ( *text && *text != '|' && *text != '}' ) text++; if (!*text) break; ccp col = ""; char namebuf[20]; const uint nlen = text - name; if ( nlen < sizeof(namebuf) ) { memcpy(namebuf,name,nlen); namebuf[nlen] = 0; col = GetColorByName(colset,namebuf); } if (*col) { cur.dest = StringCopyE(cur.dest,buf+sizeof(buf),col); if ( *text == '}' ) cur.col_active = col; else cur.col_embed = col; } else if ( *text == '|' ) cur.col_embed = ""; // to detect the closing '}' text++; } break; case '}': if (!cur.col_embed) goto is_char; cur.col_embed = 0; cur.dest = StringCopyE(cur.dest,buf+sizeof(buf), cur.col_active ? cur.col_active : colset->reset ); break; case '\t': case ' ': if ( !n_space++ && column ) { gb_mode = column < fw/2 ? GB_COMMA : GB_SPACE; save = cur; } if ( code == '\t' ) { uint pos; for ( pos = column + n_space; pos < sizeof(is_tab); pos++ ) if (is_tab[pos]) { n_space = pos - column; break; } } break; case '|': if ( *text == '|' ) { text++; goto is_char; } else if ( *text == '+' ) { text++; uint pos = column + n_space; if ( pos < sizeof(is_tab) ) is_tab[pos] = 1; } else if ( *text == '-' ) { uint pos = column + n_space; if ( pos < sizeof(is_tab) ) is_tab[pos] = 0; } else if ( *text == '[' ) { text++; memset(is_tab,0,sizeof(is_tab)); for(;;) { while ( *text == ',' ) text++; char *end; uint num = str2ul(text,&end,10); if ( text == end ) break; text = end; if ( num < sizeof(is_tab) ) is_tab[num] = 1; if ( *text == '*' ) { text++; uint delta = str2ul(text,&end,10); if ( text == end ) break; if ( delta > 0 ) for ( ; num < sizeof(is_tab); num += delta ) is_tab[num] = 1; } } if ( *text == ']' ) text++; //HexDump16(stderr,0,0,is_tab,sizeof(is_tab)); } else { if ( *text == '>' ) text++; cont_indent = column + n_space; if ( cont_indent > fw/2 ) cont_indent = fw/2; } break; case '+': case '-': case '=': case '/': if ( gb_mode <= GB_SIGN ) { gb_mode = GB_SIGN; save = cur; } // fall through default: is_char: column += n_space; if ( column >= fw ) { // auto break line if ( gb_mode > GB_NONE ) cur = save; while ( *cur.text == ' ' ) cur.text++; goto new_line; } while ( n_space > 0 ) *cur.dest++ = ' ', n_space--; cur.dest = PrintUTF8Char(cur.dest,code); if ( cur.dest > buf_end ) goto new_line; // should never happen! column++; if ( gb_mode <= GB_COMMA && ( code == ',' || code == ';' )) { gb_mode = GB_COMMA; save = cur; save.text++; } break; } } } /////////////////////////////////////////////////////////////////////////////// uint PrintArgColoredLines ( // returns the number of written lines FILE * f, // valid output stream const ColorSet_t *colset, // NULL or color set int indent, // indent of output int fw, // field width; indent+prefix+eol don't count ccp prefix, // NULL or prefix for each line ccp eol, // End Of Line test. If NULL -> LF ccp format, // format string for vsnprintf() va_list arg // parameters for 'format' ) { DASSERT(f); DASSERT(format); char buf[10000]; va_list arg2; va_copy(arg2,arg); int stat = vsnprintf(buf,sizeof(buf),format,arg2); va_end(arg2); if ( stat < sizeof(buf) ) return PutColoredLines(f,colset,indent,fw,prefix,eol,buf); //--- buffer too small, use dynamic memory noPRINT("PrintArgGrowBuffer() -> MALLOC(%u)\n",stat+1); char *temp = MALLOC(stat+1); stat = vsnprintf(temp,stat+1,format,arg); const uint res = PutColoredLines(f,colset,indent,fw,prefix,eol,temp); FREE(temp); return res; } /////////////////////////////////////////////////////////////////////////////// uint PrintColoredLines ( // returns the number of written lines FILE * f, // valid output stream const ColorSet_t *colset, // NULL or color set int indent, // indent of output int fw, // field width; indent+prefix+eol don't count ccp prefix, // NULL or prefix for each line ccp eol, // End Of Line test. If NULL -> LF ccp format, // format string for vsnprintf() ... // arguments for 'vsnprintf(format,...)' ) { DASSERT(f); DASSERT(format); va_list arg; va_start(arg,format); const uint res = PrintArgColoredLines(f,colset,indent,fw,prefix,eol,format,arg); va_end(arg); return res; } // /////////////////////////////////////////////////////////////////////////////// /////////////// terminal /////////////// /////////////////////////////////////////////////////////////////////////////// // Sequence counter for output to stdout (and stderr). // Functions shall increment it on output, so that other functions // know about a destroyed screen. uint stdout_seq_count = 0; /////////////////////////////////////////////////////////////////////////////// uint opt_width = 0; uint opt_height = 0; int ScanOptWidth ( ccp arg ) { return ERR_OK != ScanSizeOptU32( &opt_width, // u32 * num arg, // ccp source 1, // default_factor1 0, // int force_base "width", // ccp opt_name 40, // u64 min 10000, // u64 max 1, // u32 multiple 0, // u32 pow2 true // bool print_err ); } int ScanOptHeight ( ccp arg ) { return ERR_OK != ScanSizeOptU32( &opt_height, // u32 * num arg, // ccp source 1, // default_factor1 0, // int force_base "height", // ccp opt_name 40, // u64 min 10000, // u64 max 1, // u32 multiple 0, // u32 pow2 true // bool print_err ); } /////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// term_size_t GetTermSize ( int default_width, int default_height ) { TRACE("GetTermWidth(%d,%d) opt=%d,%d\n", default_width, default_height, opt_width, opt_height ); term_size_t ts; if ( opt_width > 0 && opt_height > 0 ) { ts.width = opt_width; ts.height = opt_height; } else { ts = GetTermSizeFD(STDOUT_FILENO,default_width,default_height); if ( opt_width > 0 ) ts.width = opt_width; if ( opt_height > 0 ) ts.height = opt_height; } return ts; } /////////////////////////////////////////////////////////////////////////////// term_size_t GetTermSizeFD ( int fd, int default_width, int default_height ) { PRINT("GetTermSizeFD(%d,%d,%d)\n",fd,default_width,default_height); #ifdef TIOCGSIZE TRACE(" - have TIOCGSIZE\n"); #endif #ifdef TIOCGWINSZ TRACE(" - have TIOCGWINSZ\n"); #endif #ifndef WIN_SZS_LIB if (isatty(fd)) { TRACE(" - isatty\n"); #ifdef TIOCGSIZE { struct ttysize ts; if ( !ioctl(fd,TIOCGSIZE,&ts)) { PRINT(" - TIOCGSIZE = %d*%d\n",ts.ts_cols,ts.ts_lines); if ( ts.ts_cols > 0 && ts.ts_lines > 0 ) { term_size_t tes = {ts.ts_cols,ts.ts_lines}; return tes; } } } #endif #ifdef TIOCGWINSZ { struct winsize ws; if ( !ioctl(fd,TIOCGWINSZ,&ws)) { PRINT(" - TIOCGWINSZ = %d*%d\n",ws.ws_col,ws.ws_row); if ( ws.ws_col > 0 && ws.ws_row > 0 ) { term_size_t ts = {ws.ws_col,ws.ws_row}; return ts; } } } #endif } #endif term_size_t ts = {default_width,default_height}; return ts; } /////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// int GetTermWidth ( int default_value, int min_value ) { TRACE("GetTermWidth(%d,%d) opt=%d\n",default_value,min_value,opt_width); int term_width = opt_width > 0 ? opt_width : GetTermWidthFD(STDOUT_FILENO,-1,min_value); return term_width > 0 ? term_width : default_value; } /////////////////////////////////////////////////////////////////////////////// int GetTermWidthFD ( int fd, int default_value, int min_value ) { TRACE("GetTermWidthFD(%d,%d,%d)\n",fd,default_value,min_value); term_size_t ts = GetTermSizeFD(fd,default_value,25); return ts.width > min_value ? ts.width : min_value; } /////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// int GetTermHeight ( int default_value, int min_value ) { TRACE("GetTermHeight(%d,%d) opt=%d\n",default_value,min_value,opt_height); int term_height = opt_height > 0 ? opt_height : GetTermHeightFD(STDOUT_FILENO,-1,min_value); return term_height > 0 ? term_height : default_value; } /////////////////////////////////////////////////////////////////////////////// int GetTermHeightFD ( int fd, int default_value, int min_value ) { TRACE("GetTermHeightFD(%d,%d,%d)\n",fd,default_value,min_value); term_size_t ts = GetTermSizeFD(fd,default_value,25); return ts.height > min_value ? ts.height : min_value; } /////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// term_size_t auto_term_size = {80,25}; uint auto_term_resized = 0; // incremented for each resize, init by 0 uint auto_term_size_dirty = 0; // >0: SIGWINCH received, auto_term_size is dirty //----------------------------------------------------------------------------- bool GetAutoTermSize() { // return true if changed auto_term_size_dirty = 0; int fd = isatty(1) ? 1 : isatty(0) ? 0 : -1; if ( fd >= 0 ) { term_size_t size = GetTermSizeFD(fd,auto_term_size.width,auto_term_size.height); if (memcmp(&auto_term_size,&size,sizeof(size))) { auto_term_size = size; if (!++auto_term_resized) auto_term_resized++; return true; } } return false; } //----------------------------------------------------------------------------- static void Signal_SIGWINCH ( int signal ) { if (!++auto_term_size_dirty) auto_term_size_dirty++; } void EnableAutoTermSize() { signal(SIGWINCH,Signal_SIGWINCH); GetAutoTermSize(); } // /////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// ccp TermCursorUp = TERM_CURSOR_UP; // move cursor up ccp TermCursorDown = TERM_CURSOR_DOWN; // move cursor down ccp TermCursorRight = TERM_CURSOR_RIGHT; // move cursor right ccp TermCursorLeft = TERM_CURSOR_LEFT; // move cursor left ccp TermCursorUpN = TERM_CURSOR_UP_N; // move cursor N* up (format 1 '%d') ccp TermCursorDownN = TERM_CURSOR_DOWN_N; // move cursor N* down (format 1 '%d') ccp TermCursorRightN = TERM_CURSOR_RIGHT_N; // move cursor N* right (format 1 '%d') ccp TermCursorLeftN = TERM_CURSOR_LEFT_N; // move cursor N* left (format 1 '%d') ccp TermClearEOL = TERM_CLEAR_EOL; // clear from cursor to end of line ccp TermClearBOL = TERM_CLEAR_BOL; // clear from beginning of line to cursor ccp TermClearLine = TERM_CLEAR_LINE; // clear entire line ccp TermClearEOD = TERM_CLEAR_EOD; // clear from cursor to end of display ccp TermClearBOD = TERM_CLEAR_BOD; // clear from beginning of display to cursor ccp TermClearDisplay = TERM_CLEAR_DISPLAY; // clear Entire display ccp TermSetWrap = TERM_SET_WRAP; // enabled line wrapping ccp TermResetWrap = TERM_RESET_WRAP; // disable line wrapping ccp TermTextModeBeg = TERM_TEXT_MODE_BEG; // begin of text mode sequence ccp TermTextModeEnd = TERM_TEXT_MODE_END; // end of text mode sequence ccp TermTextModeReset = TERM_TEXT_MODE_RESET; // reset text mode static uint grayscale_tab[4] = {0,8,7,15}; #if SUPPORT_36_COLORS const char ColorIndexName[TCI__N][16] = { "black", "dark_gray_1", "dark_gray_2", "dark_gray_3", "light_gray_1", "light_gray_2", "light_gray_3", "white", "red", "red_orange", "orange", "orange_yellow", "yellow", "yellow_green", "green", "green_cyan", "cyan", "cyan_blue", "blue", "blue_magenta", "magenta", "magenta_red", "b_red", "b_red_orange", "b_orange", "b_orange_yellow", "b_yellow", "b_yellow_green", "b_green", "b_green_cyan", "b_cyan", "b_cyan_blue", "b_blue", "b_blue_magenta", "b_magenta", "b_magenta_red", }; #else // !SUPPORT_36_COLORS const char ColorIndexName[TCI__N][11] = { "black", "dark gray", "light gray", "white", "red", "orange", "yellow", "green", "cyan", "blue", "magenta", "b_red", "b_orange", "b_yellow", "b_green", "b_cyan", "b_blue", "b_magenta", }; #endif // !SUPPORT_36_COLORS const int Color18Index[18+1] = // 18 elements + -1 as terminator { TCI_BLACK, // gray scale TCI_DARKGRAY, TCI_LIGHTGRAY, TCI_WHITE, TCI_RED, // normal colors in rainbow order TCI_ORANGE, TCI_YELLOW, TCI_GREEN, TCI_CYAN, TCI_BLUE, TCI_MAGENTA, TCI_B_RED, // bold colors in rainbow order TCI_B_ORANGE, TCI_B_YELLOW, TCI_B_GREEN, TCI_B_CYAN, TCI_B_BLUE, TCI_B_MAGENTA, -1 }; /////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// static char * GetColorCircBuf ( uint len ) { static char circ_buf[1024]; static char *circ_ptr = circ_buf; DASSERT( circ_ptr >= circ_buf && circ_ptr <= circ_buf + sizeof(circ_buf) ); if ( len > sizeof(circ_buf)/8 ) return GetCircBuf(len); if ( circ_buf + sizeof(circ_buf) - circ_ptr < len ) circ_ptr = circ_buf; char *buf = circ_ptr; circ_ptr += len; DASSERT( circ_ptr >= circ_buf && circ_ptr <= circ_buf + sizeof(circ_buf) ); return buf; } //----------------------------------------------------------------------------- ccp GetTextMode ( // returns a pointer to an internal circulary buffer (not GetCircBuf()) ColorMode_t col_mode, // if < COLMD_ON: return an empty string TermTextMode_t mode // mode for text generation ) { if ( col_mode < COLMD_ON ) return EmptyString; if ( mode == TTM_RESET ) return TermTextModeReset; uint len = strlen(TermTextModeBeg) + strlen(TermTextModeEnd) + 2; if ( mode & TTM_F_COLOR ) len += 3; else if ( mode & TTM_F_GRAYSCALE ) len += 8; if ( mode & TTM_F_BG_COLOR ) len += 3; else if ( mode & TTM_F_BG_GRAYSCALE ) len += 8; if ( mode & TTM_RESET ) len += 2; if ( mode & (TTM_BOLD|TTM_NO_BOLD) ) len += 3; if ( mode & (TTM_UL|TTM_NO_UL) ) len += 3; //--- use a private circulary buffer (long term valid) char *buf = GetColorCircBuf(len); //--- compose string uint sep = 0; char *end = buf + len; char *dest = StringCopyS(buf,len,TermTextModeBeg); if ( mode & TTM_RESET ) { *dest++ = '0'; sep++; } if ( mode & TTM_BOLD ) { if (sep++) *dest++ = ';'; *dest++ = '1'; } else if ( mode & TTM_NO_BOLD ) { if (sep++) *dest++ = ';'; *dest++ = '2'; *dest++ = '2'; } if ( mode & TTM_UL ) { if (sep++) *dest++ = ';'; *dest++ = '4'; } else if ( mode & TTM_NO_UL ) { if (sep++) *dest++ = ';'; *dest++ = '2'; *dest++ = '4'; } if ( mode & TTM_F_COLOR ) { if (sep++) *dest++ = ';'; dest = snprintfE(dest,end,"%u",(mode&TTM_M_COLOR)+30); } else if ( mode & TTM_F_GRAYSCALE ) { if (sep++) *dest++ = ';'; dest = snprintfE(dest,end,"38;5;%u", grayscale_tab[ mode & TTM_M_GRAYSCALE ]); } if ( mode & TTM_F_BG_COLOR ) { if (sep++) *dest++ = ';'; dest = snprintfE(dest,end,"%u",((mode&TTM_M_BG_COLOR)>>TTM_SHIFT_BG)+40); } else if ( mode & TTM_F_BG_GRAYSCALE ) { if (sep++) *dest++ = ';'; dest = snprintfE(dest,end,"48;5;%u", grayscale_tab[ (mode & TTM_M_BG_GRAYSCALE) >> TTM_SHIFT_BG ]); } StringCopyE(dest,end,TermTextModeEnd); return buf; } // /////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// #if SUPPORT_36_COLORS ccp GetColorMode // 36 colors version ( // returns a pointer to an internal circulary buffer (not GetCircBuf()) ColorMode_t col_mode, // if < COLMD_ON: return an empty string TermColorIndex_t font_index, // index of font color TermColorIndex_t bg_index, // index of background color GetColorOption_t option // execution options ) { col_mode = NormalizeColorMode(col_mode,8); if ( col_mode < COLMD_ON ) return EmptyString; //--- recommended combinations if ( option & GCM_ALT && (uint)font_index < TCI__IGNORE && (uint)bg_index < TCI__IGNORE ) { static const u8 tab[TCI__N_BG][TCI__N_FONT] = { //--- TCI_GRAY0 = TCI_BLACK { TCI_GRAY2, // TCI_GRAY0 = TCI_BLACK TCI_GRAY2, // TCI_GRAY1 TCI_GRAY3, // TCI_GRAY2 = TCI_DARKGRAY TCI_GRAY3, // TCI_GRAY3 TCI_GRAY4, // TCI_GRAY4 TCI_GRAY5, // TCI_GRAY5 = TCI_LIGHTGRAY TCI_GRAY6, // TCI_GRAY6 TCI_GRAY7, // TCI_GRAY7 = TCI_WHITE TCI_B_RED, // TCI_RED TCI_B_RED_ORANGE, // TCI_RED_ORANGE TCI_B_ORANGE, // TCI_ORANGE TCI_B_ORANGE_YELLOW, // TCI_ORANGE_YELLOW TCI_B_YELLOW, // TCI_YELLOW TCI_B_YELLOW_GREEN, // TCI_YELLOW_GREEN TCI_B_GREEN, // TCI_GREEN TCI_B_GREEN_CYAN, // TCI_GREEN_CYAN TCI_B_CYAN, // TCI_CYAN TCI_B_CYAN_BLUE, // TCI_CYAN_BLUE TCI_B_BLUE, // TCI_BLUE TCI_B_BLUE_MAGENTA, // TCI_BLUE_MAGENTA TCI_B_MAGENTA, // TCI_MAGENTA TCI_B_MAGENTA_RED, // TCI_MAGENTA_RED }, //--- TCI_GRAY1 { TCI_GRAY3, // TCI_GRAY0 = TCI_BLACK TCI_GRAY3, // TCI_GRAY1 TCI_GRAY4, // TCI_GRAY2 = TCI_DARKGRAY TCI_GRAY4, // TCI_GRAY3 TCI_GRAY5, // TCI_GRAY4 TCI_GRAY5, // TCI_GRAY5 = TCI_LIGHTGRAY TCI_GRAY6, // TCI_GRAY6 TCI_GRAY7, // TCI_GRAY7 = TCI_WHITE TCI_B_RED, // TCI_RED TCI_B_RED_ORANGE, // TCI_RED_ORANGE TCI_B_ORANGE, // TCI_ORANGE TCI_B_ORANGE_YELLOW, // TCI_ORANGE_YELLOW TCI_B_YELLOW, // TCI_YELLOW TCI_B_YELLOW_GREEN, // TCI_YELLOW_GREEN TCI_B_GREEN, // TCI_GREEN TCI_B_GREEN_CYAN, // TCI_GREEN_CYAN TCI_B_CYAN, // TCI_CYAN TCI_B_CYAN_BLUE, // TCI_CYAN_BLUE TCI_B_BLUE, // TCI_BLUE TCI_B_BLUE_MAGENTA, // TCI_BLUE_MAGENTA TCI_B_MAGENTA, // TCI_MAGENTA TCI_B_MAGENTA_RED, // TCI_MAGENTA_RED }, //--- TCI_GRAY2 = TCI_DARKGRAY { TCI_GRAY0, // TCI_GRAY0 = TCI_BLACK TCI_GRAY0, // TCI_GRAY1 TCI_GRAY0, // TCI_GRAY2 = TCI_DARKGRAY TCI_GRAY4, // TCI_GRAY3 TCI_GRAY4, // TCI_GRAY4 TCI_GRAY5, // TCI_GRAY5 = TCI_LIGHTGRAY TCI_GRAY6, // TCI_GRAY6 TCI_GRAY7, // TCI_GRAY7 = TCI_WHITE TCI_B_RED, // TCI_RED TCI_B_RED_ORANGE, // TCI_RED_ORANGE TCI_B_ORANGE, // TCI_ORANGE TCI_B_ORANGE_YELLOW, // TCI_ORANGE_YELLOW TCI_B_YELLOW, // TCI_YELLOW TCI_B_YELLOW_GREEN, // TCI_YELLOW_GREEN TCI_B_GREEN, // TCI_GREEN TCI_B_GREEN_CYAN, // TCI_GREEN_CYAN TCI_B_CYAN, // TCI_CYAN TCI_B_CYAN_BLUE, // TCI_CYAN_BLUE TCI_B_BLUE, // TCI_BLUE TCI_B_BLUE_MAGENTA, // TCI_BLUE_MAGENTA TCI_B_MAGENTA, // TCI_MAGENTA TCI_B_MAGENTA_RED, // TCI_MAGENTA_RED }, //--- TCI_GRAY3 { TCI_GRAY0, // TCI_GRAY0 = TCI_BLACK TCI_GRAY0, // TCI_GRAY1 TCI_GRAY1, // TCI_GRAY2 = TCI_DARKGRAY TCI_GRAY1, // TCI_GRAY3 TCI_GRAY5, // TCI_GRAY4 TCI_GRAY5, // TCI_GRAY5 = TCI_LIGHTGRAY TCI_GRAY6, // TCI_GRAY6 TCI_GRAY7, // TCI_GRAY7 = TCI_WHITE TCI_B_RED, // TCI_RED TCI_B_RED_ORANGE, // TCI_RED_ORANGE TCI_B_ORANGE, // TCI_ORANGE TCI_B_ORANGE_YELLOW, // TCI_ORANGE_YELLOW TCI_B_YELLOW, // TCI_YELLOW TCI_B_YELLOW_GREEN, // TCI_YELLOW_GREEN TCI_B_GREEN, // TCI_GREEN TCI_B_GREEN_CYAN, // TCI_GREEN_CYAN TCI_B_CYAN, // TCI_CYAN TCI_B_CYAN_BLUE, // TCI_CYAN_BLUE TCI_B_BLUE, // TCI_BLUE TCI_B_BLUE_MAGENTA, // TCI_BLUE_MAGENTA TCI_B_MAGENTA, // TCI_MAGENTA TCI_B_MAGENTA_RED, // TCI_MAGENTA_RED }, //--- TCI_GRAY4 = TCI_LIGHTGRAY { TCI_GRAY0, // TCI_GRAY0 = TCI_BLACK TCI_GRAY1, // TCI_GRAY1 TCI_GRAY1, // TCI_GRAY2 = TCI_DARKGRAY TCI_GRAY2, // TCI_GRAY3 TCI_GRAY2, // TCI_GRAY4 TCI_GRAY6, // TCI_GRAY5 = TCI_LIGHTGRAY TCI_GRAY6, // TCI_GRAY6 TCI_GRAY7, // TCI_GRAY7 = TCI_WHITE TCI_RED, // TCI_RED TCI_RED_ORANGE, // TCI_RED_ORANGE TCI_B_ORANGE, // TCI_ORANGE TCI_B_ORANGE_YELLOW, // TCI_ORANGE_YELLOW TCI_B_YELLOW, // TCI_YELLOW TCI_B_YELLOW_GREEN, // TCI_YELLOW_GREEN TCI_B_GREEN, // TCI_GREEN TCI_B_GREEN_CYAN, // TCI_GREEN_CYAN TCI_B_CYAN, // TCI_CYAN TCI_CYAN_BLUE, // TCI_CYAN_BLUE TCI_BLUE, // TCI_BLUE TCI_BLUE_MAGENTA, // TCI_BLUE_MAGENTA TCI_MAGENTA, // TCI_MAGENTA TCI_MAGENTA_RED, // TCI_MAGENTA_RED }, //--- TCI_GRAY5 = TCI_LIGHTGRAY { TCI_GRAY0, // TCI_GRAY0 = TCI_BLACK TCI_GRAY1, // TCI_GRAY1 TCI_GRAY2, // TCI_GRAY2 = TCI_DARKGRAY TCI_GRAY2, // TCI_GRAY3 TCI_GRAY3, // TCI_GRAY4 TCI_GRAY3, // TCI_GRAY5 = TCI_LIGHTGRAY TCI_GRAY7, // TCI_GRAY6 TCI_GRAY7, // TCI_GRAY7 = TCI_WHITE TCI_RED, // TCI_RED TCI_RED_ORANGE, // TCI_RED_ORANGE TCI_ORANGE, // TCI_ORANGE TCI_ORANGE_YELLOW, // TCI_ORANGE_YELLOW TCI_B_YELLOW, // TCI_YELLOW TCI_B_YELLOW_GREEN, // TCI_YELLOW_GREEN TCI_B_GREEN, // TCI_GREEN TCI_B_GREEN_CYAN, // TCI_GREEN_CYAN TCI_B_CYAN, // TCI_CYAN TCI_CYAN_BLUE, // TCI_CYAN_BLUE TCI_BLUE, // TCI_BLUE TCI_BLUE_MAGENTA, // TCI_BLUE_MAGENTA TCI_MAGENTA, // TCI_MAGENTA TCI_MAGENTA_RED, // TCI_MAGENTA_RED }, //--- TCI_GRAY6 { TCI_GRAY0, // TCI_GRAY0 = TCI_BLACK TCI_GRAY1, // TCI_GRAY1 TCI_GRAY2, // TCI_GRAY2 = TCI_DARKGRAY TCI_GRAY2, // TCI_GRAY3 TCI_GRAY3, // TCI_GRAY4 TCI_GRAY3, // TCI_GRAY5 = TCI_LIGHTGRAY TCI_GRAY4, // TCI_GRAY6 TCI_GRAY4, // TCI_GRAY7 = TCI_WHITE TCI_RED, // TCI_RED TCI_RED_ORANGE, // TCI_RED_ORANGE TCI_ORANGE, // TCI_ORANGE TCI_ORANGE_YELLOW, // TCI_ORANGE_YELLOW TCI_ORANGE_YELLOW, // TCI_YELLOW TCI_YELLOW_GREEN, // TCI_YELLOW_GREEN TCI_GREEN, // TCI_GREEN TCI_GREEN_CYAN, // TCI_GREEN_CYAN TCI_CYAN, // TCI_CYAN TCI_CYAN_BLUE, // TCI_CYAN_BLUE TCI_BLUE, // TCI_BLUE TCI_BLUE_MAGENTA, // TCI_BLUE_MAGENTA TCI_MAGENTA, // TCI_MAGENTA TCI_MAGENTA_RED, // TCI_MAGENTA_RED }, //--- TCI_GRAY7 = TCI_WHITE { TCI_GRAY0, // TCI_GRAY0 = TCI_BLACK TCI_GRAY1, // TCI_GRAY1 TCI_GRAY2, // TCI_GRAY2 = TCI_DARKGRAY TCI_GRAY3, // TCI_GRAY3 TCI_GRAY4, // TCI_GRAY4 TCI_GRAY4, // TCI_GRAY5 = TCI_LIGHTGRAY TCI_GRAY5, // TCI_GRAY6 TCI_GRAY5, // TCI_GRAY7 = TCI_WHITE TCI_RED, // TCI_RED TCI_RED_ORANGE, // TCI_RED_ORANGE TCI_ORANGE, // TCI_ORANGE TCI_ORANGE_YELLOW, // TCI_ORANGE_YELLOW TCI_ORANGE_YELLOW, // TCI_YELLOW TCI_YELLOW_GREEN, // TCI_YELLOW_GREEN TCI_GREEN, // TCI_GREEN TCI_GREEN_CYAN, // TCI_GREEN_CYAN TCI_CYAN, // TCI_CYAN TCI_CYAN_BLUE, // TCI_CYAN_BLUE TCI_BLUE, // TCI_BLUE TCI_BLUE_MAGENTA, // TCI_BLUE_MAGENTA TCI_MAGENTA, // TCI_MAGENTA TCI_MAGENTA_RED, // TCI_MAGENTA_RED }, //--- TCI_RED { TCI_GRAY0, // TCI_GRAY0 = TCI_BLACK TCI_GRAY1, // TCI_GRAY1 TCI_GRAY1, // TCI_GRAY2 = TCI_DARKGRAY TCI_GRAY4, // TCI_GRAY3 TCI_GRAY4, // TCI_GRAY4 TCI_GRAY5, // TCI_GRAY5 = TCI_LIGHTGRAY TCI_GRAY6, // TCI_GRAY6 TCI_GRAY7, // TCI_GRAY7 = TCI_WHITE TCI_B_ORANGE, // TCI_RED TCI_B_ORANGE, // TCI_RED_ORANGE TCI_B_ORANGE, // TCI_ORANGE TCI_B_ORANGE_YELLOW, // TCI_ORANGE_YELLOW TCI_B_YELLOW, // TCI_YELLOW TCI_B_YELLOW_GREEN, // TCI_YELLOW_GREEN TCI_B_GREEN, // TCI_GREEN TCI_B_GREEN_CYAN, // TCI_GREEN_CYAN TCI_B_CYAN, // TCI_CYAN TCI_B_CYAN_BLUE, // TCI_CYAN_BLUE TCI_B_BLUE, // TCI_BLUE TCI_B_BLUE_MAGENTA, // TCI_BLUE_MAGENTA TCI_B_MAGENTA, // TCI_MAGENTA TCI_B_MAGENTA, // TCI_MAGENTA_RED }, //--- TCI_RED_ORANGE { TCI_GRAY0, // TCI_GRAY0 = TCI_BLACK TCI_GRAY1, // TCI_GRAY1 TCI_GRAY2, // TCI_GRAY2 = TCI_DARKGRAY TCI_GRAY2, // TCI_GRAY3 TCI_GRAY5, // TCI_GRAY4 TCI_GRAY5, // TCI_GRAY5 = TCI_LIGHTGRAY TCI_GRAY6, // TCI_GRAY6 TCI_GRAY7, // TCI_GRAY7 = TCI_WHITE TCI_RED, // TCI_RED TCI_RED, // TCI_RED_ORANGE TCI_B_ORANGE_YELLOW, // TCI_ORANGE TCI_B_ORANGE_YELLOW, // TCI_ORANGE_YELLOW TCI_B_YELLOW, // TCI_YELLOW TCI_B_YELLOW_GREEN, // TCI_YELLOW_GREEN TCI_B_GREEN, // TCI_GREEN TCI_B_GREEN_CYAN, // TCI_GREEN_CYAN TCI_B_CYAN, // TCI_CYAN TCI_B_CYAN_BLUE, // TCI_CYAN_BLUE TCI_BLUE, // TCI_BLUE TCI_B_BLUE_MAGENTA, // TCI_BLUE_MAGENTA TCI_B_MAGENTA, // TCI_MAGENTA TCI_MAGENTA_RED, // TCI_MAGENTA_RED }, //--- TCI_ORANGE { TCI_GRAY0, // TCI_GRAY0 = TCI_BLACK TCI_GRAY1, // TCI_GRAY1 TCI_GRAY2, // TCI_GRAY2 = TCI_DARKGRAY TCI_GRAY3, // TCI_GRAY3 TCI_GRAY3, // TCI_GRAY4 TCI_GRAY5, // TCI_GRAY5 = TCI_LIGHTGRAY TCI_GRAY6, // TCI_GRAY6 TCI_GRAY7, // TCI_GRAY7 = TCI_WHITE TCI_RED, // TCI_RED TCI_RED, // TCI_RED_ORANGE TCI_B_ORANGE_YELLOW, // TCI_ORANGE TCI_B_ORANGE_YELLOW, // TCI_ORANGE_YELLOW TCI_B_YELLOW, // TCI_YELLOW TCI_B_YELLOW_GREEN, // TCI_YELLOW_GREEN TCI_B_GREEN, // TCI_GREEN TCI_B_GREEN_CYAN, // TCI_GREEN_CYAN TCI_B_CYAN, // TCI_CYAN TCI_B_CYAN_BLUE, // TCI_CYAN_BLUE TCI_BLUE, // TCI_BLUE TCI_BLUE_MAGENTA, // TCI_BLUE_MAGENTA TCI_MAGENTA, // TCI_MAGENTA TCI_MAGENTA_RED, // TCI_MAGENTA_RED }, //--- TCI_ORANGE_YELLOW { TCI_GRAY0, // TCI_GRAY0 = TCI_BLACK TCI_GRAY1, // TCI_GRAY1 TCI_GRAY2, // TCI_GRAY2 = TCI_DARKGRAY TCI_GRAY3, // TCI_GRAY3 TCI_GRAY3, // TCI_GRAY4 TCI_GRAY6, // TCI_GRAY5 = TCI_LIGHTGRAY TCI_GRAY6, // TCI_GRAY6 TCI_GRAY7, // TCI_GRAY7 = TCI_WHITE TCI_RED, // TCI_RED TCI_RED, // TCI_RED_ORANGE TCI_B_ORANGE, // TCI_ORANGE TCI_B_ORANGE_YELLOW, // TCI_ORANGE_YELLOW TCI_B_YELLOW, // TCI_YELLOW TCI_B_YELLOW_GREEN, // TCI_YELLOW_GREEN TCI_B_GREEN, // TCI_GREEN TCI_B_GREEN_CYAN, // TCI_GREEN_CYAN TCI_B_CYAN, // TCI_CYAN TCI_B_CYAN_BLUE, // TCI_CYAN_BLUE TCI_BLUE, // TCI_BLUE TCI_BLUE_MAGENTA, // TCI_BLUE_MAGENTA TCI_MAGENTA, // TCI_MAGENTA TCI_MAGENTA_RED, // TCI_MAGENTA_RED }, //--- TCI_YELLOW { TCI_GRAY0, // TCI_GRAY0 = TCI_BLACK TCI_GRAY1, // TCI_GRAY1 TCI_GRAY2, // TCI_GRAY2 = TCI_DARKGRAY TCI_GRAY2, // TCI_GRAY3 TCI_GRAY3, // TCI_GRAY4 TCI_GRAY3, // TCI_GRAY5 = TCI_LIGHTGRAY TCI_GRAY6, // TCI_GRAY6 TCI_GRAY7, // TCI_GRAY7 = TCI_WHITE TCI_B_RED, // TCI_RED TCI_B_RED_ORANGE, // TCI_RED_ORANGE TCI_B_ORANGE, // TCI_ORANGE TCI_B_ORANGE_YELLOW, // TCI_ORANGE_YELLOW TCI_B_YELLOW, // TCI_YELLOW TCI_B_YELLOW_GREEN, // TCI_YELLOW_GREEN TCI_B_GREEN, // TCI_GREEN TCI_B_GREEN_CYAN, // TCI_GREEN_CYAN TCI_B_CYAN, // TCI_CYAN TCI_CYAN_BLUE, // TCI_CYAN_BLUE TCI_BLUE, // TCI_BLUE TCI_BLUE_MAGENTA, // TCI_BLUE_MAGENTA TCI_MAGENTA, // TCI_MAGENTA TCI_MAGENTA_RED, // TCI_MAGENTA_RED }, //--- TCI_YELLOW_GREEN { TCI_GRAY0, // TCI_GRAY0 = TCI_BLACK TCI_GRAY1, // TCI_GRAY1 TCI_GRAY2, // TCI_GRAY2 = TCI_DARKGRAY TCI_GRAY3, // TCI_GRAY3 TCI_GRAY3, // TCI_GRAY4 TCI_GRAY6, // TCI_GRAY5 = TCI_LIGHTGRAY TCI_GRAY6, // TCI_GRAY6 TCI_GRAY7, // TCI_GRAY7 = TCI_WHITE TCI_RED, // TCI_RED TCI_RED_ORANGE, // TCI_RED_ORANGE TCI_ORANGE, // TCI_ORANGE TCI_B_ORANGE_YELLOW, // TCI_ORANGE_YELLOW TCI_B_YELLOW, // TCI_YELLOW TCI_B_YELLOW_GREEN, // TCI_YELLOW_GREEN TCI_B_GREEN, // TCI_GREEN TCI_B_GREEN_CYAN, // TCI_GREEN_CYAN TCI_B_CYAN, // TCI_CYAN TCI_CYAN_BLUE, // TCI_CYAN_BLUE TCI_BLUE, // TCI_BLUE TCI_BLUE_MAGENTA, // TCI_BLUE_MAGENTA TCI_MAGENTA, // TCI_MAGENTA TCI_MAGENTA_RED, // TCI_MAGENTA_RED }, //--- TCI_GREEN { TCI_GRAY0, // TCI_GRAY0 = TCI_BLACK TCI_GRAY1, // TCI_GRAY1 TCI_GRAY2, // TCI_GRAY2 = TCI_DARKGRAY TCI_GRAY3, // TCI_GRAY3 TCI_GRAY3, // TCI_GRAY4 TCI_GRAY5, // TCI_GRAY5 = TCI_LIGHTGRAY TCI_GRAY6, // TCI_GRAY6 TCI_GRAY7, // TCI_GRAY7 = TCI_WHITE TCI_RED, // TCI_RED TCI_RED_ORANGE, // TCI_RED_ORANGE TCI_ORANGE, // TCI_ORANGE TCI_B_ORANGE_YELLOW, // TCI_ORANGE_YELLOW TCI_B_YELLOW, // TCI_YELLOW TCI_B_YELLOW_GREEN, // TCI_YELLOW_GREEN TCI_B_GREEN, // TCI_GREEN TCI_B_GREEN_CYAN, // TCI_GREEN_CYAN TCI_B_CYAN, // TCI_CYAN TCI_CYAN_BLUE, // TCI_CYAN_BLUE TCI_BLUE, // TCI_BLUE TCI_BLUE_MAGENTA, // TCI_BLUE_MAGENTA TCI_MAGENTA, // TCI_MAGENTA TCI_MAGENTA_RED, // TCI_MAGENTA_RED }, //--- TCI_GREEN_CYAN { TCI_GRAY0, // TCI_GRAY0 = TCI_BLACK TCI_GRAY1, // TCI_GRAY1 TCI_GRAY2, // TCI_GRAY2 = TCI_DARKGRAY TCI_GRAY3, // TCI_GRAY3 TCI_GRAY3, // TCI_GRAY4 TCI_GRAY6, // TCI_GRAY5 = TCI_LIGHTGRAY TCI_GRAY6, // TCI_GRAY6 TCI_GRAY7, // TCI_GRAY7 = TCI_WHITE TCI_RED, // TCI_RED TCI_B_RED_ORANGE, // TCI_RED_ORANGE TCI_B_ORANGE, // TCI_ORANGE TCI_B_ORANGE_YELLOW, // TCI_ORANGE_YELLOW TCI_B_YELLOW, // TCI_YELLOW TCI_B_YELLOW_GREEN, // TCI_YELLOW_GREEN TCI_B_GREEN, // TCI_GREEN TCI_B_GREEN_CYAN, // TCI_GREEN_CYAN TCI_B_CYAN, // TCI_CYAN TCI_CYAN_BLUE, // TCI_CYAN_BLUE TCI_BLUE, // TCI_BLUE TCI_BLUE_MAGENTA, // TCI_BLUE_MAGENTA TCI_MAGENTA, // TCI_MAGENTA TCI_MAGENTA_RED, // TCI_MAGENTA_RED }, //--- TCI_CYAN { TCI_GRAY0, // TCI_GRAY0 = TCI_BLACK TCI_GRAY1, // TCI_GRAY1 TCI_GRAY2, // TCI_GRAY2 = TCI_DARKGRAY TCI_GRAY3, // TCI_GRAY3 TCI_GRAY3, // TCI_GRAY4 TCI_GRAY6, // TCI_GRAY5 = TCI_LIGHTGRAY TCI_GRAY6, // TCI_GRAY6 TCI_GRAY7, // TCI_GRAY7 = TCI_WHITE TCI_RED, // TCI_RED TCI_B_RED_ORANGE, // TCI_RED_ORANGE TCI_B_ORANGE, // TCI_ORANGE TCI_B_ORANGE_YELLOW, // TCI_ORANGE_YELLOW TCI_B_YELLOW, // TCI_YELLOW TCI_B_YELLOW_GREEN, // TCI_YELLOW_GREEN TCI_B_GREEN, // TCI_GREEN TCI_B_GREEN_CYAN, // TCI_GREEN_CYAN TCI_B_CYAN, // TCI_CYAN TCI_CYAN_BLUE, // TCI_CYAN_BLUE TCI_BLUE, // TCI_BLUE TCI_BLUE_MAGENTA, // TCI_BLUE_MAGENTA TCI_MAGENTA, // TCI_MAGENTA TCI_MAGENTA_RED, // TCI_MAGENTA_RED }, //--- TCI_CYAN_BLUE { TCI_GRAY0, // TCI_GRAY0 = TCI_BLACK TCI_GRAY1, // TCI_GRAY1 TCI_GRAY1, // TCI_GRAY2 = TCI_DARKGRAY TCI_GRAY2, // TCI_GRAY3 TCI_GRAY2, // TCI_GRAY4 TCI_GRAY6, // TCI_GRAY5 = TCI_LIGHTGRAY TCI_GRAY6, // TCI_GRAY6 TCI_GRAY7, // TCI_GRAY7 = TCI_WHITE TCI_B_RED, // TCI_RED TCI_B_RED_ORANGE, // TCI_RED_ORANGE TCI_B_ORANGE, // TCI_ORANGE TCI_B_ORANGE_YELLOW, // TCI_ORANGE_YELLOW TCI_B_YELLOW, // TCI_YELLOW TCI_B_YELLOW_GREEN, // TCI_YELLOW_GREEN TCI_B_GREEN, // TCI_GREEN TCI_B_GREEN_CYAN, // TCI_GREEN_CYAN TCI_B_CYAN, // TCI_CYAN TCI_B_CYAN_BLUE, // TCI_CYAN_BLUE TCI_BLUE, // TCI_BLUE TCI_BLUE_MAGENTA, // TCI_BLUE_MAGENTA TCI_MAGENTA, // TCI_MAGENTA TCI_MAGENTA_RED, // TCI_MAGENTA_RED }, //--- TCI_BLUE { TCI_GRAY0, // TCI_GRAY0 = TCI_BLACK TCI_GRAY0, // TCI_GRAY1 TCI_GRAY3, // TCI_GRAY2 = TCI_DARKGRAY TCI_GRAY4, // TCI_GRAY3 TCI_GRAY4, // TCI_GRAY4 TCI_GRAY5, // TCI_GRAY5 = TCI_LIGHTGRAY TCI_GRAY6, // TCI_GRAY6 TCI_GRAY7, // TCI_GRAY7 = TCI_WHITE TCI_B_RED, // TCI_RED TCI_B_RED_ORANGE, // TCI_RED_ORANGE TCI_B_ORANGE, // TCI_ORANGE TCI_B_ORANGE_YELLOW, // TCI_ORANGE_YELLOW TCI_B_YELLOW, // TCI_YELLOW TCI_B_YELLOW_GREEN, // TCI_YELLOW_GREEN TCI_B_GREEN, // TCI_GREEN TCI_B_GREEN_CYAN, // TCI_GREEN_CYAN TCI_B_CYAN, // TCI_CYAN TCI_B_CYAN_BLUE, // TCI_CYAN_BLUE TCI_B_BLUE, // TCI_BLUE TCI_B_BLUE_MAGENTA, // TCI_BLUE_MAGENTA TCI_B_MAGENTA, // TCI_MAGENTA TCI_B_MAGENTA_RED, // TCI_MAGENTA_RED }, //--- TCI_BLUE_MAGENTA { TCI_GRAY0, // TCI_GRAY0 = TCI_BLACK TCI_GRAY0, // TCI_GRAY1 TCI_GRAY3, // TCI_GRAY2 = TCI_DARKGRAY TCI_GRAY4, // TCI_GRAY3 TCI_GRAY4, // TCI_GRAY4 TCI_GRAY5, // TCI_GRAY5 = TCI_LIGHTGRAY TCI_GRAY6, // TCI_GRAY6 TCI_GRAY7, // TCI_GRAY7 = TCI_WHITE TCI_B_RED, // TCI_RED TCI_B_RED_ORANGE, // TCI_RED_ORANGE TCI_B_ORANGE, // TCI_ORANGE TCI_B_ORANGE_YELLOW, // TCI_ORANGE_YELLOW TCI_B_YELLOW, // TCI_YELLOW TCI_B_YELLOW_GREEN, // TCI_YELLOW_GREEN TCI_B_GREEN, // TCI_GREEN TCI_B_GREEN_CYAN, // TCI_GREEN_CYAN TCI_B_CYAN, // TCI_CYAN TCI_B_CYAN_BLUE, // TCI_CYAN_BLUE TCI_B_BLUE, // TCI_BLUE TCI_B_BLUE_MAGENTA, // TCI_BLUE_MAGENTA TCI_B_MAGENTA, // TCI_MAGENTA TCI_B_MAGENTA_RED, // TCI_MAGENTA_RED }, //--- TCI_MAGENTA { TCI_GRAY0, // TCI_GRAY0 = TCI_BLACK TCI_GRAY1, // TCI_GRAY1 TCI_GRAY1, // TCI_GRAY2 = TCI_DARKGRAY TCI_GRAY4, // TCI_GRAY3 TCI_GRAY4, // TCI_GRAY4 TCI_GRAY5, // TCI_GRAY5 = TCI_LIGHTGRAY TCI_GRAY6, // TCI_GRAY6 TCI_GRAY7, // TCI_GRAY7 = TCI_WHITE TCI_B_RED_ORANGE, // TCI_RED TCI_B_RED_ORANGE, // TCI_RED_ORANGE TCI_B_ORANGE, // TCI_ORANGE TCI_B_ORANGE_YELLOW, // TCI_ORANGE_YELLOW TCI_B_YELLOW, // TCI_YELLOW TCI_B_YELLOW_GREEN, // TCI_YELLOW_GREEN TCI_B_GREEN, // TCI_GREEN TCI_B_GREEN_CYAN, // TCI_GREEN_CYAN TCI_B_CYAN, // TCI_CYAN TCI_B_CYAN_BLUE, // TCI_CYAN_BLUE TCI_BLUE, // TCI_BLUE TCI_B_BLUE_MAGENTA, // TCI_BLUE_MAGENTA TCI_B_MAGENTA, // TCI_MAGENTA TCI_B_MAGENTA_RED, // TCI_MAGENTA_RED }, //--- TCI_MAGENTA_RED { TCI_GRAY0, // TCI_GRAY0 = TCI_BLACK TCI_GRAY1, // TCI_GRAY1 TCI_GRAY1, // TCI_GRAY2 = TCI_DARKGRAY TCI_GRAY4, // TCI_GRAY3 TCI_GRAY4, // TCI_GRAY4 TCI_GRAY5, // TCI_GRAY5 = TCI_LIGHTGRAY TCI_GRAY6, // TCI_GRAY6 TCI_GRAY7, // TCI_GRAY7 = TCI_WHITE TCI_B_RED_ORANGE, // TCI_RED TCI_B_RED_ORANGE, // TCI_RED_ORANGE TCI_B_ORANGE, // TCI_ORANGE TCI_B_ORANGE_YELLOW, // TCI_ORANGE_YELLOW TCI_B_YELLOW, // TCI_YELLOW TCI_B_YELLOW_GREEN, // TCI_YELLOW_GREEN TCI_B_GREEN, // TCI_GREEN TCI_B_GREEN_CYAN, // TCI_GREEN_CYAN TCI_B_CYAN, // TCI_CYAN TCI_B_CYAN_BLUE, // TCI_CYAN_BLUE TCI_BLUE, // TCI_BLUE TCI_B_BLUE_MAGENTA, // TCI_BLUE_MAGENTA TCI_B_MAGENTA, // TCI_MAGENTA TCI_B_MAGENTA_RED, // TCI_MAGENTA_RED }, //--- TCI_B_RED { TCI_GRAY0, // TCI_GRAY0 = TCI_BLACK TCI_GRAY1, // TCI_GRAY1 TCI_GRAY1, // TCI_GRAY2 = TCI_DARKGRAY TCI_GRAY4, // TCI_GRAY3 TCI_GRAY4, // TCI_GRAY4 TCI_GRAY5, // TCI_GRAY5 = TCI_LIGHTGRAY TCI_GRAY6, // TCI_GRAY6 TCI_GRAY7, // TCI_GRAY7 = TCI_WHITE TCI_B_ORANGE, // TCI_RED TCI_B_ORANGE, // TCI_RED_ORANGE TCI_B_ORANGE, // TCI_ORANGE TCI_B_ORANGE_YELLOW, // TCI_ORANGE_YELLOW TCI_B_YELLOW, // TCI_YELLOW TCI_B_YELLOW_GREEN, // TCI_YELLOW_GREEN TCI_B_GREEN, // TCI_GREEN TCI_B_GREEN_CYAN, // TCI_GREEN_CYAN TCI_B_CYAN, // TCI_CYAN TCI_B_CYAN_BLUE, // TCI_CYAN_BLUE TCI_BLUE, // TCI_BLUE TCI_BLUE_MAGENTA, // TCI_BLUE_MAGENTA TCI_B_MAGENTA, // TCI_MAGENTA TCI_B_MAGENTA, // TCI_MAGENTA_RED }, //--- TCI_B_RED_ORANGE { TCI_GRAY0, // TCI_GRAY0 = TCI_BLACK TCI_GRAY1, // TCI_GRAY1 TCI_GRAY2, // TCI_GRAY2 = TCI_DARKGRAY TCI_GRAY2, // TCI_GRAY3 TCI_GRAY5, // TCI_GRAY4 TCI_GRAY5, // TCI_GRAY5 = TCI_LIGHTGRAY TCI_GRAY6, // TCI_GRAY6 TCI_GRAY7, // TCI_GRAY7 = TCI_WHITE TCI_RED, // TCI_RED TCI_RED, // TCI_RED_ORANGE TCI_B_ORANGE_YELLOW, // TCI_ORANGE TCI_B_ORANGE_YELLOW, // TCI_ORANGE_YELLOW TCI_B_YELLOW, // TCI_YELLOW TCI_B_YELLOW_GREEN, // TCI_YELLOW_GREEN TCI_B_GREEN, // TCI_GREEN TCI_B_GREEN_CYAN, // TCI_GREEN_CYAN TCI_B_CYAN, // TCI_CYAN TCI_B_CYAN_BLUE, // TCI_CYAN_BLUE TCI_BLUE, // TCI_BLUE TCI_BLUE_MAGENTA, // TCI_BLUE_MAGENTA TCI_MAGENTA, // TCI_MAGENTA TCI_MAGENTA_RED, // TCI_MAGENTA_RED }, //--- TCI_B_ORANGE { TCI_GRAY0, // TCI_GRAY0 = TCI_BLACK TCI_GRAY1, // TCI_GRAY1 TCI_GRAY2, // TCI_GRAY2 = TCI_DARKGRAY TCI_GRAY3, // TCI_GRAY3 TCI_GRAY3, // TCI_GRAY4 TCI_GRAY5, // TCI_GRAY5 = TCI_LIGHTGRAY TCI_GRAY6, // TCI_GRAY6 TCI_GRAY7, // TCI_GRAY7 = TCI_WHITE TCI_RED, // TCI_RED TCI_RED_ORANGE, // TCI_RED_ORANGE TCI_B_ORANGE_YELLOW, // TCI_ORANGE TCI_B_ORANGE_YELLOW, // TCI_ORANGE_YELLOW TCI_B_YELLOW, // TCI_YELLOW TCI_B_YELLOW_GREEN, // TCI_YELLOW_GREEN TCI_B_GREEN, // TCI_GREEN TCI_B_GREEN_CYAN, // TCI_GREEN_CYAN TCI_B_CYAN, // TCI_CYAN TCI_B_CYAN_BLUE, // TCI_CYAN_BLUE TCI_BLUE, // TCI_BLUE TCI_BLUE_MAGENTA, // TCI_BLUE_MAGENTA TCI_MAGENTA, // TCI_MAGENTA TCI_MAGENTA_RED, // TCI_MAGENTA_RED }, //--- TCI_B_ORANGE_YELLOW { TCI_GRAY0, // TCI_GRAY0 = TCI_BLACK TCI_GRAY1, // TCI_GRAY1 TCI_GRAY2, // TCI_GRAY2 = TCI_DARKGRAY TCI_GRAY3, // TCI_GRAY3 TCI_GRAY4, // TCI_GRAY4 TCI_GRAY4, // TCI_GRAY5 = TCI_LIGHTGRAY TCI_GRAY6, // TCI_GRAY6 TCI_GRAY7, // TCI_GRAY7 = TCI_WHITE TCI_RED, // TCI_RED TCI_RED_ORANGE, // TCI_RED_ORANGE TCI_ORANGE, // TCI_ORANGE TCI_ORANGE_YELLOW, // TCI_ORANGE_YELLOW TCI_YELLOW, // TCI_YELLOW TCI_YELLOW_GREEN, // TCI_YELLOW_GREEN TCI_GREEN, // TCI_GREEN TCI_GREEN_CYAN, // TCI_GREEN_CYAN TCI_CYAN, // TCI_CYAN TCI_CYAN_BLUE, // TCI_CYAN_BLUE TCI_BLUE, // TCI_BLUE TCI_BLUE_MAGENTA, // TCI_BLUE_MAGENTA TCI_MAGENTA, // TCI_MAGENTA TCI_MAGENTA_RED, // TCI_MAGENTA_RED }, //--- TCI_B_YELLOW { TCI_GRAY0, // TCI_GRAY0 = TCI_BLACK TCI_GRAY1, // TCI_GRAY1 TCI_GRAY2, // TCI_GRAY2 = TCI_DARKGRAY TCI_GRAY3, // TCI_GRAY3 TCI_GRAY4, // TCI_GRAY4 TCI_GRAY4, // TCI_GRAY5 = TCI_LIGHTGRAY TCI_GRAY5, // TCI_GRAY6 TCI_GRAY5, // TCI_GRAY7 = TCI_WHITE TCI_RED, // TCI_RED TCI_RED_ORANGE, // TCI_RED_ORANGE TCI_ORANGE, // TCI_ORANGE TCI_ORANGE_YELLOW, // TCI_ORANGE_YELLOW TCI_YELLOW, // TCI_YELLOW TCI_YELLOW_GREEN, // TCI_YELLOW_GREEN TCI_GREEN, // TCI_GREEN TCI_GREEN_CYAN, // TCI_GREEN_CYAN TCI_CYAN, // TCI_CYAN TCI_CYAN_BLUE, // TCI_CYAN_BLUE TCI_BLUE, // TCI_BLUE TCI_BLUE_MAGENTA, // TCI_BLUE_MAGENTA TCI_MAGENTA, // TCI_MAGENTA TCI_MAGENTA_RED, // TCI_MAGENTA_RED }, //--- TCI_B_YELLOW_GREEN { TCI_GRAY0, // TCI_GRAY0 = TCI_BLACK TCI_GRAY1, // TCI_GRAY1 TCI_GRAY2, // TCI_GRAY2 = TCI_DARKGRAY TCI_GRAY3, // TCI_GRAY3 TCI_GRAY4, // TCI_GRAY4 TCI_GRAY4, // TCI_GRAY5 = TCI_LIGHTGRAY TCI_GRAY5, // TCI_GRAY6 TCI_GRAY5, // TCI_GRAY7 = TCI_WHITE TCI_RED, // TCI_RED TCI_RED_ORANGE, // TCI_RED_ORANGE TCI_ORANGE, // TCI_ORANGE TCI_ORANGE_YELLOW, // TCI_ORANGE_YELLOW TCI_YELLOW, // TCI_YELLOW TCI_YELLOW_GREEN, // TCI_YELLOW_GREEN TCI_GREEN, // TCI_GREEN TCI_GREEN_CYAN, // TCI_GREEN_CYAN TCI_CYAN, // TCI_CYAN TCI_CYAN_BLUE, // TCI_CYAN_BLUE TCI_BLUE, // TCI_BLUE TCI_BLUE_MAGENTA, // TCI_BLUE_MAGENTA TCI_MAGENTA, // TCI_MAGENTA TCI_MAGENTA_RED, // TCI_MAGENTA_RED }, //--- TCI_B_GREEN { TCI_GRAY0, // TCI_GRAY0 = TCI_BLACK TCI_GRAY1, // TCI_GRAY1 TCI_GRAY2, // TCI_GRAY2 = TCI_DARKGRAY TCI_GRAY3, // TCI_GRAY3 TCI_GRAY4, // TCI_GRAY4 TCI_GRAY4, // TCI_GRAY5 = TCI_LIGHTGRAY TCI_GRAY5, // TCI_GRAY6 TCI_GRAY5, // TCI_GRAY7 = TCI_WHITE TCI_RED, // TCI_RED TCI_RED_ORANGE, // TCI_RED_ORANGE TCI_ORANGE, // TCI_ORANGE TCI_ORANGE_YELLOW, // TCI_ORANGE_YELLOW TCI_YELLOW, // TCI_YELLOW TCI_YELLOW_GREEN, // TCI_YELLOW_GREEN TCI_GREEN, // TCI_GREEN TCI_GREEN_CYAN, // TCI_GREEN_CYAN TCI_CYAN, // TCI_CYAN TCI_CYAN_BLUE, // TCI_CYAN_BLUE TCI_BLUE, // TCI_BLUE TCI_BLUE_MAGENTA, // TCI_BLUE_MAGENTA TCI_MAGENTA, // TCI_MAGENTA TCI_MAGENTA_RED, // TCI_MAGENTA_RED }, //--- TCI_B_GREEN_CYAN { TCI_GRAY0, // TCI_GRAY0 = TCI_BLACK TCI_GRAY1, // TCI_GRAY1 TCI_GRAY2, // TCI_GRAY2 = TCI_DARKGRAY TCI_GRAY3, // TCI_GRAY3 TCI_GRAY4, // TCI_GRAY4 TCI_GRAY4, // TCI_GRAY5 = TCI_LIGHTGRAY TCI_GRAY5, // TCI_GRAY6 TCI_GRAY5, // TCI_GRAY7 = TCI_WHITE TCI_RED, // TCI_RED TCI_RED_ORANGE, // TCI_RED_ORANGE TCI_ORANGE, // TCI_ORANGE TCI_ORANGE_YELLOW, // TCI_ORANGE_YELLOW TCI_YELLOW, // TCI_YELLOW TCI_YELLOW_GREEN, // TCI_YELLOW_GREEN TCI_GREEN, // TCI_GREEN TCI_GREEN_CYAN, // TCI_GREEN_CYAN TCI_CYAN, // TCI_CYAN TCI_CYAN_BLUE, // TCI_CYAN_BLUE TCI_BLUE, // TCI_BLUE TCI_BLUE_MAGENTA, // TCI_BLUE_MAGENTA TCI_MAGENTA, // TCI_MAGENTA TCI_MAGENTA_RED, // TCI_MAGENTA_RED }, //--- TCI_B_CYAN { TCI_GRAY0, // TCI_GRAY0 = TCI_BLACK TCI_GRAY1, // TCI_GRAY1 TCI_GRAY2, // TCI_GRAY2 = TCI_DARKGRAY TCI_GRAY3, // TCI_GRAY3 TCI_GRAY4, // TCI_GRAY4 TCI_GRAY4, // TCI_GRAY5 = TCI_LIGHTGRAY TCI_GRAY5, // TCI_GRAY6 TCI_GRAY5, // TCI_GRAY7 = TCI_WHITE TCI_RED, // TCI_RED TCI_RED_ORANGE, // TCI_RED_ORANGE TCI_ORANGE, // TCI_ORANGE TCI_ORANGE_YELLOW, // TCI_ORANGE_YELLOW TCI_YELLOW, // TCI_YELLOW TCI_YELLOW_GREEN, // TCI_YELLOW_GREEN TCI_GREEN, // TCI_GREEN TCI_GREEN_CYAN, // TCI_GREEN_CYAN TCI_CYAN, // TCI_CYAN TCI_CYAN_BLUE, // TCI_CYAN_BLUE TCI_BLUE, // TCI_BLUE TCI_BLUE_MAGENTA, // TCI_BLUE_MAGENTA TCI_MAGENTA, // TCI_MAGENTA TCI_MAGENTA_RED, // TCI_MAGENTA_RED }, //--- TCI_CYAN_BLUE { TCI_GRAY0, // TCI_GRAY0 = TCI_BLACK TCI_GRAY1, // TCI_GRAY1 TCI_GRAY2, // TCI_GRAY2 = TCI_DARKGRAY TCI_GRAY3, // TCI_GRAY3 TCI_GRAY4, // TCI_GRAY4 TCI_GRAY5, // TCI_GRAY5 = TCI_LIGHTGRAY TCI_GRAY6, // TCI_GRAY6 TCI_GRAY7, // TCI_GRAY7 = TCI_WHITE TCI_RED, // TCI_RED TCI_RED_ORANGE, // TCI_RED_ORANGE TCI_ORANGE, // TCI_ORANGE TCI_B_ORANGE_YELLOW, // TCI_ORANGE_YELLOW TCI_B_YELLOW, // TCI_YELLOW TCI_B_YELLOW_GREEN, // TCI_YELLOW_GREEN TCI_B_GREEN, // TCI_GREEN TCI_B_GREEN_CYAN, // TCI_GREEN_CYAN TCI_B_CYAN, // TCI_CYAN TCI_CYAN_BLUE, // TCI_CYAN_BLUE TCI_BLUE, // TCI_BLUE TCI_BLUE_MAGENTA, // TCI_BLUE_MAGENTA TCI_MAGENTA, // TCI_MAGENTA TCI_MAGENTA_RED, // TCI_MAGENTA_RED }, //--- TCI_B_BLUE { TCI_GRAY0, // TCI_GRAY0 = TCI_BLACK TCI_GRAY1, // TCI_GRAY1 TCI_GRAY2, // TCI_GRAY2 = TCI_DARKGRAY TCI_GRAY3, // TCI_GRAY3 TCI_GRAY4, // TCI_GRAY4 TCI_GRAY5, // TCI_GRAY5 = TCI_LIGHTGRAY TCI_GRAY6, // TCI_GRAY6 TCI_GRAY7, // TCI_GRAY7 = TCI_WHITE TCI_RED, // TCI_RED TCI_RED_ORANGE, // TCI_RED_ORANGE TCI_ORANGE, // TCI_ORANGE TCI_B_ORANGE_YELLOW, // TCI_ORANGE_YELLOW TCI_B_YELLOW, // TCI_YELLOW TCI_B_YELLOW_GREEN, // TCI_YELLOW_GREEN TCI_B_GREEN, // TCI_GREEN TCI_B_GREEN_CYAN, // TCI_GREEN_CYAN TCI_B_CYAN, // TCI_CYAN TCI_CYAN_BLUE, // TCI_CYAN_BLUE TCI_BLUE, // TCI_BLUE TCI_BLUE_MAGENTA, // TCI_BLUE_MAGENTA TCI_MAGENTA, // TCI_MAGENTA TCI_MAGENTA_RED, // TCI_MAGENTA_RED }, //--- TCI_B_BLUE_MAGENTA { TCI_GRAY0, // TCI_GRAY0 = TCI_BLACK TCI_GRAY1, // TCI_GRAY1 TCI_GRAY2, // TCI_GRAY2 = TCI_DARKGRAY TCI_GRAY3, // TCI_GRAY3 TCI_GRAY4, // TCI_GRAY4 TCI_GRAY5, // TCI_GRAY5 = TCI_LIGHTGRAY TCI_GRAY6, // TCI_GRAY6 TCI_GRAY7, // TCI_GRAY7 = TCI_WHITE TCI_RED, // TCI_RED TCI_RED_ORANGE, // TCI_RED_ORANGE TCI_B_ORANGE, // TCI_ORANGE TCI_B_ORANGE_YELLOW, // TCI_ORANGE_YELLOW TCI_B_YELLOW, // TCI_YELLOW TCI_B_YELLOW_GREEN, // TCI_YELLOW_GREEN TCI_B_GREEN, // TCI_GREEN TCI_B_GREEN_CYAN, // TCI_GREEN_CYAN TCI_B_CYAN, // TCI_CYAN TCI_B_CYAN_BLUE, // TCI_CYAN_BLUE TCI_BLUE, // TCI_BLUE TCI_BLUE_MAGENTA, // TCI_BLUE_MAGENTA TCI_MAGENTA, // TCI_MAGENTA TCI_MAGENTA_RED, // TCI_MAGENTA_RED }, //--- TCI_B_MAGENTA { TCI_GRAY0, // TCI_GRAY0 = TCI_BLACK TCI_GRAY1, // TCI_GRAY1 TCI_GRAY2, // TCI_GRAY2 = TCI_DARKGRAY TCI_GRAY3, // TCI_GRAY3 TCI_GRAY4, // TCI_GRAY4 TCI_GRAY5, // TCI_GRAY5 = TCI_LIGHTGRAY TCI_GRAY6, // TCI_GRAY6 TCI_GRAY7, // TCI_GRAY7 = TCI_WHITE TCI_RED, // TCI_RED TCI_RED_ORANGE, // TCI_RED_ORANGE TCI_B_ORANGE, // TCI_ORANGE TCI_B_ORANGE_YELLOW, // TCI_ORANGE_YELLOW TCI_B_YELLOW, // TCI_YELLOW TCI_B_YELLOW_GREEN, // TCI_YELLOW_GREEN TCI_B_GREEN, // TCI_GREEN TCI_B_GREEN_CYAN, // TCI_GREEN_CYAN TCI_B_CYAN, // TCI_CYAN TCI_CYAN_BLUE, // TCI_CYAN_BLUE TCI_BLUE, // TCI_BLUE TCI_BLUE_MAGENTA, // TCI_BLUE_MAGENTA TCI_MAGENTA, // TCI_MAGENTA TCI_MAGENTA_RED, // TCI_MAGENTA_RED }, //--- TCI_B_MAGENTA_RED { TCI_GRAY0, // TCI_GRAY0 = TCI_BLACK TCI_GRAY1, // TCI_GRAY1 TCI_GRAY2, // TCI_GRAY2 = TCI_DARKGRAY TCI_GRAY3, // TCI_GRAY3 TCI_GRAY4, // TCI_GRAY4 TCI_GRAY5, // TCI_GRAY5 = TCI_LIGHTGRAY TCI_GRAY6, // TCI_GRAY6 TCI_GRAY7, // TCI_GRAY7 = TCI_WHITE TCI_RED, // TCI_RED TCI_RED, // TCI_RED_ORANGE TCI_B_ORANGE, // TCI_ORANGE TCI_B_ORANGE_YELLOW, // TCI_ORANGE_YELLOW TCI_B_YELLOW, // TCI_YELLOW TCI_B_YELLOW_GREEN, // TCI_YELLOW_GREEN TCI_B_GREEN, // TCI_GREEN TCI_B_GREEN_CYAN, // TCI_GREEN_CYAN TCI_B_CYAN, // TCI_CYAN TCI_CYAN_BLUE, // TCI_CYAN_BLUE TCI_BLUE, // TCI_BLUE TCI_BLUE_MAGENTA, // TCI_BLUE_MAGENTA TCI_MAGENTA, // TCI_MAGENTA TCI_MAGENTA_RED, // TCI_MAGENTA_RED }, }; const uint font = font_index < TCI_B_RED ? font_index : font_index - (TCI_B_RED-TCI_RED); font_index = tab[bg_index][font]; } //--- color index static const u8 color_index_8[] = { 0, // TCI_GRAY0 = TCI_BLACK 0, // TCI_GRAY1 8, // TCI_GRAY2 = TCI_DARKGRAY 8, // TCI_GRAY3 7, // TCI_GRAY4 7, // TCI_GRAY5 = TCI_LIGHTGRAY 15, // TCI_GRAY6 15, // TCI_GRAY7 = TCI_WHITE 1, // TCI_RED 1, // TCI_RED_ORANGE 1, // TCI_ORANGE 1, // TCI_ORANGE_YELLOW 3, // TCI_YELLOW 3, // TCI_YELLOW_GREEN 2, // TCI_GREEN 2, // TCI_GREEN_CYAN 6, // TCI_CYAN 6, // TCI_CYAN_BLUE 4, // TCI_BLUE 4, // TCI_BLUE_MAGENTA 5, // TCI_MAGENTA 5, // TCI_MAGENTA_RED 9, // TCI_B_RED 9, // TCI_B_RED_ORANGE 9, // TCI_B_ORANGE 9, // TCI_B_ORANGE_YELLOW 11, // TCI_B_YELLOW 11, // TCI_B_YELLOW_GREEN 10, // TCI_B_GREEN 10, // TCI_B_GREEN_CYAN 14, // TCI_B_CYAN 14, // TCI_B_CYAN_BLUE 12, // TCI_B_BLUE 12, // TCI_B_BLUE_MAGENTA 13, // TCI_B_MAGENTA 13, // TCI_B_MAGENTA_RED }; static const u8 color_index_256[] = { 232, // TCI_GRAY0 = TCI_BLACK 236, // TCI_GRAY1 240, // TCI_GRAY2 = TCI_DARKGRAY 243, // TCI_GRAY3 246, // TCI_GRAY4 249, // TCI_GRAY5 = TCI_LIGHTGRAY 252, // TCI_GRAY6 255, // TCI_GRAY7 = TCI_WHITE 160, // TCI_RED 166, // TCI_RED_ORANGE 172, // TCI_ORANGE 136, // TCI_ORANGE_YELLOW 142, // TCI_YELLOW 106, // TCI_YELLOW_GREEN 34, // TCI_GREEN 36, // TCI_GREEN_CYAN 37, // TCI_CYAN 32, // TCI_CYAN_BLUE 21, // TCI_BLUE 92, // TCI_BLUE_MAGENTA 164, // TCI_MAGENTA 162, // TCI_MAGENTA_RED 196, // TCI_B_RED 202, // TCI_B_RED_ORANGE 208, // TCI_B_ORANGE 214, // TCI_B_ORANGE_YELLOW 226, // TCI_B_YELLOW 154, // TCI_B_YELLOW_GREEN 46, // TCI_B_GREEN 49, // TCI_B_GREEN_CYAN 51, // TCI_B_CYAN 75, // TCI_B_CYAN_BLUE 105, // TCI_B_BLUE 177, // TCI_B_BLUE_MAGENTA 207, // TCI_B_MAGENTA 204, // TCI_B_MAGENTA_RED }; const u8 *color_index; uint x_bg; if ( col_mode == COLMD_256_COLORS ) { color_index = color_index_256; x_bg = 8; } else { color_index = color_index_8; x_bg = 16; option |= GCM_SHORT; } //--- output char buf[100], *end = buf + sizeof(buf); char *dest = StringCopyE(buf,end,TermTextModeBeg); const uint bg = (uint)bg_index < TCI__IGNORE ? color_index[bg_index] : ~0; ccp sep = ""; if ( (uint)font_index < TCI__IGNORE ) { uint idx = color_index[font_index]; if ( idx < 16 && idx == (bg&7) && option & GCM_ALT ) idx = idx ^ 8; if ( !(option & GCM_SHORT) || idx >= 16 ) dest = snprintfE(dest,end,"38;5;%u",idx); else if ( idx < 8 ) dest = snprintfE(dest,end,"0;%u",30+idx); else dest = snprintfE(dest,end,"1;%u",22+idx); sep = ";"; } if ( (uint)bg_index < TCI__IGNORE ) { if ( !(option & GCM_SHORT) || bg >= x_bg ) dest = snprintfE(dest,end,"%s48;5;%u",sep,bg); else dest = snprintfE(dest,end,"%s%u",sep,40+(bg&7)); } dest = StringCopyE(dest,end,TermTextModeEnd); const int len = dest + 1 - buf; char *res = GetColorCircBuf(len); memcpy(res,buf,len); return res; } #else // !SUPPORT_36_COLORS ccp GetColorMode // 18 colors version ( // returns a pointer to an internal circulary buffer (not GetCircBuf()) ColorMode_t col_mode, // if < COLMD_ON: return an empty string TermColorIndex_t font_index, // index of font color TermColorIndex_t bg_index, // index of background color GetColorOption_t option // execution options ) { col_mode = NormalizeColorMode(col_mode,8); if ( col_mode < COLMD_ON ) return EmptyString; //--- recommended combinations if ( option & GCM_ALT && (uint)font_index < TCI__IGNORE && (uint)bg_index < TCI__IGNORE ) { static const u8 tab[TCI__N_BG][TCI__N_FONT] = { //--- TCI_BLACK { TCI_DARKGRAY, // TCI_BLACK TCI_DARKGRAY, // TCI_DARKGRAY TCI_LIGHTGRAY, // TCI_LIGHTGRAY TCI_WHITE, // TCI_WHITE TCI_B_RED, // TCI_RED TCI_B_ORANGE, // TCI_ORANGE TCI_B_YELLOW, // TCI_YELLOW TCI_B_GREEN, // TCI_GREEN TCI_B_CYAN, // TCI_CYAN TCI_B_BLUE, // TCI_BLUE TCI_B_MAGENTA, // TCI_MAGENTA }, //--- TCI_DARKGRAY { TCI_BLACK, // TCI_BLACK TCI_LIGHTGRAY, // TCI_DARKGRAY TCI_LIGHTGRAY, // TCI_LIGHTGRAY TCI_WHITE, // TCI_WHITE TCI_B_RED, // TCI_RED TCI_B_ORANGE, // TCI_ORANGE TCI_B_YELLOW, // TCI_YELLOW TCI_B_GREEN, // TCI_GREEN TCI_B_CYAN, // TCI_CYAN TCI_B_BLUE, // TCI_BLUE TCI_B_MAGENTA, // TCI_MAGENTA }, //--- TCI_LIGHTGRAY { TCI_BLACK, // TCI_BLACK TCI_DARKGRAY, // TCI_DARKGRAY TCI_DARKGRAY, // TCI_LIGHTGRAY TCI_WHITE, // TCI_WHITE TCI_RED, // TCI_RED TCI_ORANGE, // TCI_ORANGE TCI_B_YELLOW, // TCI_YELLOW TCI_GREEN, // TCI_GREEN TCI_CYAN, // TCI_CYAN TCI_BLUE, // TCI_BLUE TCI_MAGENTA, // TCI_MAGENTA }, //--- TCI_WHITE { TCI_BLACK, // TCI_BLACK TCI_DARKGRAY, // TCI_DARKGRAY TCI_LIGHTGRAY, // TCI_LIGHTGRAY TCI_LIGHTGRAY, // TCI_WHITE TCI_RED, // TCI_RED TCI_ORANGE, // TCI_ORANGE TCI_ORANGE, // TCI_YELLOW TCI_GREEN, // TCI_GREEN TCI_CYAN, // TCI_CYAN TCI_BLUE, // TCI_BLUE TCI_MAGENTA, // TCI_MAGENTA }, //--- TCI_RED { TCI_BLACK, // TCI_BLACK TCI_LIGHTGRAY, // TCI_DARKGRAY TCI_LIGHTGRAY, // TCI_LIGHTGRAY TCI_WHITE, // TCI_WHITE TCI_B_RED, // TCI_RED TCI_B_ORANGE, // TCI_ORANGE TCI_B_YELLOW, // TCI_YELLOW TCI_B_GREEN, // TCI_GREEN TCI_B_CYAN, // TCI_CYAN TCI_B_BLUE, // TCI_BLUE TCI_B_MAGENTA, // TCI_MAGENTA }, //--- TCI_ORANGE { TCI_BLACK, // TCI_BLACK TCI_DARKGRAY, // TCI_DARKGRAY TCI_WHITE, // TCI_LIGHTGRAY TCI_WHITE, // TCI_WHITE TCI_RED, // TCI_RED TCI_B_ORANGE, // TCI_ORANGE TCI_B_YELLOW, // TCI_YELLOW TCI_B_GREEN, // TCI_GREEN TCI_B_CYAN, // TCI_CYAN TCI_BLUE, // TCI_BLUE TCI_MAGENTA, // TCI_MAGENTA }, //--- TCI_YELLOW { TCI_BLACK, // TCI_BLACK TCI_DARKGRAY, // TCI_DARKGRAY TCI_WHITE, // TCI_LIGHTGRAY TCI_WHITE, // TCI_WHITE TCI_RED, // TCI_RED TCI_ORANGE, // TCI_ORANGE TCI_B_YELLOW, // TCI_YELLOW TCI_B_GREEN, // TCI_GREEN TCI_B_CYAN, // TCI_CYAN TCI_BLUE, // TCI_BLUE TCI_MAGENTA, // TCI_MAGENTA }, //--- TCI_GREEN { TCI_BLACK, // TCI_BLACK TCI_DARKGRAY, // TCI_DARKGRAY TCI_LIGHTGRAY, // TCI_LIGHTGRAY TCI_WHITE, // TCI_WHITE TCI_RED, // TCI_RED TCI_ORANGE, // TCI_ORANGE TCI_B_YELLOW, // TCI_YELLOW TCI_B_GREEN, // TCI_GREEN TCI_B_CYAN, // TCI_CYAN TCI_BLUE, // TCI_BLUE TCI_MAGENTA, // TCI_MAGENTA }, //--- TCI_CYAN { TCI_BLACK, // TCI_BLACK TCI_DARKGRAY, // TCI_DARKGRAY TCI_LIGHTGRAY, // TCI_LIGHTGRAY TCI_WHITE, // TCI_WHITE TCI_RED, // TCI_RED TCI_ORANGE, // TCI_ORANGE TCI_B_YELLOW, // TCI_YELLOW TCI_B_GREEN, // TCI_GREEN TCI_B_CYAN, // TCI_CYAN TCI_BLUE, // TCI_BLUE TCI_MAGENTA, // TCI_MAGENTA }, //--- TCI_BLUE { TCI_BLACK, // TCI_BLACK TCI_LIGHTGRAY, // TCI_DARKGRAY TCI_LIGHTGRAY, // TCI_LIGHTGRAY TCI_WHITE, // TCI_WHITE TCI_RED, // TCI_RED TCI_ORANGE, // TCI_ORANGE TCI_B_YELLOW, // TCI_YELLOW TCI_B_GREEN, // TCI_GREEN TCI_B_CYAN, // TCI_CYAN TCI_CYAN, // TCI_BLUE TCI_B_MAGENTA, // TCI_MAGENTA }, //--- TCI_MAGENTA { TCI_BLACK, // TCI_BLACK TCI_LIGHTGRAY, // TCI_DARKGRAY TCI_LIGHTGRAY, // TCI_LIGHTGRAY TCI_WHITE, // TCI_WHITE TCI_RED, // TCI_RED TCI_ORANGE, // TCI_ORANGE TCI_B_YELLOW, // TCI_YELLOW TCI_B_GREEN, // TCI_GREEN TCI_B_CYAN, // TCI_CYAN TCI_CYAN, // TCI_BLUE TCI_B_MAGENTA, // TCI_MAGENTA }, //--- TCI_B_RED { TCI_BLACK, // TCI_BLACK TCI_DARKGRAY, // TCI_DARKGRAY TCI_WHITE, // TCI_LIGHTGRAY TCI_WHITE, // TCI_WHITE TCI_RED, // TCI_RED TCI_ORANGE, // TCI_ORANGE TCI_B_YELLOW, // TCI_YELLOW TCI_B_GREEN, // TCI_GREEN TCI_B_CYAN, // TCI_CYAN TCI_BLUE, // TCI_BLUE TCI_MAGENTA, // TCI_MAGENTA }, //--- TCI_B_ORANGE { TCI_BLACK, // TCI_BLACK TCI_DARKGRAY, // TCI_DARKGRAY TCI_WHITE, // TCI_LIGHTGRAY TCI_WHITE, // TCI_WHITE TCI_RED, // TCI_RED TCI_ORANGE, // TCI_ORANGE TCI_B_YELLOW, // TCI_YELLOW TCI_B_GREEN, // TCI_GREEN TCI_B_CYAN, // TCI_CYAN TCI_BLUE, // TCI_BLUE TCI_MAGENTA, // TCI_MAGENTA }, //--- TCI_B_YELLOW { TCI_BLACK, // TCI_BLACK TCI_DARKGRAY, // TCI_DARKGRAY TCI_DARKGRAY, // TCI_LIGHTGRAY TCI_DARKGRAY, // TCI_WHITE TCI_RED, // TCI_RED TCI_ORANGE, // TCI_ORANGE TCI_YELLOW, // TCI_YELLOW TCI_GREEN, // TCI_GREEN TCI_CYAN, // TCI_CYAN TCI_BLUE, // TCI_BLUE TCI_MAGENTA, // TCI_MAGENTA }, //--- TCI_B_GREEN { TCI_BLACK, // TCI_BLACK TCI_DARKGRAY, // TCI_DARKGRAY TCI_DARKGRAY, // TCI_LIGHTGRAY TCI_WHITE, // TCI_WHITE TCI_RED, // TCI_RED TCI_ORANGE, // TCI_ORANGE TCI_B_YELLOW, // TCI_YELLOW TCI_GREEN, // TCI_GREEN TCI_CYAN, // TCI_CYAN TCI_BLUE, // TCI_BLUE TCI_MAGENTA, // TCI_MAGENTA }, //--- TCI_B_CYAN { TCI_BLACK, // TCI_BLACK TCI_DARKGRAY, // TCI_DARKGRAY TCI_DARKGRAY, // TCI_LIGHTGRAY TCI_WHITE, // TCI_WHITE TCI_RED, // TCI_RED TCI_ORANGE, // TCI_ORANGE TCI_YELLOW, // TCI_YELLOW TCI_GREEN, // TCI_GREEN TCI_CYAN, // TCI_CYAN TCI_BLUE, // TCI_BLUE TCI_MAGENTA, // TCI_MAGENTA }, //--- TCI_B_BLUE { TCI_BLACK, // TCI_BLACK TCI_DARKGRAY, // TCI_DARKGRAY TCI_DARKGRAY, // TCI_LIGHTGRAY TCI_WHITE, // TCI_WHITE TCI_RED, // TCI_RED TCI_B_ORANGE, // TCI_ORANGE TCI_B_YELLOW, // TCI_YELLOW TCI_B_GREEN, // TCI_GREEN TCI_B_CYAN, // TCI_CYAN TCI_CYAN, // TCI_BLUE TCI_MAGENTA, // TCI_MAGENTA }, //--- TCI_B_MAGENTA { TCI_BLACK, // TCI_BLACK TCI_DARKGRAY, // TCI_DARKGRAY TCI_DARKGRAY, // TCI_LIGHTGRAY TCI_WHITE, // TCI_WHITE TCI_RED, // TCI_RED TCI_B_ORANGE, // TCI_ORANGE TCI_B_YELLOW, // TCI_YELLOW TCI_GREEN, // TCI_GREEN TCI_B_CYAN, // TCI_CYAN TCI_CYAN, // TCI_BLUE TCI_MAGENTA, // TCI_MAGENTA }, }; const uint font = font_index < TCI_B_RED ? font_index : font_index - (TCI_B_RED-TCI_RED); font_index = tab[bg_index][font]; } //--- color index static const u8 color_index_8[] = { 0, // TCI_BLACK 8, // TCI_DARKGRAY 7, // TCI_LIGHTGRAY 15, // TCI_WHITE 1, // TCI_RED 1, // TCI_ORANGE 3, // TCI_YELLOW 2, // TCI_GREEN 6, // TCI_CYAN 4, // TCI_BLUE 5, // TCI_MAGENTA 9, // TCI_B_RED 9, // TCI_B_ORANGE 11, // TCI_B_YELLOW 10, // TCI_B_GREEN 14, // TCI_B_CYAN 12, // TCI_B_BLUE 13, // TCI_B_MAGENTA }; static const u8 color_index_256[] = { 0, // TCI_BLACK 8, // TCI_DARKGRAY 7, // TCI_LIGHTGRAY 15, // TCI_WHITE 160, // TCI_RED 172, // TCI_ORANGE 142, // TCI_YELLOW 34, // TCI_GREEN 37, // TCI_CYAN 21, // TCI_BLUE 164, // TCI_MAGENTA 196, // TCI_B_RED 208, // TCI_B_ORANGE 226, // TCI_B_YELLOW 46, // TCI_B_GREEN 51, // TCI_B_CYAN 105, // TCI_B_BLUE 207, // TCI_B_MAGENTA }; const u8 *color_index; uint x_bg; if ( col_mode == COLMD_256_COLORS ) { color_index = color_index_256; x_bg = 8; } else { color_index = color_index_8; x_bg = 16; option |= GCM_SHORT; } //--- output char buf[100], *end = buf + sizeof(buf); char *dest = StringCopyE(buf,end,TermTextModeBeg); ccp sep = ""; if ( (uint)font_index < TCI__IGNORE ) { const uint idx = color_index[font_index]; if ( !(option & GCM_SHORT) || idx >= 16 ) dest = snprintfE(dest,end,"38;5;%u",idx); else if ( idx < 8 ) dest = snprintfE(dest,end,"0;%u",30+idx); else dest = snprintfE(dest,end,"1;%u",22+idx); sep = ";"; } if ( (uint)bg_index < TCI__IGNORE ) { const uint idx = color_index[bg_index]; if ( !(option & GCM_SHORT) || idx >= x_bg ) dest = snprintfE(dest,end,"%s48;5;%u",sep,idx); else dest = snprintfE(dest,end,"%s%u",sep,40+(idx&7)); } dest = StringCopyE(dest,end,TermTextModeEnd); const int len = dest + 1 - buf; char *res = GetColorCircBuf(len); memcpy(res,buf,len); return res; } #endif // !SUPPORT_36_COLORS // /////////////////////////////////////////////////////////////////////////////// /////////////// colors /////////////// /////////////////////////////////////////////////////////////////////////////// const ColorSet_t * GetColorSet0() { static ColorSet_t col = {0}; if (!col.col_mode) { col.col_mode = COLMD_OFF; col.colorize = false; col.n_colors = 0; col.space = EmptyString; col.tab = EmptyString; col.lf = EmptyString; ccp *ptr = &col.reset; ccp *end = (ccp*)((ccp)&col + sizeof(col)); while ( ptr < end ) *ptr++ = EmptyString; } return &col; } /////////////////////////////////////////////////////////////////////////////// const ColorSet_t * GetColorSet8() { static ColorSet_t col = {0}; if (!col.col_mode) { col.col_mode = COLMD_8_COLORS; col.colorize = true; col.n_colors = 8; col.space = Space200; col.tab = Tabs20; col.lf = LF20; col.reset = TermTextModeReset; col.setup = STRDUP(GetTextMode(1,TTM_COL_SETUP)); col.run = STRDUP(GetTextMode(1,TTM_COL_RUN)); col.abort = STRDUP(GetTextMode(1,TTM_COL_ABORT)); col.finish = STRDUP(GetTextMode(1,TTM_COL_FINISH)); col.script = STRDUP(GetTextMode(1,TTM_COL_SCRIPT)); col.open = STRDUP(GetTextMode(1,TTM_COL_OPEN)); col.close = STRDUP(GetTextMode(1,TTM_COL_CLOSE)); col.file = STRDUP(GetTextMode(1,TTM_COL_FILE)); col.job = STRDUP(GetTextMode(1,TTM_COL_JOB)); col.info = STRDUP(GetTextMode(1,TTM_COL_INFO)); col.hint = STRDUP(GetTextMode(1,TTM_COL_HINT)); col.warn = STRDUP(GetTextMode(1,TTM_COL_WARN)); col.debug = STRDUP(GetTextMode(1,TTM_COL_DEBUG)); col.log = STRDUP(GetTextMode(1,TTM_COL_LOG)); col.name = STRDUP(GetTextMode(1,TTM_COL_NAME)); col.value = STRDUP(GetTextMode(1,TTM_COL_VALUE)); col.success = STRDUP(GetTextMode(1,TTM_COL_SUCCESS)); col.error = STRDUP(GetTextMode(1,TTM_COL_ERROR)); col.fail = STRDUP(GetTextMode(1,TTM_COL_FAIL)); col.fail2 = STRDUP(GetTextMode(1,TTM_COL_FAIL2)); col.fatal = STRDUP(GetTextMode(1,TTM_COL_FATAL)); col.mark = STRDUP(GetTextMode(1,TTM_COL_MARK)); col.bad = STRDUP(GetTextMode(1,TTM_COL_BAD)); col.select = STRDUP(GetTextMode(1,TTM_COL_SELECT)); col.differ = STRDUP(GetTextMode(1,TTM_COL_DIFFER)); col.stat_line = STRDUP(GetTextMode(1,TTM_COL_STAT_LINE)); col.warn_line = STRDUP(GetTextMode(1,TTM_COL_WARN_LINE)); col.proc_line = STRDUP(GetTextMode(1,TTM_COL_PROC_LINE)); col.cite = STRDUP(GetTextMode(1,TTM_COL_CITE)); col.status = STRDUP(GetTextMode(1,TTM_COL_STATUS)); col.highlight = STRDUP(GetTextMode(1,TTM_COL_HIGHLIGHT)); col.hide = STRDUP(GetTextMode(1,TTM_COL_HIDE)); col.heading = STRDUP(GetTextMode(1,TTM_COL_HEADING)); col.caption = STRDUP(GetTextMode(1,TTM_COL_CAPTION)); col.section = STRDUP(GetTextMode(1,TTM_COL_SECTION)); col.syntax = STRDUP(GetTextMode(1,TTM_COL_SYNTAX)); col.cmd = STRDUP(GetTextMode(1,TTM_COL_CMD)); col.option = STRDUP(GetTextMode(1,TTM_COL_OPTION)); col.param = STRDUP(GetTextMode(1,TTM_COL_PARAM)); col.on = STRDUP(GetTextMode(1,TTM_COL_ON)); col.off = STRDUP(GetTextMode(1,TTM_COL_OFF)); col.black = STRDUP(GetTextMode(1,TTM_NO_BOLD|TTM_BLACK)); col.b_black = STRDUP(GetTextMode(1,TTM_BOLD|TTM_BLACK)); col.white = STRDUP(GetTextMode(1,TTM_NO_BOLD|TTM_WHITE)); col.b_white = STRDUP(GetTextMode(1,TTM_BOLD|TTM_WHITE)); col.red = STRDUP(GetTextMode(1,TTM_NO_BOLD|TTM_RED)); col.red_orange = col.red; col.orange = col.red; col.yellow = STRDUP(GetTextMode(1,TTM_NO_BOLD|TTM_YELLOW)); col.orange_yellow = col.yellow; col.yellow_green = col.yellow; col.green = STRDUP(GetTextMode(1,TTM_NO_BOLD|TTM_GREEN)); col.green_cyan = col.green; col.cyan = STRDUP(GetTextMode(1,TTM_NO_BOLD|TTM_CYAN)); col.cyan_blue = col.cyan; col.blue = STRDUP(GetTextMode(1,TTM_NO_BOLD|TTM_BLUE)); col.blue_magenta = col.blue; col.magenta = STRDUP(GetTextMode(1,TTM_NO_BOLD|TTM_MAGENTA)); col.magenta_red = col.magenta; col.b_red = STRDUP(GetTextMode(1,TTM_BOLD|TTM_RED)); col.b_red_orange = col.b_red; col.b_orange = col.b_red; col.b_yellow = STRDUP(GetTextMode(1,TTM_BOLD|TTM_YELLOW)); col.b_orange_yellow = col.b_yellow; col.b_yellow_green = col.b_yellow; col.b_green = STRDUP(GetTextMode(1,TTM_BOLD|TTM_GREEN)); col.b_green_cyan = col.b_green; col.b_cyan = STRDUP(GetTextMode(1,TTM_BOLD|TTM_CYAN)); col.b_cyan_blue = col.b_cyan; col.b_blue = STRDUP(GetTextMode(1,TTM_BOLD|TTM_BLUE)); col.b_blue_magenta = col.b_blue; col.b_magenta = STRDUP(GetTextMode(1,TTM_BOLD|TTM_MAGENTA)); col.b_magenta_red = col.b_magenta; TermColorIndex_t font, bg; for ( font = 0; font < TCI__N_FONT; font++ ) for ( bg = 0; bg < TCI__N_BG; bg++ ) col.matrix[font][bg] = STRDUP(GetColorMode(COLMD_8_COLORS,font,bg,GCM_ALT|GCM_SHORT)); } return &col; } /////////////////////////////////////////////////////////////////////////////// const ColorSet_t * GetColorSet256() { static ColorSet_t col = {0}; if (!col.col_mode) { //--- default settings (copy of 8-COLORS) memcpy(&col,GetColorSet8(),sizeof(col)); col.col_mode = COLMD_256_COLORS; col.n_colors = 256; //--- special settings col.setup = "\e[38;5;86;40m"; col.run = "\e[38;5;229;40m"; col.abort = "\e[38;5;198;40m"; col.finish = "\e[38;5;154;40m"; col.script = "\e[0;30;48;5;219m"; col.open = "\e[38;5;225;40m"; col.close = "\e[38;5;219;40m"; col.heading = "\e[38;5;111;40m"; col.info = "\e[38;5;49;40m"; col.hint = "\e[38;5;220;40m"; col.warn = "\e[38;5;208;40m"; col.debug = "\e[38;5;210;40m"; col.error = "\e[38;5;255;48;5;130m"; col.fail = "\e[38;5;251;48;5;88m"; col.fail2 = "\e[38;5;255;48;5;88m"; col.fatal = "\e[38;5;255;48;5;129m"; col.differ = "\e[38;5;226;48;5;19m"; col.stat_line = "\e[38;5;231;48;5;19m"; col.warn_line = "\e[38;5;215;48;5;19m"; col.hide = "\e[38;5;245;40m"; //--- special settings: color names // dark: // ./mkw-ana testcol 400-420 420-330 330-030 030-033 033-005 005-404 404-400 // ./mkw-ana testcol 400 410 420 320 330 230 030 032 033 024 005 204 404 402 400 col.red = "\e[38;5;160m"; col.red_orange = "\e[38;5;166m"; col.orange = "\e[38;5;172m"; col.orange_yellow = "\e[38;5;136m"; col.yellow = "\e[38;5;142m"; col.yellow_green = "\e[38;5;106m"; col.green = "\e[38;5;34m"; col.green_cyan = "\e[38;5;36m"; col.cyan = "\e[38;5;37m"; col.cyan_blue = "\e[38;5;32m"; col.blue = "\e[38;5;21m"; col.blue_magenta = "\e[38;5;92m"; col.magenta = "\e[38;5;164m"; col.magenta_red = "\e[38;5;162m"; // bold: // ./mkw-ana testcol 500-520 520-550 550-050 050-055 055-225 225-515 515-500 // ./mkw-ana testcol 500 510 520 530 550 350 050 053 055 135 225 425 515 512 500 col.b_red = "\e[38;5;196m"; col.b_red_orange = "\e[38;5;202m"; col.b_orange = "\e[38;5;208m"; col.b_orange_yellow = "\e[38;5;214m"; col.b_yellow = "\e[38;5;226m"; col.b_yellow_green = "\e[38;5;154m"; col.b_green = "\e[38;5;46m"; col.b_green_cyan = "\e[38;5;49m"; col.b_cyan = "\e[38;5;51m"; col.b_cyan_blue = "\e[38;5;75m"; col.b_blue = "\e[38;5;105m"; col.b_blue_magenta = "\e[38;5;177m"; col.b_magenta = "\e[38;5;207m"; col.b_magenta_red = "\e[38;5;204m"; TermColorIndex_t font, bg; for ( font = 0; font < TCI__N_FONT; font++ ) for ( bg = 0; bg < TCI__N_BG; bg++ ) col.matrix[font][bg] = STRDUP(GetColorMode(COLMD_256_COLORS,font,bg,GCM_ALT|GCM_SHORT)); } return &col; //---------- old definitions ---------- // // col.differ = STRDUP(GetColorMode(COLMD_256_COLORS, // TCI_YELLOW, TCI_BLUE, GCM_ALT|GCM_SHORT )); // col.stat_line = STRDUP(GetColorMode(COLMD_256_COLORS, // TCI_WHITE, TCI_BLUE, GCM_ALT|GCM_SHORT )); // col.warn_line = STRDUP(GetColorMode(COLMD_256_COLORS, // TCI_ORANGE, TCI_BLUE, GCM_ALT|GCM_SHORT )); // // col.orange = STRDUP(GetColorMode(COLMD_256_COLORS, // TCI_ORANGE, TCI__IGNORE, GCM_ALT|GCM_SHORT )); // col.b_orange = STRDUP(GetColorMode(COLMD_256_COLORS, // TCI_B_ORANGE, TCI__IGNORE, GCM_ALT|GCM_SHORT )); // //------------------------------------- } /////////////////////////////////////////////////////////////////////////////// int setupterm(char *term, int fildes, int *errret); int tigetnum(char *capname); const ColorSet_t * GetColorSetAuto ( bool force_on ) { static ColorMode_t auto_mode = COLMD_AUTO; if ( opt_colorize != COLMD_AUTO ) { if ( opt_colorize == COLMD_ON ) force_on = true; else auto_mode = opt_colorize; } if ( auto_mode == COLMD_AUTO ) { int error; setupterm(getenv("TERM"),1,&error); const int ncol = tigetnum("colors"); auto_mode = ncol >= 256 ? COLMD_256_COLORS : ncol >= 8 ? COLMD_8_COLORS : COLMD_OFF; if ( auto_mode == COLMD_OFF && !strcmp(getenv("TERM"),"cygwin") ) auto_mode = COLMD_8_COLORS; #ifdef TEST fprintf(stderr,">>> GetColorSetAuto(%d) => \"%s\" n=%d => %d [%s]\n", force_on, getenv("TERM"), ncol, auto_mode, GetColorModeName(auto_mode,0) ); #endif } switch(auto_mode) { case COLMD_8_COLORS: return GetColorSet8(); case COLMD_256_COLORS: return GetColorSet256(); default: return force_on ? GetColorSet8() : GetColorSet0(); } } /////////////////////////////////////////////////////////////////////////////// const ColorSet_t * GetColorSet ( ColorMode_t col_mode ) { switch(col_mode) { case COLMD_AUTO: return GetColorSetAuto(false); case COLMD_ON: return GetColorSetAuto(true); case COLMD_8_COLORS: return GetColorSet8(); case COLMD_256_COLORS: return GetColorSet256(); default: return GetColorSet0(); } } /////////////////////////////////////////////////////////////////////////////// const ColorSet_t * GetFileColorSet ( FILE *f ) { return GetColorSet(GetFileColorized(f)); } /////////////////////////////////////////////////////////////////////////////// bool SetupColorSet ( ColorSet_t *cs, FILE *f ) { DASSERT(cs); memcpy(cs,GetColorSet(GetFileColorized(f)),sizeof(*cs)); return cs->colorize; } /////////////////////////////////////////////////////////////////////////////// ccp GetColorByName ( const ColorSet_t *colset, ccp name ) { struct cdef_t { u16 delta; char name[16]; }; #undef DEF1 #undef DEF2 #define DEF1(n) { offsetof(ColorSet_t,n), #n }, #define DEF2(t,n) { offsetof(ColorSet_t,n), #t }, static const struct cdef_t tab[] = { DEF1(abort) DEF1(b_black) DEF1(b_blue) DEF1(b_blue_magenta) DEF1(b_cyan) DEF1(b_cyan_blue) DEF1(b_green) DEF1(b_green_cyan) DEF1(b_magenta) DEF1(b_magenta_red) DEF1(b_orange) DEF1(b_orange_yellow) DEF1(b_red) DEF1(b_red_orange) DEF1(b_white) DEF1(b_yellow) DEF1(b_yellow_green) DEF1(bad) DEF1(black) DEF1(blue) DEF1(blue_magenta) DEF1(caption) DEF1(cite) DEF1(close) DEF1(cmd) DEF1(cyan) DEF1(cyan_blue) DEF1(debug) DEF1(differ) DEF1(error) DEF1(fail) DEF1(fail2) DEF1(fatal) DEF1(file) DEF1(finish) DEF1(green) DEF1(green_cyan) DEF2(head,heading) DEF1(heading) DEF1(hide) DEF1(highlight) DEF1(hint) DEF2(hl,highlight) DEF1(info) DEF1(job) DEF1(log) DEF1(magenta) DEF1(magenta_red) DEF1(mark) DEF1(name) DEF1(off) DEF1(on) DEF1(open) DEF2(opt,option) DEF1(option) DEF1(orange) DEF1(orange_yellow) DEF2(par,param) DEF1(param) DEF1(proc_line) DEF1(red) DEF1(red_orange) DEF1(reset) DEF1(run) DEF1(script) DEF1(section) DEF1(select) DEF1(setup) DEF1(stat_line) DEF1(status) DEF1(success) DEF1(syntax) DEF2(val,value) DEF1(value) DEF1(warn) DEF1(warn_line) DEF1(white) DEF1(yellow) DEF1(yellow_green) }; #if HAVE_PRINT static bool done = false; if (!done) { done = true; uint i, max_len = 0, err_count = 0; const struct cdef_t *cd = tab; for ( i = 0; i < sizeof(tab)/sizeof(*tab); i++, cd++ ) { if ( max_len < strlen(cd->name) ) max_len = strlen(cd->name); if ( i > 0 && strcmp(cd[-1].name,cd->name) >= 0 ) { err_count++; PRINT("WRONG COL ORDER: %s > %s\n", cd[-1].name, cd->name); } } DASSERT_MSG( max_len < sizeof(cd->name), "%s(): max name len = %d, possible = %zd\n", __FUNCTION__, max_len, sizeof(cd->name)-1 ); DASSERT_MSG( !err_count, "%s(): color order is %d* wrong!\n", __FUNCTION__, err_count ); } #endif //--- search the name if ( colset && name ) { int beg = 0; int end = sizeof(tab)/sizeof(*tab) - 1; while ( beg <= end ) { const uint idx = (beg+end)/2; const int stat = strcmp(name,tab[idx].name); if ( stat < 0 ) end = idx - 1 ; else if ( stat > 0 ) beg = idx + 1; else return *(ccp*)((u8*)colset+tab[idx].delta); } } return EmptyString; } /////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// void PrintColorSetHelper ( FILE *f, // valid output file int indent, // indention of output const ColorSet_t *cs, // valid color set; if NULL: use std colors PrintColorFunc func, // output function, never NULL uint mode // output mode (bit field, NULL=default): // 1: print normal colors (e.g. RED) // 2: print bold colors (e.g. B_RED) // 4: print background (e.g. BLUE_RED) // 8: print color names (e.g. HIGHLIGHT) // 16: include alternative names too (e.g. HL) ) { DASSERT(f); DASSERT(func); if (!cs) cs = GetColorSet(COLMD_ON); indent = NormalizeIndent(indent) + 10; // +10 is max name width if (!mode) mode = 15; #undef JOB1 #undef JOB2 #define JOB1(m,n) func(f,indent,cs,m,#n,cs->n) #define JOB2(m,t,n) func(f,indent,cs,m,#t,cs->n) if ( mode & 1 ) { func(f,indent,cs,1,0,0); JOB1(1,black); JOB1(1,red); JOB1(1,red_orange); JOB1(1,orange); JOB1(1,orange_yellow); JOB1(1,yellow); JOB1(1,yellow_green); JOB1(1,green); JOB1(1,green_cyan); JOB1(1,cyan); JOB1(1,cyan_blue); JOB1(1,blue); JOB1(1,blue_magenta); JOB1(1,magenta); JOB1(1,magenta_red); JOB1(1,white); } if ( mode & 2 ) { func(f,indent,cs,2,0,0); JOB1(2,b_black); JOB1(2,b_red); JOB1(2,b_red_orange); JOB1(2,b_orange); JOB1(2,b_orange_yellow); JOB1(2,b_yellow); JOB1(2,b_yellow_green); JOB1(2,b_green); JOB1(2,b_green_cyan); JOB1(2,b_cyan); JOB1(2,b_cyan_blue); JOB1(2,b_blue); JOB1(2,b_blue_magenta); JOB1(2,b_magenta); JOB1(2,b_magenta_red); JOB1(2,b_white); } if ( mode & 8 ) { const bool alt = ( mode & 16 ) != 0; func(f,indent,cs,8,0,0); JOB1(4,setup); JOB1(4,run); JOB1(4,abort); JOB1(4,finish); JOB1(4,script); JOB1(4,open); JOB1(4,close); JOB1(4,file); JOB1(4,job); JOB1(4,info); JOB1(4,hint); JOB1(4,warn); JOB1(4,debug); JOB1(4,log); JOB1(4,name); JOB1(4,value); if (alt) JOB2(12,val,value); JOB1(4,success); JOB1(4,error); JOB1(4,fail); JOB1(4,fail2); JOB1(4,fatal); JOB1(4,mark); JOB1(4,bad); JOB1(4,select); JOB1(4,differ); JOB1(4,stat_line); JOB1(4,warn_line); JOB1(4,proc_line); JOB1(4,cite); JOB1(4,status); JOB1(4,highlight); if (alt) JOB2(12,hl,highlight); JOB1(4,hide); JOB1(4,heading); if (alt) JOB2(12,head,heading); JOB1(4,caption); JOB1(4,section); JOB1(4,syntax); JOB1(4,cmd); JOB1(4,option); if (alt) JOB2(12,opt,option); JOB1(4,param); if (alt) JOB2(12,par,param); JOB1(4,off); JOB1(4,on); } #undef JOB1 #undef JOB2 } /////////////////////////////////////////////////////////////////////////////// static void PrintColorSetCOL ( // On start of group: col_name := NULL, col_string := NULL FILE *f, // valid output file int indent, // normalized indention of output const ColorSet_t *cs, // valid color set, never NULL uint mode, // output mode of PrintColorSetHelper() ccp col_name, // name of color ccp col_string // escape string for the color ) { if (!col_name) fputc('\n',f); else { DASSERT(col_string); #ifdef TEST fprintf(f,"%*s %s %s %s | %s %s %s\n", \ indent, col_name, col_string, col_name, cs->reset, GetColorByName(cs,col_name), col_name, cs->reset ); #else fprintf(f,"%*s %s %s %s\n", indent, col_name, col_string, col_name, cs->reset ); #endif } } //----------------------------------------------------------------------------- static void PrintColorSetSH ( // On start of group: col_name := NULL, col_string := NULL FILE *f, // valid output file int indent, // normalized indention of output const ColorSet_t *cs, // valid color set, never NULL uint mode, // output mode of PrintColorSetHelper() ccp col_name, // name of color ccp col_string // escape string for the color ) { if (col_name) { DASSERT(col_string); char name[50], buf[50]; char *dest = name; while ( *col_name && dest < name + sizeof(name) - 1 ) *dest++ = toupper((int)*col_name++); *dest = 0; PrintEscapedString(buf,sizeof(buf),col_string,-1,CHMD_ESC,0,0); if (memcmp(buf,"\\x1B",4)) fprintf(f,"COL_%s=$'%s'\n",name,buf); else fprintf(f,"COL_%s='\\033%s'\n",name,buf+4); } } //----------------------------------------------------------------------------- static void PrintColorSetPHP ( // On start of group: col_name := NULL, col_string := NULL FILE *f, // valid output file int indent, // normalized indention of output const ColorSet_t *cs, // valid color set, never NULL uint mode, // output mode of PrintColorSetHelper() ccp col_name, // name of color ccp col_string // escape string for the color ) { if (col_name) { DASSERT(col_string); char buf[50]; PrintEscapedString(buf,sizeof(buf),col_string,-1,CHMD_ESC,0,0); if (memcmp(buf,"\\x1B",4)) fprintf(f,"$COL->%-15s = \"%s\";\n",col_name,buf); else fprintf(f,"$COL->%-15s = \"\\033%s\";\n",col_name,buf+4); } } //----------------------------------------------------------------------------- void PrintColorSet ( FILE *f, // valid output file int indent, // indention of output const ColorSet_t *cs // valid color set; if NULL: use std colors ) { DASSERT(f); PrintColorSetHelper(f,indent,cs,PrintColorSetCOL,4); fputc('\n',f); } //----------------------------------------------------------------------------- void PrintColorSetEx ( FILE *f, // valid output file int indent, // indention of output const ColorSet_t *cs, // valid color set; if NULL: use std colors uint mode, // output mode => see PrintColorSetHelper() uint format // output format // 0: colored list // 1: shell definitions // 2: php class ) { DASSERT(f); char buf[50]; switch(format) { case 1: if (!cs) cs = GetColorSet(COLMD_ON); PrintColorSetHelper(f,indent,cs,PrintColorSetSH,mode); PrintEscapedString(buf,sizeof(buf),cs->reset,-1,CHMD_ESC,0,0); if (memcmp(buf,"\\x1B",4)) fprintf(f,"COL0=$'%s'\n",buf); else fprintf(f,"COL0=$'\\033%s'\n",buf+4); break; case 2: if (!cs) cs = GetColorSet(COLMD_ON); PrintColorSetHelper(f,indent,cs,PrintColorSetPHP,mode); break; default: PrintColorSetHelper(f,indent,cs,PrintColorSetCOL,mode); fputc('\n',f); break; } } // /////////////////////////////////////////////////////////////////////////////// /////////////// ViewColor*() /////////////// /////////////////////////////////////////////////////////////////////////////// void SetupColorView ( ColorView_t *cv ) { DASSERT(cv); if (!cv->f) cv->f = stdout; cv->indent = NormalizeIndent(cv->indent); #ifdef DCLIB_TERMINAL cv->col_mode = cv->colset ? cv->colset->col_mode : NormalizeColorMode(cv->col_mode, cv->term ? cv->term->colors : 8 ); #else cv->col_mode = cv->colset ? cv->colset->col_mode : NormalizeColorMode(cv->col_mode,8); #endif if (!cv->colset) cv->colset = GetColorSet(cv->col_mode); switch(cv->order) { case 'r': case 'R': cv->order = 0; break; case 'g': case 'G': cv->order = 1; break; case 'b': case 'B': cv->order = 2; break; } } /////////////////////////////////////////////////////////////////////////////// void SetupColorViewMode ( ColorView_t *cv, ColorMode_t col_mode ) { DASSERT(cv); cv->col_mode = col_mode; cv->colset = 0; SetupColorView(cv); } /////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// static ccp col_names[] = { "black:", "red:", "green:", "yellow:", "blue:", "magenta:", "cyan:", "white:", 0 }; //----------------------------------------------------------------------------- void ViewColorsAttrib8 ( ColorView_t *cv ) { DASSERT(cv); SetupColorView(cv); DASSERT(cv->colset); #ifdef TEST fprintf(cv->f,"%*s%s() %s, %u colors, mode %d, stdcol %d, order %d\n", cv->indent,"", __FUNCTION__, GetColorModeName(cv->colset->col_mode,0), cv->colset->n_colors, cv->mode, cv->std_col, cv->order ); #endif //-------------------------------------------------- fprintf(cv->f, "%s\n%*sStandard font colors with attributes (ul=underline) for mode %s:\n\n", cv->colset->reset, cv->indent, "", GetColorModeName(cv->col_mode,0) ); uint fg = 0, bg = 0; switch( (int)cv->std_col ) { case TCI_BLACK: case TCI_DARKGRAY: fg = TTM_WHITE|TTM_BOLD; bg = TTM_BG_BLACK; break; case TCI_LIGHTGRAY: case TCI_WHITE: fg = TTM_BLACK; bg = TTM_BG_WHITE; break; case TCI_RED: case TCI_B_RED: case TCI_ORANGE: case TCI_B_ORANGE: fg = TTM_WHITE|TTM_BOLD; bg = TTM_BG_RED; break; case TCI_YELLOW: case TCI_B_YELLOW: fg = TTM_BLACK; bg = TTM_BG_YELLOW; break; case TCI_GREEN: case TCI_B_GREEN: fg = TTM_WHITE|TTM_BOLD; bg = TTM_BG_GREEN; break; case TCI_CYAN: case TCI_B_CYAN: fg = TTM_BLACK; bg = TTM_BG_CYAN; break; case TCI_BLUE: case TCI_B_BLUE: fg = TTM_WHITE|TTM_BOLD; bg = TTM_BG_BLUE; break; case TCI_MAGENTA: case TCI_B_MAGENTA: fg = TTM_WHITE|TTM_BOLD; bg = TTM_BG_MAGENTA; break; } ccp *cname; TermTextMode_t mode = TTM_BLACK; for ( cname = col_names; *cname; cname++, mode += 0x01 ) { fprintf(cv->f,"%*s%s %u %-9s %snormal %sbold %sbold+ul %sul%s reset %s\n", cv->indent, "", GetTextMode(cv->col_mode,fg|bg), (int)(cname - col_names) + 30, *cname, GetTextMode(cv->col_mode,bg|mode), GetTextMode(cv->col_mode,bg|TTM_BOLD), GetTextMode(cv->col_mode,bg|TTM_UL), GetTextMode(cv->col_mode,bg|TTM_NO_BOLD), GetTextMode(cv->col_mode,bg|TTM_RESET), cv->colset->reset ); } //-------------------------------------------------- fprintf(cv->f, "\n%*sStandard background colors with attributes (ul=underline) for mode %s:\n\n", cv->indent, "", GetColorModeName(cv->col_mode,0) ); mode = TTM_BG_BLACK; for ( cname = col_names; *cname; cname++, mode += 0x10 ) { fprintf(cv->f,"%*s %u %-9s %s white %s bold %sul%s black %sbold %sul%s %s\n", cv->indent, "", (int)(cname - col_names) + 40, *cname, GetTextMode(cv->col_mode,mode|TTM_WHITE), GetTextMode(cv->col_mode,TTM_BOLD), GetTextMode(cv->col_mode,TTM_UL|TTM_NO_BOLD), GetTextMode(cv->col_mode,mode|TTM_BLACK|TTM_RESET), GetTextMode(cv->col_mode,TTM_BOLD), GetTextMode(cv->col_mode,TTM_UL|TTM_NO_BOLD), GetTextMode(cv->col_mode,TTM_NO_UL), GetTextMode(cv->col_mode,TTM_RESET) ); } } /////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// void ViewColorsCombi8 ( ColorView_t *cv ) { DASSERT(cv); SetupColorView(cv); DASSERT(cv->colset); #ifdef TEST fprintf(cv->f,"%*s%s() %s, %u colors, mode %d, stdcol %d, order %d\n", cv->indent,"", __FUNCTION__, GetColorModeName(cv->colset->col_mode,0), cv->colset->n_colors, cv->mode, cv->std_col, cv->order ); #endif fprintf(cv->f, "%s\n%*sFont and background color combinations (no=normal, bo=bold) for mode %s:\n\n", cv->colset->reset, cv->indent, "", GetColorModeName(cv->col_mode,0) ); uint mode = TTM_BG_BLACK; ccp *cname; for ( cname = col_names; *cname; cname++, mode += 0x10 ) { fprintf(cv->f,"%*s %u %-9s ", cv->indent, "", (int)(cname - col_names) + 40, *cname ); TermTextMode_t mode2; for ( mode2 = TTM_BLACK; mode2 <= TTM_WHITE; mode2++ ) fprintf(cv->f,"%s no %sbo ", GetTextMode(cv->col_mode,mode|mode2|TTM_NO_BOLD), GetTextMode(cv->col_mode,TTM_BOLD) ); fprintf(cv->f," %s\n",cv->colset->reset ); } } /////////////////////////////////////////////////////////////////////////////// void ViewColors18 ( ColorView_t *cv ) { DASSERT(cv); SetupColorView(cv); DASSERT(cv->colset); #ifdef TEST fprintf(cv->f,"%*s%s() %s, %u colors, mode %d, stdcol %d, order %d\n", cv->indent,"", __FUNCTION__, GetColorModeName(cv->colset->col_mode,0), cv->colset->n_colors, cv->mode, cv->std_col, cv->order ); #endif GetColorOption_t col_option = cv->col_option & ~GCM_ALT; fprintf(cv->f, "%s\n%*s18x18 color table ('0'=std, '1'=optimized%s) for mode %s:\n\n", cv->colset->reset, cv->indent, "", col_option & GCM_SHORT ? "; allow short codes" : "", GetColorModeName(cv->col_mode,0) ); const int *pbg; for ( pbg = Color18Index; *pbg >= 0; pbg++ ) { uint bg = *pbg; if ( bg == TCI_RED || bg == TCI_B_RED ) fputc('\n',cv->f); fprintf(cv->f,"%*s %-12s ", cv->indent, "", ColorIndexName[bg] ); const int *pfont; for ( pfont = Color18Index; *pfont >= 0; pfont++ ) { uint font = *pfont; if ( font == TCI_RED || font == TCI_B_RED ) fprintf(cv->f," %s ",TERM_TEXT_MODE_RESET); fprintf(cv->f,"%s 0%s1", GetColorMode(cv->col_mode,font,bg,col_option), GetColorMode(cv->col_mode,font,bg,col_option|GCM_ALT) ); } fprintf(cv->f," %s\n",TERM_TEXT_MODE_RESET); } } /////////////////////////////////////////////////////////////////////////////// void ViewColorsDC ( ColorView_t *cv, bool optimized ) { DASSERT(cv); SetupColorView(cv); DASSERT(cv->colset); #ifdef TEST fprintf(cv->f,"%*s%s() %s, %u colors, mode %d, stdcol %d, order %d\n", cv->indent,"", __FUNCTION__, GetColorModeName(cv->colset->col_mode,0), cv->colset->n_colors, cv->mode, cv->std_col, cv->order ); #endif GetColorOption_t col_option = cv->col_option & ~GCM_ALT; if (optimized) col_option |= GCM_ALT; fprintf(cv->f, "%s\n%*s%ux%u color table (%s%s) for mode %s:\n\n", cv->colset->reset, cv->indent, "", TCI__N, TCI__N, optimized ? "optimized" : "standard", col_option & GCM_SHORT ? "; allow short codes" : "", GetColorModeName(cv->col_mode,0) ); uint bg; for ( bg = 0; bg < TCI__N; bg++ ) { if ( bg == TCI_RED || bg == TCI_B_RED ) fputc('\n',cv->f); fprintf(cv->f,"%*s %-15s ", cv->indent, "", ColorIndexName[bg] ); ccp fill = " "; uint font; for ( font = 0; font < TCI__N; font++ ) { if ( font == TCI_RED || font == TCI_B_RED ) { fprintf(cv->f," %s ",TERM_TEXT_MODE_RESET); fill = " "; } fprintf(cv->f,"%s%sx", GetColorMode(cv->col_mode,font,bg,col_option), fill ); fill = ""; } fprintf(cv->f," %s\n",TERM_TEXT_MODE_RESET); } } /////////////////////////////////////////////////////////////////////////////// static void ViewColors256_helper ( ColorView_t *cv, // basic data uint beg, // first color printed uint end, // first color not printed uint step // increment ) { if ( cv->colset->n_colors < 8 ) { uint i; for ( i = beg; i < end; i += step ) fprintf(cv->f," %03u ",i); } #if 0 // [[2do]] else if ( cv->colset->n_colors < 256 ) { } #endif else { const int mode = cv->mode & 1 ? 48 : 38; uint i; for ( i = beg; i < end; i += step ) fprintf(cv->f,"\e[%u;5;%um %03u ",mode,i,i); fputs("\e[0m",cv->f); } } //----------------------------------------------------------------------------- void ViewColors256 ( ColorView_t *cv ) { DASSERT(cv); SetupColorView(cv); DASSERT(cv->colset); #ifdef TEST fprintf(cv->f,"%*s%s() %s, %u colors, mode %d, stdcol %d, order %d\n", cv->indent,"", __FUNCTION__, GetColorModeName(cv->colset->col_mode,0), cv->colset->n_colors, cv->mode, cv->std_col, cv->order ); #endif fprintf(cv->f, "%s\n%*s256 colors = 16 std colors + 6x6x6 colors + 24 gray for mode %s:\n", cv->colset->reset, cv->indent, "", GetColorModeName(cv->col_mode,0) ); int step, inc_horz, inc_vert; switch (cv->order) { case 1: step = 1; inc_horz = 6; inc_vert = 36; break; case 2: step = 6; inc_horz = 1; inc_vert = 36; break; default: step = 1; inc_horz = 36; inc_vert = 6; break; } //--- 16 standard colors in 2 rows fprintf(cv->f,"\n%*s ",cv->indent,""); ViewColors256_helper(cv,0,8,1); fprintf(cv->f,"\n%*s ",cv->indent,""); ViewColors256_helper(cv,8,16,1); fputs("\e[0m\n\n",cv->f); uint bl, num = 16; for ( bl = 0; bl < 3; bl++ ) { uint i, n = num; for ( i = 0; i < 6; i++ ) { fprintf(cv->f,"%*s ",cv->indent,""); ViewColors256_helper(cv,n,n+6*step,step); fputs(" ",cv->f); ViewColors256_helper(cv,n+inc_horz,n+inc_horz+6*step,step); fputc('\n',cv->f); n += inc_vert; } fputc('\n',cv->f); num += 2*inc_horz; } fprintf(cv->f,"%*s ",cv->indent,""); ViewColors256_helper(cv,232,232+12,1); fprintf(cv->f,"\n%*s ",cv->indent,""); ViewColors256_helper(cv,232+12,232+24,1); fputs("\e[0m\n",cv->f); } /////////////////////////////////////////////////////////////////////////////// static void ViewColorsPredef_helper ( ColorView_t *cv, // basic data ccp col_name, // name of color ccp col_string // escape string for the color ) { DASSERT(cv); DASSERT(col_string); if ( col_string && *col_string ) fprintf(cv->f,"%*s %s %-15s %s \\e%s\n", cv->indent, col_name, col_string, col_name, cv->colset->reset, col_string+1 ); else fprintf(cv->f,"%*s %s\n", cv->indent, col_name, col_name ); } //----------------------------------------------------------------------------- void ViewColorsPredef ( ColorView_t *cv, uint mode ) { DASSERT(cv); SetupColorView(cv); DASSERT(cv->colset); #ifdef TEST fprintf(cv->f,"%*s%s() %s, %u colors, mode %d, stdcol %d, order %d\n", cv->indent,"", __FUNCTION__, GetColorModeName(cv->colset->col_mode,0), cv->colset->n_colors, cv->mode, cv->std_col, cv->order ); #endif fprintf(cv->f, "%s\n%*sPredefined%s color names for mode %s:\n\n", cv->colset->reset, cv->indent, "", ( mode & 3 ) == 1 ? " semantic" : "", GetColorModeName(cv->col_mode,0) ); cv->indent += 14; #undef JOB1 #undef JOB2 #define JOB1(n) ViewColorsPredef_helper(cv,#n,cv->colset->n) #define JOB2(n,c) ViewColorsPredef_helper(cv,#n,cv->colset->c) if ( mode & 1 ) { const bool alt = cv->mode & 1; JOB1(setup); JOB1(run); JOB1(abort); JOB1(finish); JOB1(script); JOB1(open); JOB1(close); JOB1(file); JOB1(job); JOB1(info); JOB1(hint); JOB1(warn); JOB1(debug); JOB1(log); JOB1(name); JOB1(value); if (alt) JOB2(val,value); JOB1(success); JOB1(error); JOB1(fail); JOB1(fail2); JOB1(fatal); JOB1(mark); JOB1(bad); JOB1(select); JOB1(differ); JOB1(stat_line); JOB1(warn_line); JOB1(proc_line); JOB1(cite); JOB1(status); JOB1(highlight); if (alt) JOB2(hl,highlight); JOB1(hide); JOB1(heading); JOB1(caption); JOB1(section); JOB1(syntax); JOB1(cmd); JOB1(option); if (alt) JOB2(opt,option); JOB1(param); if (alt) JOB2(par,param); JOB1(off); JOB1(on); } if ( mode & 2 ) { if ( mode & 1 ) fputc('\n',cv->f); JOB1(black); JOB1(b_black); JOB1(white); JOB1(b_white); if ( !(mode & 1) ) fputc('\n',cv->f); JOB1(red); JOB1(red_orange); JOB1(orange); JOB1(orange_yellow); JOB1(yellow); JOB1(yellow_green); JOB1(green); JOB1(green_cyan); JOB1(cyan); JOB1(cyan_blue); JOB1(blue); JOB1(blue_magenta); JOB1(magenta); JOB1(magenta_red); JOB1(red); if ( !(mode & 1) ) fputc('\n',cv->f); JOB1(b_red); JOB1(b_red_orange); JOB1(b_orange); JOB1(b_orange_yellow); JOB1(b_yellow); JOB1(b_yellow_green); JOB1(b_green); JOB1(b_green_cyan); JOB1(b_cyan); JOB1(b_cyan_blue); JOB1(b_blue); JOB1(b_blue_magenta); JOB1(b_magenta); JOB1(b_magenta_red); JOB1(b_red); } #undef JOB1 #undef JOB2 cv->indent -= 14; } // /////////////////////////////////////////////////////////////////////////////// /////////////// old color views (wrapper) /////////////// /////////////////////////////////////////////////////////////////////////////// void PrintTextModes ( FILE *f, // valid output file int indent, // indention of output ColorMode_t col_mode // color mode ) { ColorView_t cv; InitializeColorView(&cv); cv.f = f; cv.indent = indent; cv.col_mode = col_mode; ViewColorsAttrib8(&cv); ViewColorsCombi8(&cv); } /////////////////////////////////////////////////////////////////////////////// void PrintColorModes ( FILE *f, // valid output file int indent, // indention of output ColorMode_t col_mode, // color mode -> NormalizeColorMode() GetColorOption_t option // execution options (GCM_ALT ignored) ) { ColorView_t cv; InitializeColorView(&cv); cv.f = f; cv.indent = indent; cv.col_mode = col_mode; cv.col_option = option; ViewColors18(&cv); } // /////////////////////////////////////////////////////////////////////////////// /////////////// stdout, stderr, stdlog and colors /////////////// /////////////////////////////////////////////////////////////////////////////// FILE *stdlog = 0; // NULL or logfile bool close_stdlog = 0; // true: close file behing 'stdlog' FILE *stdmsg = 0; // 'stdlog' or 'stdout' or 'stderr' or NULL FILE *stdwrn = 0; // used by PrintError(), initialized with 'stderr' ColorMode_t colorize_stdout = COLMD_AUTO; ColorMode_t colorize_stderr = COLMD_AUTO; ColorMode_t colorize_stdlog = COLMD_AUTO; ColorMode_t colorize_stdmsg = COLMD_AUTO; ColorMode_t colorize_stdwrn = COLMD_AUTO; const ColorSet_t *colout = 0; // color set for 'stdout' const ColorSet_t *colerr = 0; // color set for 'stderr' const ColorSet_t *collog = 0; // color set for 'stdlog' const ColorSet_t *colmsg = 0; // color set for 'stdmsg' const ColorSet_t *colwrn = 0; // color set for 'stdwrn' /////////////////////////////////////////////////////////////////////////////// ColorMode_t GetFileColorized ( FILE *f ) { if (!stdmsg) SetupStdMsg(); return !f ? COLMD_OFF : f == stdlog && colorize_stdlog != COLMD_AUTO ? colorize_stdlog : f == stdout && colorize_stdout != COLMD_AUTO ? colorize_stdout : f == stderr && colorize_stderr != COLMD_AUTO ? colorize_stderr : f == stdmsg && colorize_stdmsg != COLMD_AUTO ? colorize_stdmsg : f == stdwrn && colorize_stdwrn != COLMD_AUTO ? colorize_stdwrn : opt_colorize >= COLMD_ON ? opt_colorize : opt_colorize == COLMD_AUTO && isatty(fileno(f)) ? COLMD_AUTO : COLMD_OFF; } /////////////////////////////////////////////////////////////////////////////// void SetupStdMsg() { //--- setup static bool active = false; // avoid loops if (!active) { active = true; stdwrn = stderr; colwrn = colerr; colorize_stdwrn = colorize_stderr; if (!colout) { colorize_stdout = GetFileColorized(stdout); colout = GetColorSet(colorize_stdout); } if (!colerr) { colorize_stderr = GetFileColorized(stderr); colerr = GetColorSet(colorize_stderr); } if (!collog) { colorize_stdlog = GetFileColorized(stdlog); collog = GetColorSet(colorize_stdlog); } active = false; } //--- assign to msg if (stdlog) { stdmsg = stdlog; colmsg = collog; colorize_stdmsg = colorize_stdlog; } else if (stdout) { stdmsg = stdout; colmsg = colout; colorize_stdmsg = colorize_stdout; } else if (stderr) { stdmsg = stderr; colmsg = colerr; colorize_stdmsg = colorize_stderr; } else { stdmsg = 0; colmsg = GetColorSet0(); colorize_stdmsg = 0; } noPRINT("SetupStdMsg() : out=%d[%zd], err=%d[%zd], log=%d[%zd], msg=%d[%zd]\n", colorize_stdout, colout ? strlen(colout->reset) : -1, colorize_stderr, colerr ? strlen(colerr->reset) : -1, colorize_stdlog, collog ? strlen(collog->reset) : -1, colorize_stdmsg, colmsg ? strlen(colmsg->reset) : -1 ); } /////////////////////////////////////////////////////////////////////////////// enumError OpenStdLog ( ccp fname, // If NULL or empty: don't open and use 'fallback' // If first char == '+': open file in append mode FILE *fallback // Fall back to this file, if no file name given // If NULL: just clode 'stdlog'. ) { CloseStdLog(); bool append = fname && *fname == '+'; if (append) fname++; if ( !fname || !*fname ) { if (fallback) { stdlog = fallback; colorize_stdlog = GetFileColorized(stdlog); PRINT("COLORIZE/LOG/FALLBACK: opt=%d, out=%d, err=%d, log=%d\n", opt_colorize, colorize_stdout, colorize_stderr, colorize_stdlog ); } } else { if (!strcmp(fname,"-")) { stdlog = stdout; colorize_stdlog = colorize_stdout; } else { stdlog = fopen( fname, append ? "ab" : "wb" ); if (!stdlog) return ERROR1(ERR_CANT_CREATE, "Can't open log file (mode=%s): %s\n", append ? "append" : "create", fname ); close_stdlog = true; colorize_stdlog = GetFileColorized(stdlog); } PRINT("COLORIZE/LOG: opt=%d, out=%d, err=%d, log=%d\n", opt_colorize, colorize_stdout, colorize_stderr, colorize_stdlog ); } collog = GetColorSet(colorize_stdlog); SetupStdMsg(); return ERR_OK; } /////////////////////////////////////////////////////////////////////////////// void CloseStdLog() { if (stdlog) { if (close_stdlog) fclose(stdlog); else fflush(stdlog); stdlog = 0; } close_stdlog = false; colorize_stdlog = 0; collog = GetColorSet0(); SetupStdMsg(); } /////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// void SaveStdFiles ( SavedStdFiles_t *ssf ) { DASSERT(ssf); ssf->std_out = stdout; ssf->std_err = stderr; ssf->std_log = stdlog; ssf->std_msg = stdmsg; ssf->std_wrn = stdwrn; ssf->col_out = colout; ssf->col_err = colerr; ssf->col_log = collog; ssf->col_msg = colmsg; ssf->col_wrn = colwrn; ssf->stdout_seq_count = stdout_seq_count; ssf->f = 0; ssf->data = 0; ssf->size = 0; ssf->marker = 0; } /////////////////////////////////////////////////////////////////////////////// void RestoreStdFiles ( SavedStdFiles_t *ssf ) { DASSERT(ssf); stdout = ssf->std_out; stderr = ssf->std_err; stdlog = ssf->std_log; stdmsg = ssf->std_msg; stdwrn = ssf->std_wrn; colout = ssf->col_out; colerr = ssf->col_err; collog = ssf->col_log; colmsg = ssf->col_msg; colwrn = ssf->col_wrn; stdout_seq_count = ssf->stdout_seq_count; } /////////////////////////////////////////////////////////////////////////////// void RedirectStdFiles ( SavedStdFiles_t *ssf, // not NULL: save old output here FILE *f, // use this as out,err,log and msg, never NULL const ColorSet_t *colset,// new colset; if NULL: use GetFileColorSet(f) bool err_too // true: redirect stderr too ) { DASSERT(f); if (ssf) SaveStdFiles(ssf); stdout = stdwrn = stdmsg = f; colout = colwrn = colmsg = colset ? colset : GetFileColorSet(f); // special handling for stdlog if (stdlog) { stdlog = stdout; collog = colout; } if (err_too) { stderr = stdout; colerr = colout; } } /////////////////////////////////////////////////////////////////////////////// #ifndef __APPLE__ enumError CatchStdFiles ( SavedStdFiles_t *ssf, // save old output and data here, never NULL const ColorSet_t *colset // new colset; if NULL: no color support ) { DASSERT(ssf); SaveStdFiles(ssf); FILE *f = open_memstream(&ssf->data,&ssf->size); if (!f) return ERR_CANT_CREATE; ssf->f = f; RedirectStdFiles(0,f,colset,false); return ERR_OK; } #endif // !__APPLE__ /////////////////////////////////////////////////////////////////////////////// void TermCatchStdFiles ( SavedStdFiles_t *ssf ) { DASSERT(ssf); RestoreStdFiles(ssf); if (ssf->f) { fclose(ssf->f); ssf->f = 0; } } // /////////////////////////////////////////////////////////////////////////////// /////////////// END /////////////// ///////////////////////////////////////////////////////////////////////////////