Add DECSTR and RIS
Implement soft and hard resets (handling intermediate bytes a little better in the process).
This commit is contained in:
		
							parent
							
								
									c28b3597dd
								
							
						
					
					
						commit
						a37657ac52
					
				
							
								
								
									
										137
									
								
								ANSI.c
									
									
									
									
									
								
							
							
						
						
									
										137
									
								
								ANSI.c
									
									
									
									
									
								
							| @ -176,7 +176,8 @@ | ||||
|     added insert mode; | ||||
|     BS/CUB/HPB after wrap will move back to the previous line(s); | ||||
|     added DECOM, DECSTBM, SD & SU; | ||||
|     only flush before accessing the console, adding a mode to flush immediately. | ||||
|     only flush before accessing the console, adding a mode to flush immediately; | ||||
|     added DECSTR & RIS. | ||||
| */ | ||||
| 
 | ||||
| #include "ansicon.h" | ||||
| @ -213,10 +214,11 @@ struct Cache | ||||
| 
 | ||||
| #define MAX_ARG 16		// max number of args in an escape sequence
 | ||||
| int   state;			// automata state
 | ||||
| TCHAR prefix;			// escape sequence prefix ( '[', ']' or '(' );
 | ||||
| TCHAR prefix2;			// secondary prefix ( '?' or '>' );
 | ||||
| TCHAR suffix;			// escape sequence suffix
 | ||||
| TCHAR suffix2;			// escape sequence secondary suffix
 | ||||
| TCHAR prefix;			// escape sequence prefix ( '[' or ']' );
 | ||||
| TCHAR prefix2;			// secondary prefix ( one of '<=>?' );
 | ||||
| TCHAR suffix;			// escape sequence final byte
 | ||||
| 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
 | ||||
| @ -945,6 +947,56 @@ void init_tabs( int size ) | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| // ========== Reset
 | ||||
| 
 | ||||
| void InterpretEscSeq( void ); | ||||
| 
 | ||||
