Modify DECSC/DECRC
Save/restore the attributes and G0 character set (the ANSI version still only does the cursor). Add the comment I missed when adding SCS; remove `DEC` from the sequence descriptions.
This commit is contained in:
		
							parent
							
								
									d20ab7471f
								
							
						
					
					
						commit
						7c14985a5d
					
				
							
								
								
									
										150
									
								
								ANSI.c
									
									
									
									
									
								
							
							
						
						
									
										150
									
								
								ANSI.c
									
									
									
									
									
								
							@ -152,7 +152,7 @@
 | 
			
		||||
    remove wcstok, avoiding potential interference with the host;
 | 
			
		||||
    similarly, use a private heap instead of malloc.
 | 
			
		||||
 | 
			
		||||
  v1.80, 26 October to 9 December, 2017:
 | 
			
		||||
  v1.80, 26 October to 11 December, 2017:
 | 
			
		||||
    fix unloading;
 | 
			
		||||
    revert back to (re)storing buffer cursor position;
 | 
			
		||||
    increase cache to five handles;
 | 
			
		||||
@ -167,7 +167,8 @@
 | 
			
		||||
    added palette sequences;
 | 
			
		||||
    change the scan lines in the graphics set to their actual Unicode chars;
 | 
			
		||||
    added IND, NEL & RI (using buffer, in keeping with LF);
 | 
			
		||||
    added DA, DECCOLM, DECNCSM, DECSC & DECRC;
 | 
			
		||||
    added DA, DECCOLM, DECNCSM, DECSC & DECRC (with SGR & G0);
 | 
			
		||||
    partially support SCS (just G0 as DEC special & ASCII);
 | 
			
		||||
    an explicit zero parameter should still default to one;
 | 
			
		||||
    restrict parameters to a maximum value of 32767;
 | 
			
		||||
    added tab handling.
 | 
			
		||||
@ -215,7 +216,7 @@ 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
 | 
			
		||||
int   Pt_len;
 | 
			
		||||
BOOL  shifted, G0_special;
 | 
			
		||||
BOOL  shifted, G0_special, SaveG0;
 | 
			
		||||
int   screen_top = -1;		// initial window top when cleared
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -340,13 +341,19 @@ PHCSBIX GetConsoleScreenBufferInfoX, SetConsoleScreenBufferInfoX;
 | 
			
		||||
 | 
			
		||||
typedef struct
 | 
			
		||||
{
 | 
			
		||||
  BYTE	   foreground;	// ANSI base color (0 to 7; add 30)
 | 
			
		||||
  BYTE	   background;	// ANSI base color (0 to 7; add 40)
 | 
			
		||||
  BYTE	   bold;	// console FOREGROUND_INTENSITY bit
 | 
			
		||||
  BYTE	   underline;	// console BACKGROUND_INTENSITY bit
 | 
			
		||||
  BYTE	   rvideo;	// swap foreground/bold & background/underline
 | 
			
		||||
  BYTE	   concealed;	// set foreground/bold to background/underline
 | 
			
		||||
  BYTE	   reverse;	// swap console foreground & background attributes
 | 
			
		||||
  BYTE	foreground;	// ANSI base color (0 to 7; add 30)
 | 
			
		||||
  BYTE	background;	// ANSI base color (0 to 7; add 40)
 | 
			
		||||
  BYTE	bold;		// console FOREGROUND_INTENSITY bit
 | 
			
		||||
  BYTE	underline;	// console BACKGROUND_INTENSITY bit
 | 
			
		||||
  BYTE	rvideo; 	// swap foreground/bold & background/underline
 | 
			
		||||
  BYTE	concealed;	// set foreground/bold to background/underline
 | 
			
		||||
  BYTE	reverse;	// swap console foreground & background attributes
 | 
			
		||||
} SGR;
 | 
			
		||||
 | 
			
		||||
