Add DECSTR and RIS

Implement soft and hard resets (handling intermediate bytes a little
better in the process).
This commit is contained in:
Jason Hood 2017-12-23 16:44:32 +10:00
parent c28b3597dd
commit a37657ac52
4 changed files with 154 additions and 73 deletions

137
ANSI.c
View File

@ -176,7 +176,8 @@
added insert mode; added insert mode;
BS/CUB/HPB after wrap will move back to the previous line(s); BS/CUB/HPB after wrap will move back to the previous line(s);
added DECOM, DECSTBM, SD & SU; 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" #include "ansicon.h"
@ -213,10 +214,11 @@ struct Cache
#define MAX_ARG 16 // max number of args in an escape sequence #define MAX_ARG 16 // max number of args in an escape sequence
int state; // automata state int state; // automata state
TCHAR prefix; // escape sequence prefix ( '[', ']' or '(' ); TCHAR prefix; // escape sequence prefix ( '[' or ']' );
TCHAR prefix2; // secondary prefix ( '?' or '>' ); TCHAR prefix2; // secondary prefix ( one of '<=>?' );
TCHAR suffix; // escape sequence suffix TCHAR suffix; // escape sequence final byte
TCHAR suffix2; // escape sequence secondary suffix TCHAR suffix2; // escape sequence intermediate byte
int ibytes; // count of intermediate bytes
int es_argc; // escape sequence args count int es_argc; // escape sequence args count
int es_argv[MAX_ARG]; // escape sequence args int es_argv[MAX_ARG]; // escape sequence args
TCHAR Pt_arg[MAX_PATH*2]; // text parameter for Operating System Command 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 // ========== Print functions
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -981,7 +1033,7 @@ void InterpretEscSeq( void )
if (prefix == '[') if (prefix == '[')
{ {
if (prefix2 == '?') if (prefix2 == '?' && (suffix2 == 0 || suffix2 == '+'))
{ {
if (suffix == 'h' || suffix == 'l') if (suffix == 'h' || suffix == 'l')
{ {
@ -1093,7 +1145,7 @@ void InterpretEscSeq( void )
top = TOP; top = TOP;
bottom = BOTTOM; bottom = BOTTOM;
} }
switch (suffix) if (suffix2 == 0 || suffix2 == '+') switch (suffix)
{ {
case 'm': // SGR case 'm': // SGR
if (es_argc == 0) es_argc++; // ESC[m == ESC[0m if (es_argc == 0) es_argc++; // ESC[m == ESC[0m
@ -1580,50 +1632,46 @@ void InterpretEscSeq( void )
} }
return; return;
case 'h': // SM - ESC[#h Set Mode case 'h': // SM - ESC[#...h Set Mode
for (i = 0; i < es_argc; i++) case 'l': // RM - ESC[#...l Reset Mode
if (suffix2 == '+')
{ {
switch (es_argv[i]) BOOL state = (suffix == 'h');
for (i = 0; i < es_argc; i++)
if (suffix2 == '+') switch (es_argv[i])
{ {
case 1: // ACFM case 1: // ACFM
pState->fm = TRUE; pState->fm = state;
break; break;
} }
}
else switch (es_argv[i]) else switch (es_argv[i])
{ {
case 3: // CRM case 3: // CRM
pState->crm = TRUE; pState->crm = state;
break; break;
case 4: // IRM case 4: // IRM
im = TRUE; im = state;
break; break;
} }
return; return;
}
case 'l': // RM - ESC[#l Reset Mode default:
for (i = 0; i < es_argc; i++) return;
if (suffix2 == '+')
{
switch (es_argv[i])
{
case 1: // ACFM
pState->fm = FALSE;
break;
} }
} if (suffix2 == '!') switch (suffix)
else switch (es_argv[i]) // CRM - ESC[3l is handled during parsing
{ {
case 4: // IRM case 'p': // DECSTR - ESC[!p Soft reset
im = FALSE; if (es_argc != 0) return;
break; Reset( FALSE );
}
return; return;
case '~': default:
if (suffix2 == ',') // DECPS - ESC[#;#;#...,~ Play Sound return;
}
if (suffix2 == ',') switch (suffix)
{
case '~': // DECPS - ESC[#;#;#...,~ Play Sound
{ {
// Frequencies of notes obtained from: // Frequencies of notes obtained from:
// https://pages.mtu.edu/~suits/notefreqs.html // 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]] Beep( (es_argv[i] < lenof(snd_freq)) ? snd_freq[es_argv[i]]
: es_argv[i], dur ); : es_argv[i], dur );
} }
}
return; return;
}
default: default:
return; return;
@ -1984,6 +2032,7 @@ ParseAndPrintString( HANDLE hDev,
if (c == ESC) if (c == ESC)
{ {
suffix2 = 0; suffix2 = 0;
ibytes = 0;
get_state(); get_state();
state = (pState->crm) ? 7 : 2; state = (pState->crm) ? 7 : 2;
} }
@ -2025,10 +2074,14 @@ ParseAndPrintString( HANDLE hDev,
state = 1; state = 1;
} }
else if (c >= '\x20' && c <= '\x2f') 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') if (c == '0')
shifted = G0_special = TRUE; shifted = G0_special = TRUE;
@ -2091,6 +2144,10 @@ ParseAndPrintString( HANDLE hDev,
} }
state = 1; state = 1;
} }
else if (c == 'c') // RIS Reset to Initial State
{
Reset( TRUE );
}
else if (c == '[' || // CSI Control Sequence Introducer else if (c == '[' || // CSI Control Sequence Introducer
c == ']') // OSC Operating System Command c == ']') // OSC Operating System Command
{ {
@ -2134,15 +2191,16 @@ ParseAndPrintString( HANDLE hDev,
{ {
// ignore it // ignore it
} }
else if (c >= '\x3b' && c <= '\x3f') else if (c >= '\x3c' && c <= '\x3f')
{ {
prefix2 = c; prefix2 = c;
} }
else if (c >= '\x20' && c <= '\x2f') else if (c >= '\x20' && c <= '\x2f')
{ {
suffix2 = c; suffix2 = c;
++ibytes;
} }
else if (suffix2 != 0 && suffix2 != '+' && (suffix2 != ',' || c != '~')) else if (ibytes > 1)
{ {
state = 1; state = 1;
} }
@ -2175,8 +2233,9 @@ ParseAndPrintString( HANDLE hDev,
else if (c >= '\x20' && c <= '\x2f') else if (c >= '\x20' && c <= '\x2f')
{ {
suffix2 = c; suffix2 = c;
++ibytes;
} }
else if (suffix2 != 0 && suffix2 != '+' && (suffix2 != ',' || c != '~')) else if (ibytes > 1)
{ {
state = 1; state = 1;
} }

View File

@ -91,7 +91,7 @@
use -pu to unload from the parent. use -pu to unload from the parent.
*/ */
#define PDATE L"22 December, 2017" #define PDATE L"23 December, 2017"
#include "ansicon.h" #include "ansicon.h"
#include "version.h" #include "version.h"

View File

@ -191,6 +191,7 @@ Sequences Recognised
\e[?5W DECST8C Set Tab at Every 8 Columns \e[?5W DECST8C Set Tab at Every 8 Columns
\e[?5;#W DECST8C Set Tab at Every # Columns (ANSICON extension) \e[?5;#W DECST8C Set Tab at Every # Columns (ANSICON extension)
\e[#;#r DECSTBM Set Top and Bottom Margins \e[#;#r DECSTBM Set Top and Bottom Margins
\e[!p DECSTR Soft Terminal Reset
\e[?25h DECTCEM Text Cursor Enable Mode (show cursor) \e[?25h DECTCEM Text Cursor Enable Mode (show cursor)
\e[?25l DECTCEM Text Cursor Enable Mode (hide cursor) \e[?25l DECTCEM Text Cursor Enable Mode (hide cursor)
\e[#M DL Delete Line \e[#M DL Delete Line
@ -214,6 +215,7 @@ Sequences Recognised
\eE NEL Next Line \eE NEL Next Line
\e[#b REP Repeat \e[#b REP Repeat
\eM RI Reverse Index \eM RI Reverse Index
\ec RIS Reset to Initial State
\e(0 SCS Select Character Set (DEC special graphics) \e(0 SCS Select Character Set (DEC special graphics)
\e(B SCS Select Character Set (ASCII) \e(B SCS Select Character Set (ASCII)
\e[#;#;#m SGR Select Graphic Rendition \e[#;#;#m SGR Select Graphic Rendition
@ -322,7 +324,7 @@ Version History
Legend: + added, - bug-fixed, * changed. Legend: + added, - bug-fixed, * changed.
1.80 - 22 December, 2017: 1.80 - 23 December, 2017:
- fix unloading; - fix unloading;
- fix -e et al when redirecting to CON; - fix -e et al when redirecting to CON;
- hook CreateFile and CreateConsoleScreenBuffer to force read/write access - 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 SCS, but only for special/ASCII (same as Win10);
+ added tab handling (HT, HTS, TBC & DECST8C); + added tab handling (HT, HTS, TBC & DECST8C);
+ added IRM; + added IRM;
+ added DECOM, DECSTBM, SD & SU. + added DECOM, DECSTBM, SD & SU;
+ added DECSTR & RIS.
1.72 - 24 December, 2015: 1.72 - 24 December, 2015:
- handle STD_OUTPUT_HANDLE & STD_ERROR_HANDLE in WriteFile; - handle STD_OUTPUT_HANDLE & STD_ERROR_HANDLE in WriteFile;
@ -578,4 +581,4 @@ Distribution
============================== ==============================
Jason Hood, 22 December, 2017. Jason Hood, 23 December, 2017.

View File

@ -182,6 +182,25 @@ H set tab stop
[?95h don't clear screen when changing columns [?95h don't clear screen when changing columns
[?95l 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) [c sends "\e[?62;1c" to console input (where \e is escape)
[0c as above [0c as above
[5n sends "\e[0n" to console input [5n sends "\e[0n" to console input