| void Reset( BOOL hard ) | ||||
| { | ||||
|   CONSOLE_CURSOR_INFO CursInfo; | ||||
|   CONSOLE_SCREEN_BUFFER_INFOX csbix; | ||||
| 
 | ||||
|   GetConsoleCursorInfo( hConOut, &CursInfo ); | ||||
|   CursInfo.bVisible = TRUE; | ||||
|   SetConsoleCursorInfo( hConOut, &CursInfo ); | ||||
|   im = | ||||
|   om = | ||||
|   tb_margins = | ||||
|   pState->crm = FALSE; | ||||
|   awm = TRUE; | ||||
|   SetConsoleMode( hConOut, cache[0].mode | ENABLE_WRAP_AT_EOL_OUTPUT ); | ||||
|   shifted = G0_special = SaveG0 = FALSE; | ||||
|   pState->SavePos.X = pState->SavePos.Y = 0; | ||||
|   pState->SaveAttr = 0; | ||||
|   es_argv[0] = es_argc = 0; | ||||
|   prefix = '['; | ||||
|   prefix2 = suffix2 = 0; | ||||
|   suffix = 'm'; | ||||
|   InterpretEscSeq(); | ||||
| 
 | ||||
|   if (hard) | ||||
|   { | ||||
|     pState->tabs = | ||||
|     pState->noclear = FALSE; | ||||
|     prefix2 = '?'; | ||||
|     es_argv[0] = 3; es_argc = 1; | ||||
|     suffix2 = '+'; | ||||
|     suffix = 'l'; | ||||
|     InterpretEscSeq(); | ||||
|     screen_top = -1; | ||||
|     csbix.cbSize = sizeof(csbix); | ||||
|     if (GetConsoleScreenBufferInfoX && | ||||
| 	GetConsoleScreenBufferInfoX( hConOut, &csbix )) | ||||
|     { | ||||
|       memcpy( csbix.ColorTable, pState->palette, sizeof(csbix.ColorTable) ); | ||||
|       ++csbix.srWindow.Right; | ||||
|       ++csbix.srWindow.Bottom; | ||||
|       SetConsoleScreenBufferInfoX( hConOut, &csbix ); | ||||
|     } | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| // ========== Print functions
 | ||||
| 
 | ||||
| //-----------------------------------------------------------------------------
 | ||||
| @ -981,7 +1033,7 @@ void InterpretEscSeq( void ) | ||||
| 
 | ||||
|   if (prefix == '[') | ||||
|   { | ||||
|     if (prefix2 == '?') | ||||
|     if (prefix2 == '?' && (suffix2 == 0 || suffix2 == '+')) | ||||
|     { | ||||
|       if (suffix == 'h' || suffix == 'l') | ||||
|       { | ||||
| @ -1093,7 +1145,7 @@ void InterpretEscSeq( void ) | ||||
|       top    = TOP; | ||||
|       bottom = BOTTOM; | ||||
|     } | ||||
|     switch (suffix) | ||||
|     if (suffix2 == 0 || suffix2 == '+') switch (suffix) | ||||
|     { | ||||
|       case 'm': // SGR
 | ||||
| 	if (es_argc == 0) es_argc++; // ESC[m == ESC[0m
 | ||||
| @ -1580,50 +1632,46 @@ void InterpretEscSeq( void ) | ||||
| 	} | ||||
|       return; | ||||
| 
 | ||||
|       case 'h': // SM - ESC[#h Set Mode
 | ||||
| 	for (i = 0; i < es_argc; i++) | ||||
| 	  if (suffix2 == '+') | ||||
|       case 'h': // SM - ESC[#...h Set Mode
 | ||||
|       case 'l': // RM - ESC[#...l Reset Mode
 | ||||
|       { | ||||
| 	    switch (es_argv[i]) | ||||
| 	BOOL state = (suffix == 'h'); | ||||
| 	for (i = 0; i < es_argc; i++) | ||||
| 	  if (suffix2 == '+') switch (es_argv[i]) | ||||
| 	  { | ||||
| 	    case 1: // ACFM
 | ||||
| 		pState->fm = TRUE; | ||||
| 	      pState->fm = state; | ||||
| 	    break; | ||||
| 	  } | ||||
| 	  } | ||||
| 	  else switch (es_argv[i]) | ||||
| 	  { | ||||
| 	    case 3: // CRM
 | ||||
| 	      pState->crm = TRUE; | ||||
| 	      pState->crm = state; | ||||
| 	    break; | ||||
| 
 | ||||
| 	    case 4: // IRM
 | ||||
| 	      im = TRUE; | ||||
| 	      im = state; | ||||
| 	    break; | ||||
| 	  } | ||||
| 	return; | ||||
|       } | ||||
| 
 | ||||
|       case 'l': // RM - ESC[#l Reset Mode
 | ||||
| 	for (i = 0; i < es_argc; i++) | ||||
| 	  if (suffix2 == '+') | ||||
| 	  { | ||||
| 	    switch (es_argv[i]) | ||||
| 	    { | ||||
| 	      case 1: // ACFM
 | ||||
| 		pState->fm = FALSE; | ||||
| 	      break; | ||||
|       default: | ||||
|       return; | ||||
|     } | ||||
| 	  } | ||||
| 	  else switch (es_argv[i]) // CRM - ESC[3l is handled during parsing
 | ||||
|     if (suffix2 == '!') switch (suffix) | ||||
|     { | ||||
| 	    case 4: // IRM
 | ||||
| 	      im = FALSE; | ||||
| 	    break; | ||||
| 	  } | ||||
|       case 'p': // DECSTR - ESC[!p Soft reset
 | ||||
| 	if (es_argc != 0) return; | ||||
| 	Reset( FALSE ); | ||||
|       return; | ||||
| 
 | ||||
|       case '~': | ||||
| 	if (suffix2 == ',') // DECPS - ESC[#;#;#...,~ Play Sound
 | ||||
|       default: | ||||
|       return; | ||||
|     } | ||||
|     if (suffix2 == ',') switch (suffix) | ||||
|     { | ||||
|       case '~': // DECPS - ESC[#;#;#...,~ Play Sound
 | ||||
|       { | ||||
| 	// Frequencies of notes obtained from:
 | ||||
| 	//	https://pages.mtu.edu/~suits/notefreqs.html
 | ||||
| @ -1654,8 +1702,8 @@ void InterpretEscSeq( void ) | ||||
| 	    Beep( (es_argv[i] < lenof(snd_freq)) ? snd_freq[es_argv[i]] | ||||
| 						 : es_argv[i], dur ); | ||||
| 	} | ||||
| 	} | ||||
| 	return; | ||||
|       } | ||||
| 
 | ||||
|       default: | ||||
|       return; | ||||
| @ -1984,6 +2032,7 @@ ParseAndPrintString( HANDLE hDev, | ||||
|       if (c == ESC) | ||||
|       { | ||||
| 	suffix2 = 0; | ||||
| 	ibytes = 0; | ||||
| 	get_state(); | ||||
| 	state = (pState->crm) ? 7 : 2; | ||||
|       } | ||||
| @ -2025,10 +2074,14 @@ ParseAndPrintString( HANDLE hDev, | ||||
| 	state = 1; | ||||
|       } | ||||
|       else if (c >= '\x20' && c <= '\x2f') | ||||
| 	suffix2 = c; | ||||
|       else if (suffix2 != 0) | ||||
|       { | ||||
| 	if (suffix2 == '(')     // SCS - Designate G0 character set
 | ||||
| 	suffix2 = c; | ||||
| 	++ibytes; | ||||
|       } | ||||
|       else if (ibytes != 0) | ||||
|       { | ||||
| 	if (ibytes == 1 && | ||||
| 	    suffix2 == '(')     // SCS - Designate G0 character set
 | ||||
| 	{ | ||||
| 	  if (c == '0') | ||||
| 	    shifted = G0_special = TRUE; | ||||
| @ -2091,6 +2144,10 @@ ParseAndPrintString( HANDLE hDev, | ||||
| 	} | ||||
| 	state = 1; | ||||
|       } | ||||
|       else if (c == 'c')        // RIS Reset to Initial State
 | ||||
|       { | ||||
| 	Reset( TRUE ); | ||||
|       } | ||||
|       else if (c == '[' ||      // CSI Control Sequence Introducer
 | ||||
| 	       c == ']')        // OSC Operating System Command
 | ||||
|       { | ||||
| @ -2134,15 +2191,16 @@ ParseAndPrintString( HANDLE hDev, | ||||
|       { | ||||
| 	// ignore it
 | ||||
|       } | ||||
|       else if (c >= '\x3b' && c <= '\x3f') | ||||
|       else if (c >= '\x3c' && c <= '\x3f') | ||||
|       { | ||||
| 	prefix2 = c; | ||||
|       } | ||||
|       else if (c >= '\x20' && c <= '\x2f') | ||||
|       { | ||||
| 	suffix2 = c; | ||||
| 	++ibytes; | ||||
|       } | ||||
|       else if (suffix2 != 0 && suffix2 != '+' && (suffix2 != ',' || c != '~')) | ||||
|       else if (ibytes > 1) | ||||
|       { | ||||
| 	state = 1; | ||||
|       } | ||||
| @ -2175,8 +2233,9 @@ ParseAndPrintString( HANDLE hDev, | ||||
|       else if (c >= '\x20' && c <= '\x2f') | ||||
|       { | ||||
| 	suffix2 = c; | ||||
| 	++ibytes; | ||||
|       } | ||||
|       else if (suffix2 != 0 && suffix2 != '+' && (suffix2 != ',' || c != '~')) | ||||
|       else if (ibytes > 1) | ||||
|       { | ||||
| 	state = 1; | ||||
|       } | ||||
|  | ||||
| @ -91,7 +91,7 @@ | ||||
|     use -pu to unload from the parent. | ||||
| */ | ||||
| 
 | ||||
| #define PDATE L"22 December, 2017" | ||||
| #define PDATE L"23 December, 2017" | ||||
| 
 | ||||
| #include "ansicon.h" | ||||
| #include "version.h" | ||||
|  | ||||
| @ -191,6 +191,7 @@ Sequences Recognised | ||||
| 	\e[?5W		DECST8C Set Tab at Every 8 Columns | ||||
| 	\e[?5;#W	DECST8C Set Tab at Every # Columns (ANSICON extension) | ||||
| 	\e[#;#r 	DECSTBM Set Top and Bottom Margins | ||||
| 	\e[!p		DECSTR	Soft Terminal Reset | ||||
| 	\e[?25h 	DECTCEM Text Cursor Enable Mode (show cursor) | ||||
| 	\e[?25l 	DECTCEM Text Cursor Enable Mode (hide cursor) | ||||
| 	\e[#M		DL	Delete Line | ||||
| @ -214,6 +215,7 @@ Sequences Recognised | ||||
| 	\eE		NEL	Next Line | ||||
| 	\e[#b		REP	Repeat | ||||
| 	\eM		RI	Reverse Index | ||||
| 	\ec		RIS	Reset to Initial State | ||||
| 	\e(0		SCS	Select Character Set (DEC special graphics) | ||||
| 	\e(B		SCS	Select Character Set (ASCII) | ||||
| 	\e[#;#;#m	SGR	Select Graphic Rendition | ||||
| @ -322,7 +324,7 @@ Version History | ||||
| 
 | ||||
|     Legend: + added, - bug-fixed, * changed. | ||||
| 
 | ||||
|     1.80 - 22 December, 2017: | ||||
|     1.80 - 23 December, 2017: | ||||
|     - fix unloading; | ||||
|     - fix -e et al when redirecting to CON; | ||||
|     - hook CreateFile and CreateConsoleScreenBuffer to force read/write access | ||||
| @ -349,7 +351,8 @@ Version History | ||||
|     + added SCS, but only for special/ASCII (same as Win10); | ||||
|     + added tab handling (HT, HTS, TBC & DECST8C); | ||||
|     + added IRM; | ||||
|     + added DECOM, DECSTBM, SD & SU. | ||||
|     + added DECOM, DECSTBM, SD & SU; | ||||
|     + added DECSTR & RIS. | ||||
| 
 | ||||
|     1.72 - 24 December, 2015: | ||||
|     - handle STD_OUTPUT_HANDLE & STD_ERROR_HANDLE in WriteFile; | ||||
| @ -578,4 +581,4 @@ Distribution | ||||
| 
 | ||||
| 
 | ||||
| ============================== | ||||
| Jason Hood, 22 December, 2017. | ||||
| Jason Hood, 23 December, 2017. | ||||
|  | ||||
| @ -182,6 +182,25 @@ H	set tab stop | ||||
| [?95h	don't clear screen when changing columns | ||||
| [?95l	clear screen when changing columns | ||||
| 
 | ||||
| [!p	soft reset: | ||||
| 	  show cursor | ||||
| 	  perform control functions | ||||
| 	  replace characters | ||||
| 	  set origin to top line | ||||
| 	  wrap lines at screen edge | ||||
| 	  select ASCII | ||||
| 	  remove margins | ||||
| 	  default SGR | ||||
| 	  set the saved cursor to the top-left | ||||
| c	hard reset: | ||||
| 	  as above | ||||
| 	  restore console tab handling | ||||
| 	  restore the entire palette | ||||
| 	  restore original columns | ||||
| 	  clear screen when changing columns | ||||
| 	  clear the buffer | ||||
| 	  home the cursor | ||||
| 
 | ||||
| [c	sends "\e[?62;1c" to console input (where \e is escape) | ||||
| [0c	as above | ||||
| [5n	sends "\e[0n" to console input | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Jason Hood
						Jason Hood