From 9fbe42a583fadbc781168feaec9762f1d74620ff Mon Sep 17 00:00:00 2001 From: Jason Hood Date: Fri, 24 Nov 2017 11:10:42 +1000 Subject: [PATCH] Escape control characters; fix CRM issues Since ESC is now preserved for unrecognised sequences, I feel able to use it to escape control characters in order to display them (e.g. "\e\e" will display a single escape). Control mode would not display the recognised controls (i.e. BEL, SO and SI) and would not work if it was turned off in the same string. --- ANSI.c | 43 ++++++++++++++++++++++++++++++++----------- ansicon.c | 2 +- readme.txt | 10 +++++++--- 3 files changed, 40 insertions(+), 15 deletions(-) diff --git a/ANSI.c b/ANSI.c index 3b08d5d..e0ce4a7 100644 --- a/ANSI.c +++ b/ANSI.c @@ -162,7 +162,8 @@ fix escape followed by CRM in control mode; use the system default sound for the bell; add DECPS Play Sound; - use intermediate byte '+' to use buffer, not window. + use intermediate byte '+' to use buffer, not window; + ESC followed by a control character will display that character. */ #include "ansicon.h" @@ -185,7 +186,7 @@ HANDLE hHeap; // local memory heap HANDLE hBell; #define CACHE 5 -struct +struct Cache { HANDLE h; DWORD mode; @@ -478,11 +479,9 @@ void FlushBuffer( void ) if (pState->crm) { - DWORD mode; - GetConsoleMode( hConOut, &mode ); - SetConsoleMode( hConOut, mode & ~ENABLE_PROCESSED_OUTPUT ); + SetConsoleMode( hConOut, cache[0].mode & ~ENABLE_PROCESSED_OUTPUT ); WriteConsole( hConOut, ChBuffer, nCharInBuffer, &nWritten, NULL ); - SetConsoleMode( hConOut, mode ); + SetConsoleMode( hConOut, cache[0].mode ); } else { @@ -699,9 +698,11 @@ void InterpretEscSeq( void ) return; case 7: - mode = ENABLE_PROCESSED_OUTPUT; + mode = cache[0].mode; if (suffix == 'h') mode |= ENABLE_WRAP_AT_EOL_OUTPUT; + else + mode &= ~ENABLE_WRAP_AT_EOL_OUTPUT; SetConsoleMode( hConOut, mode ); return; } @@ -1269,6 +1270,7 @@ ParseAndPrintString( HANDLE hDev, get_state(); state = (pState->crm) ? 7 : 2; } + else if (pState->crm) PushBuffer( (WCHAR)c ); else if (c == BEL) { if (hBell == NULL) @@ -1280,8 +1282,15 @@ ParseAndPrintString( HANDLE hDev, } else if (state == 2) { - if (c == ESC) - PushBuffer( ESC ); + if (c < '\x20') + { + FlushBuffer(); + pState->crm = TRUE; + PushBuffer( (WCHAR)c ); + FlushBuffer(); + pState->crm = FALSE; + state = 1; + } else if (c >= '\x20' && c <= '\x2f') suffix2 = c; else if (suffix2 != 0) @@ -1433,7 +1442,11 @@ ParseAndPrintString( HANDLE hDev, } else if (state == 9) { - if (c == 'l') pState->crm = FALSE; + if (c == 'l') + { + FlushBuffer(); + pState->crm = FALSE; + } else { PushBuffer( ESC ); @@ -2098,7 +2111,15 @@ BOOL IsConsoleHandle( HANDLE h ) for (c = 0; c < CACHE; ++c) if (cache[c].h == h) - return (cache[c].mode & ENABLE_PROCESSED_OUTPUT); + { + if (c != 0) + { + struct Cache tc = cache[c]; + do cache[c] = cache[c-1]; while (--c > 0); + cache[0] = tc; + } + return (cache[0].mode & ENABLE_PROCESSED_OUTPUT); + } while (--c > 0) cache[c] = cache[c-1]; diff --git a/ansicon.c b/ansicon.c index ff2b1ac..9f3ba74 100644 --- a/ansicon.c +++ b/ansicon.c @@ -90,7 +90,7 @@ write newline with _putws, not putwchar (fixes redirecting to CON). */ -#define PDATE L"23 November, 2017" +#define PDATE L"24 November, 2017" #include "ansicon.h" #include "version.h" diff --git a/readme.txt b/readme.txt index 00b4741..5fe8603 100644 --- a/readme.txt +++ b/readme.txt @@ -198,6 +198,9 @@ Sequences Recognised and underline will set the background intensity; conceal uses background as foreground. See "sequences.txt" for a more complete description. + Escape followed by a control character will display that character, not + perform its function. An unrecognised sequence will preserve the escape. + I make a distinction between '\e[m' and '\e[0;...m'. Both will restore the original foreground/background colors (and so '0' should be the first para- meter); the former will also restore the original bold and underline attri- @@ -295,15 +298,16 @@ Version History Legend: + added, - bug-fixed, * changed. - 1.80 - 23 November, 2017: + 1.80 - 24 November, 2017: - fix unloading; - fix -e et al when redirecting to CON; - hook CreateFile and CreateConsoleScreenBuffer to force read/write access (fixes redirecting to CON and Microsoft's conio); - fix cursor report with duplicated digits (e.g. "11" was only writing "1"); - - fix escape followed by CRM in control mode; + - fix issues with CRM; * go back to saving the buffer cursor position; * preserve escape that isn't part of a sequence; + * escape control characters; + use the system default sound for the bell; + added Play Sound DECPS; + added '+' intermediate byte to use the buffer, rather than the window. @@ -535,4 +539,4 @@ Distribution ============================= -Jason Hood, 23 November, 2017. +Jason Hood, 24 November, 2017.