Use window height, not buffer.
Clear screen (\e[2J) will scroll in a new window the first time it's used, or the window has scrolled, or the cursor is on the last line of the buffer. Restore Cursor Position (\e[u) will recognise screen size changes and limit itself to the new boundaries.
This commit is contained in:
parent
9fa86512f3
commit
7539473550
224
ANSI.c
224
ANSI.c
@ -111,7 +111,7 @@
|
|||||||
v1.66, 20 & 21 September, 2013:
|
v1.66, 20 & 21 September, 2013:
|
||||||
fix 32-bit process trying to detect 64-bit process.
|
fix 32-bit process trying to detect 64-bit process.
|
||||||
|
|
||||||
v1.70, 25 January to 18 February, 2014:
|
v1.70, 25 January to 20 February, 2014:
|
||||||
don't hook ourself from LoadLibrary or LoadLibraryEx;
|
don't hook ourself from LoadLibrary or LoadLibraryEx;
|
||||||
update the LoadLibraryEx flags that should not cause hooking;
|
update the LoadLibraryEx flags that should not cause hooking;
|
||||||
inject by manipulating the import directory table; for 64-bit AnyCPU use
|
inject by manipulating the import directory table; for 64-bit AnyCPU use
|
||||||
@ -126,7 +126,8 @@
|
|||||||
don't hook a module that's already hooked us;
|
don't hook a module that's already hooked us;
|
||||||
better parsing of escape & CSI sequences;
|
better parsing of escape & CSI sequences;
|
||||||
ignore xterm 38 & 48 SGR values;
|
ignore xterm 38 & 48 SGR values;
|
||||||
change G1 blank from space to U+00A0 - No-Break Space.
|
change G1 blank from space to U+00A0 - No-Break Space;
|
||||||
|
use window height, not buffer.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "ansicon.h"
|
#include "ansicon.h"
|
||||||
@ -156,6 +157,7 @@ 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
|
||||||
int Pt_len;
|
int Pt_len;
|
||||||
BOOL shifted;
|
BOOL shifted;
|
||||||
|
int screen_top = -1; // initial window top when cleared
|
||||||
|
|
||||||
|
|
||||||
// DEC Special Graphics Character Set from
|
// DEC Special Graphics Character Set from
|
||||||
@ -473,6 +475,17 @@ void InterpretEscSeq( void )
|
|||||||
SMALL_RECT Rect;
|
SMALL_RECT Rect;
|
||||||
CHAR_INFO CharInfo;
|
CHAR_INFO CharInfo;
|
||||||
|
|
||||||
|
#define WIDTH Info.dwSize.X
|
||||||
|
#define CUR Info.dwCursorPosition
|
||||||
|
#define WIN Info.srWindow
|
||||||
|
#define TOP WIN.Top
|
||||||
|
#define BOTTOM WIN.Bottom
|
||||||
|
|
||||||
|
#define FillBlank( len, Pos ) \
|
||||||
|
FillConsoleOutputCharacter( hConOut, ' ', len, Pos, &NumberOfCharsWritten );\
|
||||||
|
FillConsoleOutputAttribute( hConOut, Info.wAttributes, len, Pos, \
|
||||||
|
&NumberOfCharsWritten )
|
||||||
|
|
||||||
if (prefix == '[')
|
if (prefix == '[')
|
||||||
{
|
{
|
||||||
if (prefix2 == '?' && (suffix == 'h' || suffix == 'l'))
|
if (prefix2 == '?' && (suffix == 'h' || suffix == 'l'))
|
||||||
@ -613,35 +626,50 @@ void InterpretEscSeq( void )
|
|||||||
switch (es_argv[0])
|
switch (es_argv[0])
|
||||||
{
|
{
|
||||||
case 0: // ESC[0J erase from cursor to end of display
|
case 0: // ESC[0J erase from cursor to end of display
|
||||||
len = (Info.dwSize.Y - Info.dwCursorPosition.Y - 1) * Info.dwSize.X
|
len = (BOTTOM - CUR.Y) * WIDTH + WIDTH - CUR.X;
|
||||||
+ Info.dwSize.X - Info.dwCursorPosition.X - 1;
|
FillBlank( len, CUR );
|
||||||
FillConsoleOutputCharacter( hConOut, ' ', len,
|
|
||||||
Info.dwCursorPosition,
|
|
||||||
&NumberOfCharsWritten );
|
|
||||||
FillConsoleOutputAttribute( hConOut, Info.wAttributes, len,
|
|
||||||
Info.dwCursorPosition,
|
|
||||||
&NumberOfCharsWritten );
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case 1: // ESC[1J erase from start to cursor.
|
case 1: // ESC[1J erase from start to cursor.
|
||||||
Pos.X = 0;
|
Pos.X = 0;
|
||||||
Pos.Y = 0;
|
Pos.Y = TOP;
|
||||||
len = Info.dwCursorPosition.Y * Info.dwSize.X
|
len = (CUR.Y - TOP) * WIDTH + CUR.X + 1;
|
||||||
+ Info.dwCursorPosition.X + 1;
|
FillBlank( len, Pos );
|
||||||
FillConsoleOutputCharacter( hConOut, ' ', len, Pos,
|
return;
|
||||||
&NumberOfCharsWritten );
|
|
||||||
FillConsoleOutputAttribute( hConOut, Info.wAttributes, len, Pos,
|
|
||||||
&NumberOfCharsWritten );
|
|
||||||
return;
|
|
||||||
|
|
||||||
case 2: // ESC[2J Clear screen and home cursor
|
case 2: // ESC[2J Clear screen and home cursor
|
||||||
|
if (TOP != screen_top || BOTTOM == Info.dwSize.Y - 1)
|
||||||
|
{
|
||||||
|
// Rather than clearing the existing window, make the current
|
||||||
|
// line the new top of the window (assuming this is the first
|
||||||
|
// thing a program does).
|
||||||
|
int range = BOTTOM - TOP;
|
||||||
|
if (CUR.Y + range < Info.dwSize.Y)
|
||||||
|
{
|
||||||
|
TOP = CUR.Y;
|
||||||
|
BOTTOM = TOP + range;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
BOTTOM = Info.dwSize.Y - 1;
|
||||||
|
TOP = BOTTOM - range;
|
||||||
|
Rect.Left = 0;
|
||||||
|
Rect.Right = WIDTH - 1;
|
||||||
|
Rect.Top = CUR.Y - TOP;
|
||||||
|
Rect.Bottom = CUR.Y - 1;
|
||||||
|
Pos.X = Pos.Y = 0;
|
||||||
|
CharInfo.Char.UnicodeChar = ' ';
|
||||||
|
CharInfo.Attributes = Info.wAttributes;
|
||||||
|
ScrollConsoleScreenBuffer(hConOut, &Rect, NULL, Pos, &CharInfo);
|
||||||
|
}
|
||||||
|
SetConsoleWindowInfo( hConOut, TRUE, &WIN );
|
||||||
|
screen_top = TOP;
|
||||||
|
}
|
||||||
Pos.X = 0;
|
Pos.X = 0;
|
||||||
Pos.Y = 0;
|
Pos.Y = TOP;
|
||||||
len = Info.dwSize.X * Info.dwSize.Y;
|
len = (BOTTOM - TOP + 1) * WIDTH;
|
||||||
FillConsoleOutputCharacter( hConOut, ' ', len, Pos,
|
FillBlank( len, Pos );
|
||||||
&NumberOfCharsWritten );
|
// Not technically correct, but perhaps expected.
|
||||||
FillConsoleOutputAttribute( hConOut, Info.wAttributes, len, Pos,
|
|
||||||
&NumberOfCharsWritten );
|
|
||||||
SetConsoleCursorPosition( hConOut, Pos );
|
SetConsoleCursorPosition( hConOut, Pos );
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -655,34 +683,20 @@ void InterpretEscSeq( void )
|
|||||||
switch (es_argv[0])
|
switch (es_argv[0])
|
||||||
{
|
{
|
||||||
case 0: // ESC[0K Clear to end of line
|
case 0: // ESC[0K Clear to end of line
|
||||||
len = Info.dwSize.X - Info.dwCursorPosition.X + 1;
|
len = WIDTH - CUR.X + 1;
|
||||||
FillConsoleOutputCharacter( hConOut, ' ', len,
|
FillBlank( len, CUR );
|
||||||
Info.dwCursorPosition,
|
|
||||||
&NumberOfCharsWritten );
|
|
||||||
FillConsoleOutputAttribute( hConOut, Info.wAttributes, len,
|
|
||||||
Info.dwCursorPosition,
|
|
||||||
&NumberOfCharsWritten );
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case 1: // ESC[1K Clear from start of line to cursor
|
case 1: // ESC[1K Clear from start of line to cursor
|
||||||
Pos.X = 0;
|
Pos.X = 0;
|
||||||
Pos.Y = Info.dwCursorPosition.Y;
|
Pos.Y = CUR.Y;
|
||||||
FillConsoleOutputCharacter( hConOut, ' ',
|
FillBlank( CUR.X + 1, Pos );
|
||||||
Info.dwCursorPosition.X + 1, Pos,
|
|
||||||
&NumberOfCharsWritten );
|
|
||||||
FillConsoleOutputAttribute( hConOut, Info.wAttributes,
|
|
||||||
Info.dwCursorPosition.X + 1, Pos,
|
|
||||||
&NumberOfCharsWritten );
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case 2: // ESC[2K Clear whole line.
|
case 2: // ESC[2K Clear whole line.
|
||||||
Pos.X = 0;
|
Pos.X = 0;
|
||||||
Pos.Y = Info.dwCursorPosition.Y;
|
Pos.Y = CUR.Y;
|
||||||
FillConsoleOutputCharacter( hConOut, ' ', Info.dwSize.X, Pos,
|
FillBlank( WIDTH, Pos );
|
||||||
&NumberOfCharsWritten );
|
|
||||||
FillConsoleOutputAttribute( hConOut, Info.wAttributes,
|
|
||||||
Info.dwSize.X, Pos,
|
|
||||||
&NumberOfCharsWritten );
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -692,82 +706,74 @@ void InterpretEscSeq( void )
|
|||||||
case 'X': // ESC[#X Erase # characters.
|
case 'X': // ESC[#X Erase # characters.
|
||||||
if (es_argc == 0) es_argv[es_argc++] = 1; // ESC[X == ESC[1X
|
if (es_argc == 0) es_argv[es_argc++] = 1; // ESC[X == ESC[1X
|
||||||
if (es_argc != 1) return;
|
if (es_argc != 1) return;
|
||||||
FillConsoleOutputCharacter( hConOut, ' ', es_argv[0],
|
FillBlank( es_argv[0], CUR );
|
||||||
Info.dwCursorPosition,
|
|
||||||
&NumberOfCharsWritten );
|
|
||||||
FillConsoleOutputAttribute( hConOut, Info.wAttributes, es_argv[0],
|
|
||||||
Info.dwCursorPosition,
|
|
||||||
&NumberOfCharsWritten );
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case 'L': // ESC[#L Insert # blank lines.
|
case 'L': // ESC[#L Insert # blank lines.
|
||||||
if (es_argc == 0) es_argv[es_argc++] = 1; // ESC[L == ESC[1L
|
if (es_argc == 0) es_argv[es_argc++] = 1; // ESC[L == ESC[1L
|
||||||
if (es_argc != 1) return;
|
if (es_argc != 1) return;
|
||||||
Rect.Left = 0;
|
Rect.Left = WIN.Left = 0;
|
||||||
Rect.Top = Info.dwCursorPosition.Y;
|
Rect.Right = WIN.Right = WIDTH - 1;
|
||||||
Rect.Right = Info.dwSize.X - 1;
|
Rect.Top = CUR.Y;
|
||||||
Rect.Bottom = Info.dwSize.Y - 1;
|
Rect.Bottom = BOTTOM;
|
||||||
Pos.X = 0;
|
Pos.X = 0;
|
||||||
Pos.Y = Info.dwCursorPosition.Y + es_argv[0];
|
Pos.Y = CUR.Y + es_argv[0];
|
||||||
CharInfo.Char.UnicodeChar = ' ';
|
CharInfo.Char.UnicodeChar = ' ';
|
||||||
CharInfo.Attributes = Info.wAttributes;
|
CharInfo.Attributes = Info.wAttributes;
|
||||||
ScrollConsoleScreenBuffer( hConOut, &Rect, NULL, Pos, &CharInfo );
|
ScrollConsoleScreenBuffer( hConOut, &Rect, &WIN, Pos, &CharInfo );
|
||||||
|
// Technically should home the cursor, but perhaps not expected.
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case 'M': // ESC[#M Delete # lines.
|
case 'M': // ESC[#M Delete # lines.
|
||||||
if (es_argc == 0) es_argv[es_argc++] = 1; // ESC[M == ESC[1M
|
if (es_argc == 0) es_argv[es_argc++] = 1; // ESC[M == ESC[1M
|
||||||
if (es_argc != 1) return;
|
if (es_argc != 1) return;
|
||||||
if (es_argv[0] > Info.dwSize.Y - Info.dwCursorPosition.Y)
|
Rect.Left = WIN.Left = 0;
|
||||||
es_argv[0] = Info.dwSize.Y - Info.dwCursorPosition.Y;
|
Rect.Right = WIN.Right = WIDTH - 1;
|
||||||
Rect.Left = 0;
|
Rect.Bottom = BOTTOM;
|
||||||
Rect.Top = Info.dwCursorPosition.Y + es_argv[0];
|
Rect.Top = CUR.Y - es_argv[0];
|
||||||
Rect.Right = Info.dwSize.X - 1;
|
|
||||||
Rect.Bottom = Info.dwSize.Y - 1;
|
|
||||||
Pos.X = 0;
|
Pos.X = 0;
|
||||||
Pos.Y = Info.dwCursorPosition.Y;
|
Pos.Y = TOP = CUR.Y;
|
||||||
CharInfo.Char.UnicodeChar = ' ';
|
CharInfo.Char.UnicodeChar = ' ';
|
||||||
CharInfo.Attributes = Info.wAttributes;
|
CharInfo.Attributes = Info.wAttributes;
|
||||||
ScrollConsoleScreenBuffer( hConOut, &Rect, NULL, Pos, &CharInfo );
|
ScrollConsoleScreenBuffer( hConOut, &Rect, &WIN, Pos, &CharInfo );
|
||||||
|
// Technically should home the cursor, but perhaps not expected.
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case 'P': // ESC[#P Delete # characters.
|
case 'P': // ESC[#P Delete # characters.
|
||||||
if (es_argc == 0) es_argv[es_argc++] = 1; // ESC[P == ESC[1P
|
if (es_argc == 0) es_argv[es_argc++] = 1; // ESC[P == ESC[1P
|
||||||
if (es_argc != 1) return;
|
if (es_argc != 1) return;
|
||||||
if (Info.dwCursorPosition.X + es_argv[0] > Info.dwSize.X - 1)
|
Rect.Left = WIN.Left = CUR.X;
|
||||||
es_argv[0] = Info.dwSize.X - Info.dwCursorPosition.X;
|
Rect.Right = WIN.Right = WIDTH - 1;
|
||||||
Rect.Left = Info.dwCursorPosition.X + es_argv[0];
|
Pos.X = CUR.X - es_argv[0];
|
||||||
Rect.Top = Info.dwCursorPosition.Y;
|
Pos.Y =
|
||||||
Rect.Right = Info.dwSize.X - 1;
|
Rect.Top =
|
||||||
Rect.Bottom = Info.dwCursorPosition.Y;
|
Rect.Bottom = CUR.Y;
|
||||||
CharInfo.Char.UnicodeChar = ' ';
|
CharInfo.Char.UnicodeChar = ' ';
|
||||||
CharInfo.Attributes = Info.wAttributes;
|
CharInfo.Attributes = Info.wAttributes;
|
||||||
ScrollConsoleScreenBuffer( hConOut, &Rect, NULL, Info.dwCursorPosition,
|
ScrollConsoleScreenBuffer( hConOut, &Rect, &WIN, Pos, &CharInfo );
|
||||||
&CharInfo );
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case '@': // ESC[#@ Insert # blank characters.
|
case '@': // ESC[#@ Insert # blank characters.
|
||||||
if (es_argc == 0) es_argv[es_argc++] = 1; // ESC[@ == ESC[1@
|
if (es_argc == 0) es_argv[es_argc++] = 1; // ESC[@ == ESC[1@
|
||||||
if (es_argc != 1) return;
|
if (es_argc != 1) return;
|
||||||
if (Info.dwCursorPosition.X + es_argv[0] > Info.dwSize.X - 1)
|
Rect.Left = WIN.Left = CUR.X;
|
||||||
es_argv[0] = Info.dwSize.X - Info.dwCursorPosition.X;
|
Rect.Right = WIN.Right = WIDTH - 1;
|
||||||
Rect.Left = Info.dwCursorPosition.X;
|
Pos.X = CUR.X + es_argv[0];
|
||||||
Rect.Top = Info.dwCursorPosition.Y;
|
Pos.Y =
|
||||||
Rect.Right = Info.dwSize.X - 1 - es_argv[0];
|
Rect.Top =
|
||||||
Rect.Bottom = Info.dwCursorPosition.Y;
|
Rect.Bottom = CUR.Y;
|
||||||
Pos.X = Info.dwCursorPosition.X + es_argv[0];
|
|
||||||
Pos.Y = Info.dwCursorPosition.Y;
|
|
||||||
CharInfo.Char.UnicodeChar = ' ';
|
CharInfo.Char.UnicodeChar = ' ';
|
||||||
CharInfo.Attributes = Info.wAttributes;
|
CharInfo.Attributes = Info.wAttributes;
|
||||||
ScrollConsoleScreenBuffer( hConOut, &Rect, NULL, Pos, &CharInfo );
|
ScrollConsoleScreenBuffer( hConOut, &Rect, &WIN, Pos, &CharInfo );
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case 'k': // ESC[#k
|
case 'k': // ESC[#k
|
||||||
case 'A': // ESC[#A Moves cursor up # lines
|
case 'A': // ESC[#A Moves cursor up # lines
|
||||||
if (es_argc == 0) es_argv[es_argc++] = 1; // ESC[A == ESC[1A
|
if (es_argc == 0) es_argv[es_argc++] = 1; // ESC[A == ESC[1A
|
||||||
if (es_argc != 1) return;
|
if (es_argc != 1) return;
|
||||||
Pos.Y = Info.dwCursorPosition.Y - es_argv[0];
|
Pos.Y = CUR.Y - es_argv[0];
|
||||||
if (Pos.Y < 0) Pos.Y = 0;
|
if (Pos.Y < TOP) Pos.Y = TOP;
|
||||||
Pos.X = Info.dwCursorPosition.X;
|
Pos.X = CUR.X;
|
||||||
SetConsoleCursorPosition( hConOut, Pos );
|
SetConsoleCursorPosition( hConOut, Pos );
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -775,9 +781,9 @@ void InterpretEscSeq( void )
|
|||||||
case 'B': // ESC[#B Moves cursor down # lines
|
case 'B': // ESC[#B Moves cursor down # lines
|
||||||
if (es_argc == 0) es_argv[es_argc++] = 1; // ESC[B == ESC[1B
|
if (es_argc == 0) es_argv[es_argc++] = 1; // ESC[B == ESC[1B
|
||||||
if (es_argc != 1) return;
|
if (es_argc != 1) return;
|
||||||
Pos.Y = Info.dwCursorPosition.Y + es_argv[0];
|
Pos.Y = CUR.Y + es_argv[0];
|
||||||
if (Pos.Y >= Info.dwSize.Y) Pos.Y = Info.dwSize.Y - 1;
|
if (Pos.Y > BOTTOM) Pos.Y = BOTTOM;
|
||||||
Pos.X = Info.dwCursorPosition.X;
|
Pos.X = CUR.X;
|
||||||
SetConsoleCursorPosition( hConOut, Pos );
|
SetConsoleCursorPosition( hConOut, Pos );
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -785,9 +791,9 @@ void InterpretEscSeq( void )
|
|||||||
case 'C': // ESC[#C Moves cursor forward # spaces
|
case 'C': // ESC[#C Moves cursor forward # spaces
|
||||||
if (es_argc == 0) es_argv[es_argc++] = 1; // ESC[C == ESC[1C
|
if (es_argc == 0) es_argv[es_argc++] = 1; // ESC[C == ESC[1C
|
||||||
if (es_argc != 1) return;
|
if (es_argc != 1) return;
|
||||||
Pos.X = Info.dwCursorPosition.X + es_argv[0];
|
Pos.X = CUR.X + es_argv[0];
|
||||||
if (Pos.X >= Info.dwSize.X) Pos.X = Info.dwSize.X - 1;
|
if (Pos.X >= WIDTH) Pos.X = WIDTH - 1;
|
||||||
Pos.Y = Info.dwCursorPosition.Y;
|
Pos.Y = CUR.Y;
|
||||||
SetConsoleCursorPosition( hConOut, Pos );
|
SetConsoleCursorPosition( hConOut, Pos );
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -795,17 +801,17 @@ void InterpretEscSeq( void )
|
|||||||
case 'D': // ESC[#D Moves cursor back # spaces
|
case 'D': // ESC[#D Moves cursor back # spaces
|
||||||
if (es_argc == 0) es_argv[es_argc++] = 1; // ESC[D == ESC[1D
|
if (es_argc == 0) es_argv[es_argc++] = 1; // ESC[D == ESC[1D
|
||||||
if (es_argc != 1) return;
|
if (es_argc != 1) return;
|
||||||
Pos.X = Info.dwCursorPosition.X - es_argv[0];
|
Pos.X = CUR.X - es_argv[0];
|
||||||
if (Pos.X < 0) Pos.X = 0;
|
if (Pos.X < 0) Pos.X = 0;
|
||||||
Pos.Y = Info.dwCursorPosition.Y;
|
Pos.Y = CUR.Y;
|
||||||
SetConsoleCursorPosition( hConOut, Pos );
|
SetConsoleCursorPosition( hConOut, Pos );
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case 'E': // ESC[#E Moves cursor down # lines, column 1.
|
case 'E': // ESC[#E Moves cursor down # lines, column 1.
|
||||||
if (es_argc == 0) es_argv[es_argc++] = 1; // ESC[E == ESC[1E
|
if (es_argc == 0) es_argv[es_argc++] = 1; // ESC[E == ESC[1E
|
||||||
if (es_argc != 1) return;
|
if (es_argc != 1) return;
|
||||||
Pos.Y = Info.dwCursorPosition.Y + es_argv[0];
|
Pos.Y = CUR.Y + es_argv[0];
|
||||||
if (Pos.Y >= Info.dwSize.Y) Pos.Y = Info.dwSize.Y - 1;
|
if (Pos.Y > BOTTOM) Pos.Y = BOTTOM;
|
||||||
Pos.X = 0;
|
Pos.X = 0;
|
||||||
SetConsoleCursorPosition( hConOut, Pos );
|
SetConsoleCursorPosition( hConOut, Pos );
|
||||||
return;
|
return;
|
||||||
@ -813,8 +819,8 @@ void InterpretEscSeq( void )
|
|||||||
case 'F': // ESC[#F Moves cursor up # lines, column 1.
|
case 'F': // ESC[#F Moves cursor up # lines, column 1.
|
||||||
if (es_argc == 0) es_argv[es_argc++] = 1; // ESC[F == ESC[1F
|
if (es_argc == 0) es_argv[es_argc++] = 1; // ESC[F == ESC[1F
|
||||||
if (es_argc != 1) return;
|
if (es_argc != 1) return;
|
||||||
Pos.Y = Info.dwCursorPosition.Y - es_argv[0];
|
Pos.Y = CUR.Y - es_argv[0];
|
||||||
if (Pos.Y < 0) Pos.Y = 0;
|
if (Pos.Y < TOP) Pos.Y = TOP;
|
||||||
Pos.X = 0;
|
Pos.X = 0;
|
||||||
SetConsoleCursorPosition( hConOut, Pos );
|
SetConsoleCursorPosition( hConOut, Pos );
|
||||||
return;
|
return;
|
||||||
@ -824,9 +830,9 @@ void InterpretEscSeq( void )
|
|||||||
if (es_argc == 0) es_argv[es_argc++] = 1; // ESC[G == ESC[1G
|
if (es_argc == 0) es_argv[es_argc++] = 1; // ESC[G == ESC[1G
|
||||||
if (es_argc != 1) return;
|
if (es_argc != 1) return;
|
||||||
Pos.X = es_argv[0] - 1;
|
Pos.X = es_argv[0] - 1;
|
||||||
if (Pos.X >= Info.dwSize.X) Pos.X = Info.dwSize.X - 1;
|
if (Pos.X >= WIDTH) Pos.X = WIDTH - 1;
|
||||||
if (Pos.X < 0) Pos.X = 0;
|
if (Pos.X < 0) Pos.X = 0;
|
||||||
Pos.Y = Info.dwCursorPosition.Y;
|
Pos.Y = CUR.Y;
|
||||||
SetConsoleCursorPosition( hConOut, Pos );
|
SetConsoleCursorPosition( hConOut, Pos );
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -834,8 +840,8 @@ void InterpretEscSeq( void )
|
|||||||
if (es_argc == 0) es_argv[es_argc++] = 1; // ESC[d == ESC[1d
|
if (es_argc == 0) es_argv[es_argc++] = 1; // ESC[d == ESC[1d
|
||||||
if (es_argc != 1) return;
|
if (es_argc != 1) return;
|
||||||
Pos.Y = es_argv[0] - 1;
|
Pos.Y = es_argv[0] - 1;
|
||||||
if (Pos.Y < 0) Pos.Y = 0;
|
if (Pos.Y < TOP) Pos.Y = TOP;
|
||||||
if (Pos.Y >= Info.dwSize.Y) Pos.Y = Info.dwSize.Y - 1;
|
if (Pos.Y > BOTTOM) Pos.Y = BOTTOM;
|
||||||
SetConsoleCursorPosition( hConOut, Pos );
|
SetConsoleCursorPosition( hConOut, Pos );
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -848,23 +854,28 @@ void InterpretEscSeq( void )
|
|||||||
if (es_argc > 2) return;
|
if (es_argc > 2) return;
|
||||||
Pos.X = es_argv[1] - 1;
|
Pos.X = es_argv[1] - 1;
|
||||||
if (Pos.X < 0) Pos.X = 0;
|
if (Pos.X < 0) Pos.X = 0;
|
||||||
if (Pos.X >= Info.dwSize.X) Pos.X = Info.dwSize.X - 1;
|
if (Pos.X >= WIDTH) Pos.X = WIDTH - 1;
|
||||||
Pos.Y = es_argv[0] - 1;
|
Pos.Y = es_argv[0] - 1;
|
||||||
if (Pos.Y < 0) Pos.Y = 0;
|
if (Pos.Y < TOP) Pos.Y = TOP;
|
||||||
if (Pos.Y >= Info.dwSize.Y) Pos.Y = Info.dwSize.Y - 1;
|
if (Pos.Y > BOTTOM) Pos.Y = BOTTOM;
|
||||||
SetConsoleCursorPosition( hConOut, Pos );
|
SetConsoleCursorPosition( hConOut, Pos );
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case 's': // ESC[s Saves cursor position for recall later
|
case 's': // ESC[s Saves cursor position for recall later
|
||||||
if (es_argc != 0) return;
|
if (es_argc != 0) return;
|
||||||
get_state();
|
get_state();
|
||||||
pState->SavePos = Info.dwCursorPosition;
|
pState->SavePos.X = CUR.X;
|
||||||
|
pState->SavePos.Y = CUR.Y - TOP;
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case 'u': // ESC[u Return to saved cursor position
|
case 'u': // ESC[u Return to saved cursor position
|
||||||
if (es_argc != 0) return;
|
if (es_argc != 0) return;
|
||||||
get_state();
|
get_state();
|
||||||
SetConsoleCursorPosition( hConOut, pState->SavePos );
|
Pos.X = pState->SavePos.X;
|
||||||
|
Pos.Y = pState->SavePos.Y + TOP;
|
||||||
|
if (Pos.X >= WIDTH) Pos.X = WIDTH - 1;
|
||||||
|
if (Pos.Y > BOTTOM) Pos.Y = BOTTOM;
|
||||||
|
SetConsoleCursorPosition( hConOut, Pos );
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case 'n': // ESC[#n Device status report
|
case 'n': // ESC[#n Device status report
|
||||||
@ -878,8 +889,7 @@ void InterpretEscSeq( void )
|
|||||||
case 6: // ESC[6n Report cursor position
|
case 6: // ESC[6n Report cursor position
|
||||||
{
|
{
|
||||||
TCHAR buf[32];
|
TCHAR buf[32];
|
||||||
wsprintf( buf, L"\33[%d;%dR", Info.dwCursorPosition.Y + 1,
|
wsprintf( buf, L"\33[%d;%dR", CUR.Y - TOP + 1, CUR.X + 1 );
|
||||||
Info.dwCursorPosition.X + 1 );
|
|
||||||
SendSequence( buf );
|
SendSequence( buf );
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
@ -87,7 +87,7 @@
|
|||||||
add error codes to some message.
|
add error codes to some message.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define PDATE L"18 February, 2014"
|
#define PDATE L"20 February, 2014"
|
||||||
|
|
||||||
#include "ansicon.h"
|
#include "ansicon.h"
|
||||||
#include "version.h"
|
#include "version.h"
|
||||||
|
26
readme.txt
26
readme.txt
@ -147,11 +147,11 @@ Sequences Recognised
|
|||||||
|
|
||||||
The following escape sequences are recognised.
|
The following escape sequences are recognised.
|
||||||
|
|
||||||
\e]0;titleBEL Set (xterm) window's title (and icon, ignored)
|
\e]0;titleBEL xterm: Set window's title (and icon, ignored)
|
||||||
\e]2;titleBEL Set (xterm) window's title
|
\e]2;titleBEL xterm: Set window's title
|
||||||
\e[21t Report (xterm) window's title
|
\e[21t xterm: Report window's title
|
||||||
\e[s Save Cursor
|
\e[s ANSI.SYS: Save Cursor Position
|
||||||
\e[u Restore Cursor
|
\e[u ANSI.SYS: Restore Cursor Position
|
||||||
\e[#G CHA Cursor Character Absolute
|
\e[#G CHA Cursor Character Absolute
|
||||||
\e[#E CNL Cursor Next Line
|
\e[#E CNL Cursor Next Line
|
||||||
\e[#F CPL Cursor Preceding Line
|
\e[#F CPL Cursor Preceding Line
|
||||||
@ -194,6 +194,12 @@ Sequences Recognised
|
|||||||
iable ANSICON_DEF can be used to change the default colors (same value as
|
iable ANSICON_DEF can be used to change the default colors (same value as
|
||||||
'-m'; setting the variable does not change the current colors).
|
'-m'; setting the variable does not change the current colors).
|
||||||
|
|
||||||
|
The first time a program clears the screen ('\e[2J') will actually scroll
|
||||||
|
in a new window (assuming the buffer is bigger than the window, of course).
|
||||||
|
Subsequent clears will then blank the window. However, if the window has
|
||||||
|
scrolled, or the cursor is on the last line of the buffer, it will again
|
||||||
|
scroll in a new window.
|
||||||
|
|
||||||
|
|
||||||
Sequences Ignored
|
Sequences Ignored
|
||||||
=================
|
=================
|
||||||
@ -261,7 +267,7 @@ DEC Special Graphics Character Set
|
|||||||
Limitations
|
Limitations
|
||||||
===========
|
===========
|
||||||
|
|
||||||
The entire console buffer is used, not just the visible window.
|
Line sequences use the window; column sequences use the buffer.
|
||||||
|
|
||||||
There's a conflict with NVIDIA's drivers, requiring the setting of the
|
There's a conflict with NVIDIA's drivers, requiring the setting of the
|
||||||
Environment Variable:
|
Environment Variable:
|
||||||
@ -277,7 +283,7 @@ Version History
|
|||||||
|
|
||||||
Legend: + added, - bug-fixed, * changed.
|
Legend: + added, - bug-fixed, * changed.
|
||||||
|
|
||||||
1.70 - 18 February, 2014:
|
1.70 - 20 February, 2014:
|
||||||
- don't hook again if using LoadLibrary or LoadLibraryEx;
|
- don't hook again if using LoadLibrary or LoadLibraryEx;
|
||||||
- update the LoadLibraryEx flags that shouldn't hook;
|
- update the LoadLibraryEx flags that shouldn't hook;
|
||||||
- restore original attributes on detach (for LoadLibrary/FreeLibrary usage);
|
- restore original attributes on detach (for LoadLibrary/FreeLibrary usage);
|
||||||
@ -285,12 +291,14 @@ Version History
|
|||||||
- an installed ansicon.exe will restore current (not default) attributes;
|
- an installed ansicon.exe will restore current (not default) attributes;
|
||||||
- attributes and saved position are local to each console window;
|
- attributes and saved position are local to each console window;
|
||||||
- improved recognition of unsupported sequences;
|
- improved recognition of unsupported sequences;
|
||||||
|
- restore cursor to bounds, if size reduced;
|
||||||
* inject into a created process by modifying the import descriptor table
|
* inject into a created process by modifying the import descriptor table
|
||||||
(-p will use CreateRemoteThread);
|
(-p will use CreateRemoteThread);
|
||||||
* log: remove the quotes around the CreateProcess command line;
|
* log: remove the quotes around the CreateProcess command line;
|
||||||
add an underscore in 64-bit addresses to distinguish 8-digit groups;
|
add an underscore in 64-bit addresses to distinguish 8-digit groups;
|
||||||
* ANSICON_EXC can exclude entire programs;
|
* ANSICON_EXC can exclude entire programs;
|
||||||
* switch G1 blank from space (U+0020) to No-Break Space (U+00A0).
|
* switch G1 blank from space (U+0020) to No-Break Space (U+00A0);
|
||||||
|
* use window height, not buffer.
|
||||||
|
|
||||||
1.66 - 20 September, 2013:
|
1.66 - 20 September, 2013:
|
||||||
- fix 32-bit process trying to detect 64-bit process.
|
- fix 32-bit process trying to detect 64-bit process.
|
||||||
@ -478,4 +486,4 @@ Distribution
|
|||||||
|
|
||||||
|
|
||||||
==============================
|
==============================
|
||||||
Jason Hood, 18 February, 2014.
|
Jason Hood, 20 February, 2014.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user