Skip to content

Commit

Permalink
gh-1159, gh-1775: ANSI, tmux, compatibility issues.
Browse files Browse the repository at this point in the history
  • Loading branch information
Maximus5 committed Feb 24, 2019
1 parent bbc1837 commit 5eaceac
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 14 deletions.
16 changes: 9 additions & 7 deletions src/ConEmuCD/ConAnsiImpl.cpp
Expand Up @@ -1313,12 +1313,13 @@ CSI P s @ Insert P s (Blank) Character(s) (default = 1) (ICH)
//if (gbIsVimProcess)
// gbIsVimAnsi = true;

struct PointXY {int X,Y;};
const auto& workSize = m_Table->GetSize();
const struct {int left, top, right, bottom;} workRgn = {0, 0, workSize.x - 1, workSize.y - 1};
const struct {int left, top, right, bottom;} workRgn = {0, 0, (int)workSize.x - 1, workSize.y - 1};
_ASSERTEX(workRgn.left <= workRgn.right && workRgn.top <= workRgn.bottom);
const auto& clipRgn = m_Table->GetScrollRegion();
const struct {int X, Y;} cur = {(int)m_Table->GetCursor().x, m_Table->GetCursor().y};
struct {int X,Y;} crNewPos = {cur.X, cur.Y};
const auto cur = PointXY{(int)m_Table->GetCursor().x, m_Table->GetCursor().y};
PointXY crNewPos = cur;
enum class Direction { kAbsolute, kCompatible, kRelative };

