From 3c61ef860dab376e958b1f5c1ffbdf136c6780cb Mon Sep 17 00:00:00 2001 From: Jason Hood Date: Thu, 28 Dec 2017 12:47:09 +1000 Subject: [PATCH] Improve palette usage Support the entire 256-color palette. When specifying an index or RGB color, find the nearest match in the console palette. Preserve bold and underline when setting color by index. Getting all palette entries will stop at 15 if the initial index is below that (i.e. `0;*` will get 0 to 15 and `16;*` will get 16 to 255). --- ANSI.c | 231 ++++++++++++++++++++++++++++++++++++-------------- ansicon.c | 2 +- palette.h | 58 +++++++++++++ readme.txt | 11 ++- sequences.txt | 20 +++-- 5 files changed, 247 insertions(+), 75 deletions(-) create mode 100644 palette.h diff --git a/ANSI.c b/ANSI.c index 00811ad..ae894aa 100644 --- a/ANSI.c +++ b/ANSI.c @@ -180,12 +180,13 @@ added DECSTR & RIS; fix state problems with windowless processes. - v1.81-wip, 26 December, 2017: + v1.81-wip, 26 to 28 December, 2017: combine multiple CRs as one (to ignore all CRs before LF); don't process CR or BS during CRM; don't flush CR immediately (to catch following LF); fix CRM with all partial RM sequences; - check for the empty buffer within the critical section. + check for the empty buffer within the critical section; + palette improvements. */ #include "ansicon.h" @@ -229,7 +230,7 @@ TCHAR suffix2; // escape sequence intermediate byte int ibytes; // count of intermediate bytes int es_argc; // escape sequence args count int es_argv[MAX_ARG]; // escape sequence args -TCHAR Pt_arg[MAX_PATH*2]; // text parameter for Operating System Command +TCHAR Pt_arg[4096]; // text parameter for Operating System Command int Pt_len; BOOL shifted, G0_special, SaveG0; BOOL awm = TRUE; // autowrap mode @@ -369,6 +370,12 @@ typedef BOOL (WINAPI *PHCSBIX)( PHCSBIX GetConsoleScreenBufferInfoX, SetConsoleScreenBufferInfoX; +BOOL WINAPI GetConsoleScreenBufferInfoEx_repl( HANDLE h, + PCONSOLE_SCREEN_BUFFER_INFOX i ) +{ + return FALSE; +} + typedef struct _CONSOLE_FONT_INFOX { ULONG cbSize; @@ -426,7 +433,8 @@ typedef struct SHORT top_margin; SHORT bot_margin; COORD SavePos; // saved cursor position - COLORREF palette[16]; + COLORREF o_palette[16]; // original palette, for resetting + COLORREF x_palette[240]; // xterm 256-color palette, less 16 system colors SHORT buf_width; // buffer width prior to setting 132 columns SHORT win_width; // window width prior to setting 132 columns BYTE noclear; // don't clear the screen on column mode change @@ -439,6 +447,8 @@ PSTATE pState = &default_state; BOOL valid_state; HANDLE hMap; +#include "palette.h" + void set_ansicon( PCONSOLE_SCREEN_BUFFER_INFO ); @@ -480,26 +490,30 @@ void get_state( void ) FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL ); csbix.cbSize = sizeof(csbix); - if (GetConsoleScreenBufferInfoX && - GetConsoleScreenBufferInfoX( hConOut, &csbix )) + if (GetConsoleScreenBufferInfoX( hConOut, &csbix )) { Info.dwSize = csbix.dwSize; ATTR = csbix.wAttributes; WIN = csbix.srWindow; - memcpy( pState->palette, csbix.ColorTable, sizeof(csbix.ColorTable) ); + memcpy( pState->o_palette, csbix.ColorTable, sizeof(csbix.ColorTable) ); } - else if (!GetConsoleScreenBufferInfo( hConOut, &Info )) + else { - DEBUGSTR( 1, "Failed to get screen buffer info (%u) - assuming defaults", - GetLastError() ); - ATTR = 7; - WIDTH = 80; - HEIGHT = 300; - WIN.Left = 0; - WIN.Right = 79; - TOP = 0; - BOTTOM = 24; + memcpy( pState->o_palette, legacy_palette, sizeof(legacy_palette) ); + if (!GetConsoleScreenBufferInfo( hConOut, &Info )) + { + DEBUGSTR( 1, "Failed to get screen buffer info (%u) - assuming defaults", + GetLastError() ); + ATTR = 7; + WIDTH = 80; + HEIGHT = 300; + WIN.Left = 0; + WIN.Right = 79; + TOP = 0; + BOTTOM = 24; + } } + memcpy( pState->x_palette, xterm_palette, sizeof(xterm_palette) ); if (GetEnvironmentVariable( L"ANSICON_REVERSE", NULL, 0 )) { SetEnvironmentVariable( L"ANSICON_REVERSE", NULL ); @@ -985,7 +999,7 @@ void send_palette_sequence( COLORREF c ) r = GetRValue( c ); g = GetGValue( c ); b = GetBValue( c ); - if ((c & 0x0F0F0F) == ((c & 0xF0F0F0) >> 4)) + if ((c & 0x0F0F0F) == ((c >> 4) & 0x0F0F0F)) wsprintf( buf, L"#%X%X%X", r & 0xF, g & 0xF, b & 0xF ); else wsprintf( buf, L"#%02X%02X%02X", r, g, b ); @@ -1005,6 +1019,49 @@ void init_tabs( int size ) } +// Find the "distance" between two colors. +// https://www.compuphase.com/cmetric.htm +int color_distance( COLORREF c1, COLORREF c2 ) +{ + int rmean = (GetRValue( c1 ) + GetRValue( c2 )) / 2; + int r = GetRValue( c1 ) - GetRValue( c2 ); + int g = GetGValue( c1 ) - GetGValue( c2 ); + int b = GetBValue( c1 ) - GetBValue( c2 ); + return (((512 + rmean) * r * r) >> 8) + + 4 * g * g + + (((767 - rmean) * b * b) >> 8); +} + +// Find the nearest color to a system color. +int find_nearest_color( COLORREF col ) +{ + int d, d_min; + int i, idx; + CONSOLE_SCREEN_BUFFER_INFOX csbix; + const COLORREF* table; + + csbix.cbSize = sizeof(csbix); + table = (GetConsoleScreenBufferInfoX( hConOut, &csbix )) + ? csbix.ColorTable : legacy_palette; + + d_min = color_distance( col, table[0] ); + if (d_min == 0) return 0; + idx = 0; + for (i = 1; i < 16; ++i) + { + d = color_distance( col, table[i] ); + if (d < d_min) + { + if (d == 0) return i; + d_min = d; + idx = i; + } + } + + return idx; +} + + // ========== Reset void InterpretEscSeq( void ); @@ -1043,14 +1100,14 @@ void Reset( BOOL hard ) InterpretEscSeq(); screen_top = -1; csbix.cbSize = sizeof(csbix); - if (GetConsoleScreenBufferInfoX && - GetConsoleScreenBufferInfoX( hConOut, &csbix )) + if (GetConsoleScreenBufferInfoX( hConOut, &csbix )) { - memcpy( csbix.ColorTable, pState->palette, sizeof(csbix.ColorTable) ); + memcpy( csbix.ColorTable, pState->o_palette, sizeof(csbix.ColorTable) ); ++csbix.srWindow.Right; ++csbix.srWindow.Bottom; SetConsoleScreenBufferInfoX( hConOut, &csbix ); } + memcpy( pState->x_palette, xterm_palette, sizeof(xterm_palette) ); } } @@ -1206,6 +1263,10 @@ void InterpretEscSeq( void ) if (suffix2 == 0 || suffix2 == '+') switch (suffix) { case 'm': // SGR + { + BYTE b = FOREGROUND_INTENSITY; + BYTE u = BACKGROUND_INTENSITY; + if (es_argc == 0) es_argc++; // ESC[m == ESC[0m for (i = 0; i < es_argc; i++) { @@ -1232,26 +1293,42 @@ void InterpretEscSeq( void ) // only one parameter, which is divided into elements. So where // xterm does "38;2;R;G;B" it should really be "38:2:I:R:G:B" (I is // a color space identifier). - if (i+1 < es_argc) + if (++i < es_argc) { - if (es_argv[i+1] == 2) // rgb - i += 4; - else if (es_argv[i+1] == 5) // index + COLORREF col = CLR_INVALID; + int idx = -1; + int arg = es_argv[i-1]; + + if (es_argv[i] == 2) // rgb { - if (i+2 < es_argc && es_argv[i+2] < 16) + if (i+3 < es_argc) + col = RGB( es_argv[i+1], es_argv[i+2], es_argv[i+3] ); + i += 3; + } + else if (es_argv[i] == 5) // index + { + if (++i < es_argc) { - if (es_argv[i] == 38) - { - pState->sgr.foreground = es_argv[i+2]; - pState->sgr.bold = es_argv[i+2] & FOREGROUND_INTENSITY; - } - else - { - pState->sgr.background = es_argv[i+2]; - pState->sgr.underline = es_argv[i+2] & BACKGROUND_INTENSITY; - } + if (es_argv[i] < 16) + idx = es_argv[i]; + else if (es_argv[i] < 256) + col = pState->x_palette[es_argv[i] - 16]; + } + } + if (col != CLR_INVALID) + idx = attr2ansi[find_nearest_color( col )]; + if (idx != -1) + { + if (arg == 38) + { + pState->sgr.foreground = idx; + b = 0; + } + else + { + pState->sgr.background = idx; + u = 0; } - i += 2; } } } @@ -1308,20 +1385,22 @@ void InterpretEscSeq( void ) case 28: pState->sgr.concealed = 0; break; } } + b &= pState->sgr.bold; + u &= pState->sgr.underline; if (pState->sgr.concealed) { if (pState->sgr.rvideo) { attribut = foregroundcolor[pState->sgr.foreground] | backgroundcolor[pState->sgr.foreground]; - if (pState->sgr.bold) + if (b) attribut |= FOREGROUND_INTENSITY | BACKGROUND_INTENSITY; } else { attribut = foregroundcolor[pState->sgr.background] | backgroundcolor[pState->sgr.background]; - if (pState->sgr.underline) + if (u) attribut |= FOREGROUND_INTENSITY | BACKGROUND_INTENSITY; } } @@ -1329,17 +1408,16 @@ void InterpretEscSeq( void ) { attribut = foregroundcolor[pState->sgr.background] | backgroundcolor[pState->sgr.foreground]; - if (pState->sgr.bold) - attribut |= BACKGROUND_INTENSITY; - if (pState->sgr.underline) - attribut |= FOREGROUND_INTENSITY; + if (b) attribut |= BACKGROUND_INTENSITY; + if (u) attribut |= FOREGROUND_INTENSITY; } else - attribut = foregroundcolor[pState->sgr.foreground] | pState->sgr.bold - | backgroundcolor[pState->sgr.background] | pState->sgr.underline; + attribut = foregroundcolor[pState->sgr.foreground] | b + | backgroundcolor[pState->sgr.background] | u; if (pState->sgr.reverse) attribut = ((attribut >> 4) & 15) | ((attribut & 15) << 4); SetConsoleTextAttribute( hConOut, attribut ); + } return; case 'J': // ED @@ -1788,9 +1866,8 @@ void InterpretEscSeq( void ) { CONSOLE_SCREEN_BUFFER_INFOX csbix; csbix.cbSize = sizeof(csbix); - if (!GetConsoleScreenBufferInfoX || - !GetConsoleScreenBufferInfoX( hConOut, &csbix )) - return; + if (!GetConsoleScreenBufferInfoX( hConOut, &csbix )) + memcpy( csbix.ColorTable, legacy_palette, sizeof(legacy_palette) ); if (es_argv[0] == 4) { BYTE r, g, b; @@ -1800,7 +1877,7 @@ void InterpretEscSeq( void ) for (beg = Pt_arg;; beg = end + 1) { i = (int)wcstoul( beg, &end, 10 ); - if (end == beg || (*end != ';' && *end != '\0') || i >= 16) + if (end == beg || (*end != ';' && *end != '\0') || i >= 256) break; if (end[2] == ';' || end[2] == '\0') { @@ -1809,11 +1886,18 @@ void InterpretEscSeq( void ) SendSequence( L"\33]4;" ); end[1] = '\0'; SendSequence( beg ); - for (; i < 16; ++i) - { - send_palette_sequence( csbix.ColorTable[attr2ansi[i]] ); - SendSequence( (i == 15) ? L"\a" : L"," ); - } + if (i < 16) + for (; i < 16; ++i) + { + send_palette_sequence( csbix.ColorTable[attr2ansi[i]] ); + SendSequence( (i == 15) ? L"\a" : L"," ); + } + else + for (; i < 256; ++i) + { + send_palette_sequence( pState->x_palette[i - 16] ); + SendSequence( (i == 255) ? L"\a" : L"," ); + } } else if (end[1] == '?') { @@ -1825,7 +1909,8 @@ void InterpretEscSeq( void ) SendSequence( L";" ); end[1] = '\0'; SendSequence( beg ); - send_palette_sequence( csbix.ColorTable[attr2ansi[i]] ); + send_palette_sequence( (i < 16) ? csbix.ColorTable[attr2ansi[i]] + : pState->x_palette[i - 16] ); } else break; @@ -1905,8 +1990,13 @@ void InterpretEscSeq( void ) } } if (valid) - csbix.ColorTable[attr2ansi[i++]] = RGB( r, g, b ); - if (*end != ',' || i == 16) + { + if (i < 16) + csbix.ColorTable[attr2ansi[i++]] = RGB( r, g, b ); + else + pState->x_palette[i++ - 16] = RGB( r, g, b ); + } + if (*end != ',' || i == 256) { while (*end != ';' && *end != '\0') ++end; @@ -1924,25 +2014,36 @@ void InterpretEscSeq( void ) { // Reset each index, or the entire palette. if (Pt_len == 0) - memcpy( csbix.ColorTable, pState->palette, sizeof(csbix.ColorTable) ); + { + memcpy(csbix.ColorTable, pState->o_palette, sizeof(csbix.ColorTable)); + memcpy( pState->x_palette, xterm_palette, sizeof(xterm_palette) ); + } else { LPTSTR beg, end; for (beg = Pt_arg;; beg = end + 1) { i = (int)wcstoul( beg, &end, 10 ); - if (end == beg || (*end != ';' && *end != '\0') || i >= 16) + if (end == beg || (*end != ';' && *end != '\0') || i >= 256) break; - i = attr2ansi[i]; - csbix.ColorTable[i] = pState->palette[i]; + if (i < 16) + { + i = attr2ansi[i]; + csbix.ColorTable[i] = pState->o_palette[i]; + } + else + pState->x_palette[i - 16] = xterm_palette[i - 16]; if (*end == '\0') break; } } } - ++csbix.srWindow.Right; - ++csbix.srWindow.Bottom; - SetConsoleScreenBufferInfoX( hConOut, &csbix ); + if (SetConsoleScreenBufferInfoX) + { + ++csbix.srWindow.Right; + ++csbix.srWindow.Bottom; + SetConsoleScreenBufferInfoX( hConOut, &csbix ); + } } } } @@ -3709,6 +3810,8 @@ BOOL WINAPI DllMain( HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved ) hKernel = GetModuleHandleA( APIKernel ); GetConsoleScreenBufferInfoX = (PHCSBIX)GetProcAddress( hKernel, "GetConsoleScreenBufferInfoEx" ); + if (GetConsoleScreenBufferInfoX == NULL) + GetConsoleScreenBufferInfoX = GetConsoleScreenBufferInfoEx_repl; SetConsoleScreenBufferInfoX = (PHCSBIX)GetProcAddress( hKernel, "SetConsoleScreenBufferInfoEx" ); SetCurrentConsoleFontX = (PHBCFIX)GetProcAddress( diff --git a/ansicon.c b/ansicon.c index 646aafc..e50ce03 100644 --- a/ansicon.c +++ b/ansicon.c @@ -91,7 +91,7 @@ use -pu to unload from the parent. */ -#define PDATE L"26 December, 2017" +#define PDATE L"28 December, 2017" #include "ansicon.h" #include "version.h" diff --git a/palette.h b/palette.h new file mode 100644 index 0000000..74fb9e6 --- /dev/null +++ b/palette.h @@ -0,0 +1,58 @@ +// Legacy console colors for XP (later systems get the actual palette). + +static const COLORREF legacy_palette[] = +{ +0x000000, 0x800000, 0x008000, 0x808000, 0x000080, 0x800080, 0x008080, 0xC0C0C0, +0x808080, 0xFF0000, 0x00FF00, 0xFFFF00, 0x0000FF, 0xFF00FF, 0x00FFFF, 0xFFFFFF, +}; + +// This is the Windows (10.0.15063) version of the xterm 256-color palette. + +static const COLORREF xterm_palette[] = +{ +// 16 system colors left out. + +// RGB 6x6x6 color cube. +0x000000, 0x5F0000, 0x870000, 0xAF0000, 0xD70000, 0xFF0000, +0x005F00, 0x5F5F00, 0x875F00, 0xAF5F00, 0xD75F00, 0xFF5F00, +0x008700, 0x5F8700, 0x878700, 0xAF8700, 0xD78700, 0xFF8700, +0x00AF00, 0x5FAF00, 0x87AF00, 0xAFAF00, 0xD7AF00, 0xFFAF00, +0x00D700, 0x5FD700, 0x87D700, 0xAFD700, 0xD7D700, 0xFFD700, +0x00FF00, 0x5FFF00, 0x87FF00, 0xAFFF00, 0xD7FF00, 0xFFFF00, +0x00005F, 0x5F005F, 0x87005F, 0xAF005F, 0xD7005F, 0xFF005F, +0x005F5F, 0x5F5F5F, 0x875F5F, 0xAF5F5F, 0xD75F5F, 0xFF5F5F, +0x00875F, 0x5F875F, 0x87875F, 0xAF875F, 0xD7875F, 0xFF875F, +0x00AF5F, 0x5FAF5F, 0x87AF5F, 0xAFAF5F, 0xD7AF5F, 0xFFAF5F, +0x00D75F, 0x5FD75F, 0x87D75F, 0xAFD75F, 0xD7D75F, 0xFFD75F, +0x00FF5F, 0x5FFF5F, 0x87FF5F, 0xAFFF5F, 0xD7FF5F, 0xFFFF5F, +0x000087, 0x5F0087, 0x870087, 0xAF0087, 0xD70087, 0xFF0087, +0x005F87, 0x5F5F87, 0x875F87, 0xAF5F87, 0xD75F87, 0xFF5F87, +0x008787, 0x5F8787, 0x878787, 0xAF8787, 0xD78787, 0xFF8787, +0x00AF87, 0x5FAF87, 0x87AF87, 0xAFAF87, 0xD7AF87, 0xFFAF87, +0x00D787, 0x5FD787, 0x87D787, 0xAFD787, 0xD7D787, 0xFFD787, +0x00FF87, 0x5FFF87, 0x87FF87, 0xAFFF87, 0xD7FF87, 0xFFFF87, +0x0000AF, 0x5F00AF, 0x8700AF, 0xAF00AF, 0xD700AF, 0xFF00AF, +0x005FAF, 0x5F5FAF, 0x875FAF, 0xAF5FAF, 0xD75FAF, 0xFF5FAF, +0x0087AF, 0x5F87AF, 0x8787AF, 0xAF87AF, 0xD787AF, 0xFF87AF, +0x00AFAF, 0x5FAFAF, 0x87AFAF, 0xAFAFAF, 0xD7AFAF, 0xFFAFAF, +0x00D7AF, 0x5FD7AF, 0x87D7AF, 0xAFD7AF, 0xD7D7AF, 0xFFD7AF, +0x00FFAF, 0x5FFFAF, 0x87FFAF, 0xAFFFAF, 0xD7FFAF, 0xFFFFAF, +0x0000D7, 0x5F00D7, 0x8700D7, 0xAF00D7, 0xD700D7, 0xFF00D7, +0x005FD7, 0x5F5FD7, 0x875FD7, 0xAF5FD7, 0xD75FD7, 0xFF5FD7, +0x0087D7, 0x5F87D7, 0x8787D7, 0xAF87D7, 0xD787D7, 0xFF87D7, +0x00AFDF, 0x5FAFDF, 0x87AFDF, 0xAFAFDF, 0xD7AFDF, 0xFFAFDF, // xterm uses +0x00D7DF, 0x5FD7DF, 0x87D7DF, 0xAFD7DF, 0xD7D7DF, 0xFFD7DF, // R = 0xD7 +0x00FFDF, 0x5FFFDF, 0x87FFDF, 0xAFFFDF, 0xD7FFDF, 0xFFFFDF, // here +0x0000FF, 0x5F00FF, 0x8700FF, 0xAF00FF, 0xD700FF, 0xFF00FF, +0x005FFF, 0x5F5FFF, 0x875FFF, 0xAF5FFF, 0xD75FFF, 0xFF5FFF, +0x0087FF, 0x5F87FF, 0x8787FF, 0xAF87FF, 0xD787FF, 0xFF87FF, +0x00AFFF, 0x5FAFFF, 0x87AFFF, 0xAFAFFF, 0xD7AFFF, 0xFFAFFF, +0x00D7FF, 0x5FD7FF, 0x87D7FF, 0xAFD7FF, 0xD7D7FF, 0xFFD7FF, +0x00FFFF, 0x5FFFFF, 0x87FFFF, 0xAFFFFF, 0xD7FFFF, 0xFFFFFF, + +// Grayscale, without black or white. +0x080808, 0x121212, 0x1C1C1C, 0x262626, 0x303030, 0x3A3A3A, +0x444444, 0x4E4E4E, 0x585858, 0x626262, 0x6C6C6C, 0x767676, +0x808080, 0x8A8A8A, 0x949494, 0x9E9E9E, 0xA8A8A8, 0xB2B2B2, +0xBCBCBC, 0xC6C6C6, 0xD0D0D0, 0xDADADA, 0xE4E4E4, 0xEEEEEE, +}; diff --git a/readme.txt b/readme.txt index aeb3a97..3ebdd95 100644 --- a/readme.txt +++ b/readme.txt @@ -334,10 +334,13 @@ Version History Legend: + added, - bug-fixed, * changed. - 1.81-wip - 26 December, 2017: + 1.81-wip - 28 December, 2017: - fix multiple CRs before LF (including preventing an immediate flush); - fix CR, BS and partial RM during CRM; - - fix buffer overflow caused by incorrect critical section. + - fix buffer overflow caused by incorrect critical section; + * support the entire 256-color palette; + * setting color by index or RGB will use the nearest console color; + * setting color by index will leave bold/underline unchanged. 1.80 - 24 December, 2017: - fix unloading; @@ -573,6 +576,8 @@ Acknowledgments Vincent Fatica for pointing out \e[K was not right. Nat Kuhn for pointing out the problem with report cursor position. + Thiadmer Riemersma for the nearest color algorithm. + Contact ======= @@ -595,4 +600,4 @@ Distribution ============================== -Jason Hood, 26 December, 2017. +Jason Hood, 28 December, 2017. diff --git a/sequences.txt b/sequences.txt index 4a2c4d0..243ee3f 100644 --- a/sequences.txt +++ b/sequences.txt @@ -1,8 +1,8 @@ ANSICON - Version 1.80 + Version 1.81 -This is a complete list of the ANSI escape sequences recognised by ANSICON, +This is a complete list of the ANSI/VT escape sequences recognised by ANSICON, roughly ordered by function. The initial escape character is assumed. The display consists of the buffer width and window height; add '+' before the final character to use the buffer height (e.g. "[2J" will erase the window, @@ -32,8 +32,8 @@ the Windows default beep (but only if it's not already playing). 35 foreground magenta 36 foreground cyan 37 foreground white - 38;2;# foreground & bold based on index (0-15) - 38;5;#;#;# ignored (RGB) + 38;2;# foreground based on index (0-255) + 38;5;#;#;# foreground based on RGB 39 default foreground (using current intensity) 40 background black 41 background red @@ -43,8 +43,8 @@ the Windows default beep (but only if it's not already playing). 45 background magenta 46 background cyan 47 background white - 48;2;# background & underline based on index (0-15) - 48;5;#;#;# ignored (RGB) + 48;2;# background based on index (0-255) + 48;5;#;#;# background based on RGB 49 default background (using current intensity) 90 foreground bright black 91 foreground bright red @@ -63,6 +63,11 @@ the Windows default beep (but only if it's not already playing). 106 background bright cyan 107 background bright white + Index is 0-7 for the normal colors and 8-15 for the bright; 16-231 + are a 6x6x6 color cube; and 232-255 are a grayscale ramp (without + black or white). Indices 16-255 and RGB colors will find the nearest + color from the first 16. + [J erase from cursor to the end of display [0J as above [1J erase from the start of diplay to cursor (inclusive) @@ -212,10 +217,11 @@ c hard reset: character 7 (BEL) or escape and backslash ]4;#;spec,spec...;#...ST set or query the palette: - # is the ANSI index (0-7, or 8-15 for bold/underline) + # is the ANSI index (0-7, or 8-15 for bright) spec is: ? send the current value to console input * send the current and all subsequent values + (up to 15 if index is less than that) #RGB set the color (hexadecimal) #RRGGBB set the color (hexadecimal) R,G,B set the color (decimal)