typedef struct
 | 
			
		||||
{
 | 
			
		||||
  SGR	   sgr, SaveSgr;
 | 
			
		||||
  WORD	   SaveAttr;
 | 
			
		||||
  BYTE	   crm; 	// showing control characters?
 | 
			
		||||
  COORD    SavePos;	// saved cursor position
 | 
			
		||||
  COLORREF palette[16];
 | 
			
		||||
@ -431,24 +438,24 @@ void get_state( void )
 | 
			
		||||
    if (GetEnvironmentVariable( L"ANSICON_REVERSE", NULL, 0 ))
 | 
			
		||||
    {
 | 
			
		||||
      SetEnvironmentVariable( L"ANSICON_REVERSE", NULL );
 | 
			
		||||
      pState->reverse	 = TRUE;
 | 
			
		||||
      pState->foreground = attr2ansi[(csbi.wAttributes >> 4) & 7];
 | 
			
		||||
      pState->background = attr2ansi[csbi.wAttributes & 7];
 | 
			
		||||
      pState->bold	 = (csbi.wAttributes & BACKGROUND_INTENSITY) >> 4;
 | 
			
		||||
      pState->underline  = (csbi.wAttributes & FOREGROUND_INTENSITY) << 4;
 | 
			
		||||
      pState->sgr.reverse  = TRUE;
 | 
			
		||||
      pState->sgr.foreground = attr2ansi[(csbi.wAttributes >> 4) & 7];
 | 
			
		||||
      pState->sgr.background = attr2ansi[csbi.wAttributes & 7];
 | 
			
		||||
      pState->sgr.bold	     = (csbi.wAttributes & BACKGROUND_INTENSITY) >> 4;
 | 
			
		||||
      pState->sgr.underline  = (csbi.wAttributes & FOREGROUND_INTENSITY) << 4;
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
      pState->foreground = attr2ansi[csbi.wAttributes & 7];
 | 
			
		||||
      pState->background = attr2ansi[(csbi.wAttributes >> 4) & 7];
 | 
			
		||||
      pState->bold	 = csbi.wAttributes & FOREGROUND_INTENSITY;
 | 
			
		||||
      pState->underline  = csbi.wAttributes & BACKGROUND_INTENSITY;
 | 
			
		||||
      pState->sgr.foreground = attr2ansi[csbi.wAttributes & 7];
 | 
			
		||||
      pState->sgr.background = attr2ansi[(csbi.wAttributes >> 4) & 7];
 | 
			
		||||
      pState->sgr.bold	     = csbi.wAttributes & FOREGROUND_INTENSITY;
 | 
			
		||||
      pState->sgr.underline  = csbi.wAttributes & BACKGROUND_INTENSITY;
 | 
			
		||||
    }
 | 
			
		||||
    if (!GetEnvironmentVariable( L"ANSICON_DEF", NULL, 0 ))
 | 
			
		||||
    {
 | 
			
		||||
      TCHAR  def[4];
 | 
			
		||||
      LPTSTR a = def;
 | 
			
		||||
      if (pState->reverse)
 | 
			
		||||
      if (pState->sgr.reverse)
 | 
			
		||||
      {
 | 
			
		||||
	*a++ = '-';
 | 
			
		||||
	csbi.wAttributes = ((csbi.wAttributes >> 4) & 15)
 | 
			
		||||
@ -883,11 +890,11 @@ void InterpretEscSeq( void )
 | 
			
		||||
	{
 | 
			
		||||
	  if (30 <= es_argv[i] && es_argv[i] <= 37)
 | 
			
		||||
	  {
 | 
			
		||||
	    pState->foreground = es_argv[i] - 30;
 | 
			
		||||
	    pState->sgr.foreground = es_argv[i] - 30;
 | 
			
		||||
	  }
 | 
			
		||||
	  else if (40 <= es_argv[i] && es_argv[i] <= 47)
 | 
			
		||||
	  {
 | 
			
		||||
	    pState->background = es_argv[i] - 40;
 | 
			
		||||
	    pState->sgr.background = es_argv[i] - 40;
 | 
			
		||||
	  }
 | 
			
		||||
	  else if (es_argv[i] == 38 || es_argv[i] == 48)
 | 
			
		||||
	  {
 | 
			
		||||
@ -915,78 +922,78 @@ void InterpretEscSeq( void )
 | 
			
		||||
	      *def = '7'; def[1] = '\0';
 | 
			
		||||
	      GetEnvironmentVariable( L"ANSICON_DEF", def, lenof(def) );
 | 
			
		||||
	      a = wcstol( def, NULL, 16 );
 | 
			
		||||
	      pState->reverse = FALSE;
 | 
			
		||||
	      pState->sgr.reverse = FALSE;
 | 
			
		||||
	      if (a < 0)
 | 
			
		||||
	      {
 | 
			
		||||
		pState->reverse = TRUE;
 | 
			
		||||
		pState->sgr.reverse = TRUE;
 | 
			
		||||
		a = -a;
 | 
			
		||||
	      }
 | 
			
		||||
	      if (es_argv[i] != 49)
 | 
			
		||||
		pState->foreground = attr2ansi[a & 7];
 | 
			
		||||
		pState->sgr.foreground = attr2ansi[a & 7];
 | 
			
		||||
	      if (es_argv[i] != 39)
 | 
			
		||||
		pState->background = attr2ansi[(a >> 4) & 7];
 | 
			
		||||
		pState->sgr.background = attr2ansi[(a >> 4) & 7];
 | 
			
		||||
	      if (es_argv[i] == 0)
 | 
			
		||||
	      {
 | 
			
		||||
		if (es_argc == 1)
 | 
			
		||||
		{
 | 
			
		||||
		  pState->bold	    = a & FOREGROUND_INTENSITY;
 | 
			
		||||
		  pState->underline = a & BACKGROUND_INTENSITY;
 | 
			
		||||
		  pState->sgr.bold	= a & FOREGROUND_INTENSITY;
 | 
			
		||||
		  pState->sgr.underline = a & BACKGROUND_INTENSITY;
 | 
			
		||||
		}
 | 
			
		||||
		else
 | 
			
		||||
		{
 | 
			
		||||
		  pState->bold	    = 0;
 | 
			
		||||
		  pState->underline = 0;
 | 
			
		||||
		  pState->sgr.bold	= 0;
 | 
			
		||||
		  pState->sgr.underline = 0;
 | 
			
		||||
		}
 | 
			
		||||
		pState->rvideo    = 0;
 | 
			
		||||
		pState->concealed = 0;
 | 
			
		||||
		pState->sgr.rvideo    = 0;
 | 
			
		||||
		pState->sgr.concealed = 0;
 | 
			
		||||
	      }
 | 
			
		||||
	    }
 | 
			
		||||
	    break;
 | 
			
		||||
 | 
			
		||||
	    case  1: pState->bold      = FOREGROUND_INTENSITY; break;
 | 
			
		||||
	    case  1: pState->sgr.bold	   = FOREGROUND_INTENSITY; break;
 | 
			
		||||
	    case  5: // blink
 | 
			
		||||
	    case  4: pState->underline = BACKGROUND_INTENSITY; break;
 | 
			
		||||
	    case  7: pState->rvideo    = 1; break;
 | 
			
		||||
	    case  8: pState->concealed = 1; break;
 | 
			
		||||
	    case  4: pState->sgr.underline = BACKGROUND_INTENSITY; break;
 | 
			
		||||
	    case  7: pState->sgr.rvideo    = 1; break;
 | 
			
		||||
	    case  8: pState->sgr.concealed = 1; break;
 | 
			
		||||
	    case 21: // oops, this actually turns on double underline
 | 
			
		||||
		     // but xterm turns off bold too, so that's alright
 | 
			
		||||
	    case 22: pState->bold      = 0; break;
 | 
			
		||||
	    case 22: pState->sgr.bold	   = 0; break;
 | 
			
		||||
	    case 25:
 | 
			
		||||
	    case 24: pState->underline = 0; break;
 | 
			
		||||
	    case 27: pState->rvideo    = 0; break;
 | 
			
		||||
	    case 28: pState->concealed = 0; break;
 | 
			
		||||
	    case 24: pState->sgr.underline = 0; break;
 | 
			
		||||
	    case 27: pState->sgr.rvideo    = 0; break;
 | 
			
		||||
	    case 28: pState->sgr.concealed = 0; break;
 | 
			
		||||
	  }
 | 
			
		||||
	}
 | 
			
		||||
	if (pState->concealed)
 | 
			
		||||
	if (pState->sgr.concealed)
 | 
			
		||||
	{
 | 
			
		||||
	  if (pState->rvideo)
 | 
			
		||||
	  if (pState->sgr.rvideo)
 | 
			
		||||
	  {
 | 
			
		||||
	    attribut = foregroundcolor[pState->foreground]
 | 
			
		||||
		     | backgroundcolor[pState->foreground];
 | 
			
		||||
	    if (pState->bold)
 | 
			
		||||
	    attribut = foregroundcolor[pState->sgr.foreground]
 | 
			
		||||
		     | backgroundcolor[pState->sgr.foreground];
 | 
			
		||||
	    if (pState->sgr.bold)
 | 
			
		||||
	      attribut |= FOREGROUND_INTENSITY | BACKGROUND_INTENSITY;
 | 
			
		||||
	  }
 | 
			
		||||
	  else
 | 
			
		||||
	  {
 | 
			
		||||
	    attribut = foregroundcolor[pState->background]
 | 
			
		||||
		     | backgroundcolor[pState->background];
 | 
			
		||||
	    if (pState->underline)
 | 
			
		||||
	    attribut = foregroundcolor[pState->sgr.background]
 | 
			
		||||
		     | backgroundcolor[pState->sgr.background];
 | 
			
		||||
	    if (pState->sgr.underline)
 | 
			
		||||
	      attribut |= FOREGROUND_INTENSITY | BACKGROUND_INTENSITY;
 | 
			
		||||
	  }
 | 
			
		||||
	}
 | 
			
		||||
	else if (pState->rvideo)
 | 
			
		||||
	else if (pState->sgr.rvideo)
 | 
			
		||||
	{
 | 
			
		||||
	  attribut = foregroundcolor[pState->background]
 | 
			
		||||
		   | backgroundcolor[pState->foreground];
 | 
			
		||||
	  if (pState->bold)
 | 
			
		||||
	  attribut = foregroundcolor[pState->sgr.background]
 | 
			
		||||
		   | backgroundcolor[pState->sgr.foreground];
 | 
			
		||||
	  if (pState->sgr.bold)
 | 
			
		||||
	    attribut |= BACKGROUND_INTENSITY;
 | 
			
		||||
	  if (pState->underline)
 | 
			
		||||
	  if (pState->sgr.underline)
 | 
			
		||||
	    attribut |= FOREGROUND_INTENSITY;
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	  attribut = foregroundcolor[pState->foreground] | pState->bold
 | 
			
		||||
		   | backgroundcolor[pState->background] | pState->underline;
 | 
			
		||||
	if (pState->reverse)
 | 
			
		||||
	  attribut = foregroundcolor[pState->sgr.foreground] | pState->sgr.bold
 | 
			
		||||
		   | backgroundcolor[pState->sgr.background] | pState->sgr.underline;
 | 
			
		||||
	if (pState->sgr.reverse)
 | 
			
		||||
	  attribut = ((attribut >> 4) & 15) | ((attribut & 15) << 4);
 | 
			
		||||
	SetConsoleTextAttribute( hConOut, attribut );
 | 
			
		||||
      return;
 | 
			
		||||
@ -1706,15 +1713,32 @@ ParseAndPrintString( HANDLE hDev,
 | 
			
		||||
	if (CUR.X < MAX_TABS) pState->tab_stop[CUR.X] = TRUE;
 | 
			
		||||
	state = 1;
 | 
			
		||||
      }
 | 
			
		||||
      else if (c == '7' ||      // DECSC Save Cursor
 | 
			
		||||
	       c == '8')        // DECRC Restore Cursor
 | 
			
		||||
      else if (c == '7')        // DECSC Save Cursor
 | 
			
		||||
      {
 | 
			
		||||
	es_argc = 0;
 | 
			
		||||
	prefix = '[';
 | 
			
		||||
	prefix2 = 0;
 | 
			
		||||
	suffix = (c == '7') ? 's' : 'u';
 | 
			
		||||
	CONSOLE_SCREEN_BUFFER_INFO Info;
 | 
			
		||||
	FlushBuffer();
 | 
			
		||||
	InterpretEscSeq();
 | 
			
		||||
	GetConsoleScreenBufferInfo( hConOut, &Info );
 | 
			
		||||
	pState->SavePos = CUR;
 | 
			
		||||
	pState->SaveSgr = pState->sgr;
 | 
			
		||||
	pState->SaveAttr = Info.wAttributes;
 | 
			
		||||
	SaveG0 = G0_special;
 | 
			
		||||
	state = 1;
 | 
			
		||||
      }
 | 
			
		||||
      else if (c == '8')        // DECRC Restore Cursor
 | 
			
		||||
      {
 | 
			
		||||
	CONSOLE_SCREEN_BUFFER_INFO Info;
 | 
			
		||||
	FlushBuffer();
 | 
			
		||||
	GetConsoleScreenBufferInfo( hConOut, &Info );
 | 
			
		||||
	CUR = pState->SavePos;
 | 
			
		||||
	if (CUR.X > RIGHT) CUR.X = RIGHT;
 | 
			
		||||
	if (CUR.Y > LAST)  CUR.Y = LAST;
 | 
			
		||||
	SetConsoleCursorPosition( hConOut, CUR );
 | 
			
		||||
	if (pState->SaveAttr != 0)  // assume 0 means not saved
 | 
			
		||||
	{
 | 
			
		||||
	  pState->sgr = pState->SaveSgr;
 | 
			
		||||
	  SetConsoleTextAttribute( hConOut, pState->SaveAttr );
 | 
			
		||||
	  shifted = G0_special = SaveG0;
 | 
			
		||||
	}
 | 
			
		||||
	state = 1;
 | 
			
		||||
      }
 | 
			
		||||
      else if (c == '[' ||      // CSI Control Sequence Introducer
 | 
			
		||||
 | 
			
		||||
@ -91,7 +91,7 @@
 | 
			
		||||
    use -pu to unload from the parent.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#define PDATE L"10 December, 2017"
 | 
			
		||||
#define PDATE L"11 December, 2017"
 | 
			
		||||
 | 
			
		||||
#include "ansicon.h"
 | 
			
		||||
#include "version.h"
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										30
									
								
								readme.txt
									
									
									
									
									
								
							
							
						
						
									
										30
									
								
								readme.txt
									
									
									
									
									
								
							@ -175,19 +175,19 @@ Sequences Recognised
 | 
			
		||||
	\e[#A		CUU	Cursor Up
 | 
			
		||||
	\e[c		DA	Device Attributes
 | 
			
		||||
	\e[#P		DCH	Delete Character
 | 
			
		||||
	\e[?7h		DECAWM	DEC Autowrap Mode (autowrap)
 | 
			
		||||
	\e[?7l		DECAWM	DEC Autowrap Mode (no autowrap)
 | 
			
		||||
	\e[?3h		DECCOLM DEC Selecting 80 or 132 Columns per Page (132)
 | 
			
		||||
	\e[?3l		DECCOLM DEC Selecting 80 or 132 Columns per Page (prior)
 | 
			
		||||
	\e[?3h		DECNCSM DEC No Clearing Screen On Column Change Mode (keep)
 | 
			
		||||
	\e[?3l		DECNCSM DEC No Clearing Screen On Column Change Mode (clear)
 | 
			
		||||
	\e[#;#;#...,~	DECPS	DEC Play Sound
 | 
			
		||||
	\e8		DECRC	DEC Restore Cursor
 | 
			
		||||
	\e7		DECSC	DEC Save Cursor
 | 
			
		||||
	\e[?5W		DECST8C DEC Set Tab at Every 8 Columns
 | 
			
		||||
	\e[?5;#W	DECST8C DEC Set Tab at Every # Columns (ANSICON extension)
 | 
			
		||||
	\e[?25h 	DECTCEM DEC Text Cursor Enable Mode (show cursor)
 | 
			
		||||
	\e[?25l 	DECTCEM DEC Text Cursor Enable Mode (hide cursor)
 | 
			
		||||
	\e[?7h		DECAWM	Autowrap Mode (autowrap)
 | 
			
		||||
	\e[?7l		DECAWM	Autowrap Mode (no autowrap)
 | 
			
		||||
	\e[?3h		DECCOLM Selecting 80 or 132 Columns per Page (132)
 | 
			
		||||
	\e[?3l		DECCOLM Selecting 80 or 132 Columns per Page (prior)
 | 
			
		||||
	\e[?3h		DECNCSM No Clearing Screen On Column Change Mode (keep)
 | 
			
		||||
	\e[?3l		DECNCSM No Clearing Screen On Column Change Mode (clear)
 | 
			
		||||
	\e[#;#;#...,~	DECPS	Play Sound
 | 
			
		||||
	\e8		DECRC	Restore Cursor
 | 
			
		||||
	\e7		DECSC	Save Cursor
 | 
			
		||||
	\e[?5W		DECST8C Set Tab at Every 8 Columns
 | 
			
		||||
	\e[?5;#W	DECST8C Set Tab at Every # Columns (ANSICON extension)
 | 
			
		||||
	\e[?25h 	DECTCEM Text Cursor Enable Mode (show cursor)
 | 
			
		||||
	\e[?25l 	DECTCEM Text Cursor Enable Mode (hide cursor)
 | 
			
		||||
	\e[#M		DL	Delete Line
 | 
			
		||||
	\e[#n		DSR	Device Status Report
 | 
			
		||||
	\e[#X		ECH	Erase Character
 | 
			
		||||
@ -310,7 +310,7 @@ Version History
 | 
			
		||||
 | 
			
		||||
    Legend: + added, - bug-fixed, * changed.
 | 
			
		||||
 | 
			
		||||
    1.80 - 10 December, 2017:
 | 
			
		||||
    1.80 - 11 December, 2017:
 | 
			
		||||
    - fix unloading;
 | 
			
		||||
    - fix -e et al when redirecting to CON;
 | 
			
		||||
    - hook CreateFile and CreateConsoleScreenBuffer to force read/write access
 | 
			
		||||
@ -559,4 +559,4 @@ Distribution
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
==============================
 | 
			
		||||
Jason Hood, 10 December, 2017.
 | 
			
		||||
Jason Hood, 11 December, 2017.
 | 
			
		||||
 | 
			
		||||
@ -127,10 +127,10 @@ H	set tab stop
 | 
			
		||||
[#f	move cursor to line # and first column
 | 
			
		||||
[#;#f	move cursor to line #, column #
 | 
			
		||||
 | 
			
		||||
[s	save cursor position
 | 
			
		||||
7	as above
 | 
			
		||||
[s	save cursor position (buffer only)
 | 
			
		||||
[u	move cursor to saved position (or top-left, if nothing was saved)
 | 
			
		||||
8	as above
 | 
			
		||||
7	save cursor position (buffer only), attributes and G0 character set
 | 
			
		||||
8	restore above (if nothing was saved only moves cursor to top-left)
 | 
			
		||||
 | 
			
		||||
(0	select the DEC Special Graphics Character Set
 | 
			
		||||
(B	select ASCII
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user