auto set_y = [&crNewPos, &workRgn, &clipRgn, &cur](Direction direction, int value)
Expand All @@ -1329,9 +1330,9 @@ CSI P s @ Insert P s (Blank) Character(s) (default = 1) (ICH)
crNewPos.Y = workRgn.bottom;
else if (direction == Direction::kAbsolute || direction == Direction::kCompatible)
crNewPos.Y = std::max(workRgn.top, std::min(workRgn.bottom, value));
else if (value < 0 && cur.Y >= clipRgn.Top)
else if (value < 0 && cur.Y >= (int)clipRgn.Top)
crNewPos.Y = std::max<int>(clipRgn.Top, std::min(workRgn.bottom, cur.Y + value));
else if (value > 0 && cur.Y <= clipRgn.Bottom)
else if (value > 0 && cur.Y <= (int)clipRgn.Bottom)
crNewPos.Y = std::max(workRgn.top, std::min<int>(clipRgn.Bottom, cur.Y + value));
else
crNewPos.Y = std::max(workRgn.top, std::min(workRgn.bottom, cur.Y + value));
Expand Down Expand Up @@ -1519,7 +1520,7 @@ CSI P s @ Insert P s (Blank) Character(s) (default = 1) (ICH)
// of the screen)
//
// Values are 1-based
if ((Code.ArgC >= 2) && (Code.ArgV[0] >= 1) && (Code.ArgV[1] >= Code.ArgV[0]))
if ((Code.ArgC >= 2) && (Code.ArgV[0] >= 0) && (Code.ArgV[1] >= Code.ArgV[0]))
SetScrollRegion(true, Code.ArgV[0], Code.ArgV[1]);
else
SetScrollRegion(false);
Expand Down Expand Up @@ -2377,7 +2378,8 @@ void SrvAnsiImpl::SetScrollRegion(bool bRegion, int nStart, int nEnd)
{
if (bRegion)
{
_ASSERTE(nStart > 0 && nEnd >= nStart);
// note: the '\e[0;35r' shall be treated as '\e[1;35r'
_ASSERTE(nStart >= 0 && nEnd >= nStart);
m_Table->SetScrollRegion(true, std::max(0, nStart - 1), std::max(0, nEnd - 1));
}
else
Expand Down
41 changes: 34 additions & 7 deletions src/ConEmuHk/Ansi.cpp
Expand Up @@ -1592,6 +1592,7 @@ int CEAnsi::NextEscCode(LPCWSTR lpBuffer, LPCWSTR lpEnd, wchar_t (&szPreDump)[CE
case L'M': // Reverse LF
case L'E': // CR-LF
case L'D': // LF
// #ANSI gh-1827: support 'H' to set tab stops
// xterm?
lpStart = lpEscStart;
Code.First = 27;
Expand Down Expand Up @@ -2760,11 +2761,32 @@ CSI P s @ Insert P s (Blank) Character(s) (default = 1) (ICH)
// Change cursor position
if (GetConsoleScreenBufferInfoCached(hConsoleOutput, &csbi))
{
struct PointXY {int X,Y;};
auto get_scroll_region = [&csbi]()
{
const auto& srw = csbi.srWindow;
SMALL_RECT clipRgn = {0, 0, srw.Right - srw.Left, srw.Bottom - srw.Top};
if (gDisplayOpt.ScrollRegion)
{
clipRgn.Top = std::max<SHORT>(0, std::min<SHORT>(gDisplayOpt.ScrollStart, csbi.dwSize.Y-1));
clipRgn.Bottom = std::max<SHORT>(0, std::min<SHORT>(gDisplayOpt.ScrollEnd, csbi.dwSize.Y-1));
}
return clipRgn;
};
auto get_cursor = [&csbi]()
{
const auto& srw = csbi.srWindow;
int visible_rows = srw.Bottom - srw.Top;
return PointXY{
csbi.dwCursorPosition.X,
std::max(0, std::min(visible_rows, csbi.dwCursorPosition.Y - srw.Top))
};
};
const struct {int left, top, right, bottom;} workRgn = {0, 0, csbi.dwSize.X - 1, csbi.dwSize.Y - 1};
_ASSERTEX(workRgn.left <= workRgn.right && workRgn.top <= workRgn.bottom);
const auto& clipRgn = csbi.srWindow;
const struct {int X,Y;} cur = {csbi.dwCursorPosition.X, csbi.dwCursorPosition.Y};
struct {int X,Y;} crNewPos = {cur.X, cur.Y};
const auto& clipRgn = get_scroll_region();
const auto cur = get_cursor();
PointXY crNewPos = cur;

enum class Direction { kAbsolute, kCompatible, kRelative };

Expand Down Expand Up @@ -2846,8 +2868,12 @@ CSI P s @ Insert P s (Blank) Character(s) (default = 1) (ICH)
// Goto
ORIGINAL_KRNL(SetConsoleCursorPosition);
{
COORD crNewPosAPI = { crNewPos.X, crNewPos.Y };
_ASSERTE(crNewPosAPI.X == crNewPos.X && crNewPosAPI.Y == crNewPos.Y);
const auto& srw = csbi.srWindow;
COORD crNewPosAPI = {
(SHORT)crNewPos.X,
(SHORT)std::min<int>(csbi.dwSize.Y - 1, srw.Top + crNewPos.Y)
};
_ASSERTE(crNewPosAPI.X == crNewPos.X);
F(SetConsoleCursorPosition)(hConsoleOutput, crNewPosAPI);
}

Expand Down Expand Up @@ -3001,7 +3027,7 @@ CSI P s @ Insert P s (Blank) Character(s) (default = 1) (ICH)
//(The default for Pt is line 1, the default for Pb is the end
// of the screen)
//
if ((Code.ArgC >= 2) && (Code.ArgV[0] >= 1) && (Code.ArgV[1] >= Code.ArgV[0]))
if ((Code.ArgC >= 2) && (Code.ArgV[0] >= 0) && (Code.ArgV[1] >= Code.ArgV[0]))
{
// Values are 1-based
SetScrollRegion(true, true, Code.ArgV[0], Code.ArgV[1], hConsoleOutput);
Expand Down Expand Up @@ -3534,7 +3560,6 @@ CSI P s @ Insert P s (Blank) Character(s) (default = 1) (ICH)
case L't':
if (Code.ArgC > 0 && Code.ArgC <= 3)
{
wchar_t sCurInfo[32];
for (int i = 0; i < Code.ArgC; i++)
{
switch (Code.ArgV[i])
Expand Down Expand Up @@ -3952,6 +3977,8 @@ void CEAnsi::SetScrollRegion(bool bRegion, bool bRelative, int nStart, int nEnd,
{
if (bRegion && (nStart >= 0) && (nStart <= nEnd))
{
// note: the '\e[0;35r' shall be treated as '\e[1;35r'
_ASSERTE(nStart >= 0 && nEnd >= nStart);
SMALL_RECT working = GetWorkingRegion(hConsoleOutput, bRelative);
_ASSERTE(working.Top>=0 && working.Left>=0 && working.Bottom>=working.Top && working.Right>=working.Left);
if (bRelative)
Expand Down

0 comments on commit 5eaceac

Please sign in to comment.