Skip to content

Commit

Permalink
fix ECH to not move cursor, log output for a bit to help me reverse e…
Browse files Browse the repository at this point in the history
…ngineer some stuff
  • Loading branch information
doubleyewdee committed Nov 23, 2018
1 parent 3ba087e commit 88f1ae8
Show file tree
Hide file tree
Showing 2 changed files with 128 additions and 101 deletions.
225 changes: 125 additions & 100 deletions src/ConsoleBuffer/Buffer.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
namespace ConsoleBuffer
{
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Text;

public sealed class Buffer : INotifyPropertyChanged
{
Expand Down Expand Up @@ -181,115 +178,143 @@ private void HandleControlSequence(Commands.ControlSequence cmd)
switch (cmd)
{
case Commands.CursorMove cu:
switch (cu.Direction)
{
case Commands.CursorMove.CursorDirection.Up:
this.cursorY = (short)Math.Max(0, this.cursorY - cu.Count);
break;
case Commands.CursorMove.CursorDirection.Down:
this.cursorY = (short)Math.Min(this.Height - 1, this.cursorY + cu.Count);
break;
case Commands.CursorMove.CursorDirection.Backward:
this.cursorX = (short)Math.Max(0, this.cursorX - cu.Count);
break;
case Commands.CursorMove.CursorDirection.Forward:
this.cursorX = (short)Math.Min(this.Width - 1, this.cursorX + cu.Count);
break;
}
this.HandleCursorMove(cu);
break;
case Commands.EraseCharacter ec:
for (var c = 0; c < ec.Count; ++c)
{
this.lines[this.CurrentLine].SetGlyph(this.cursorX, 0x20);
++this.cursorX;
if (this.cursorX == this.Width)
{
// we won't advance beyond the end of viewable space when erasing, otherwise
// move on to the next line.
if (this.cursorY == this.Height - 1)
{
this.cursorX = (short)(this.Width - 1);
break;
}

++this.cursorY;
this.cursorX = 0;
}
}
case Commands.EraseCharacter ech:
this.HandleEraseCharacter(ech);
break;
case Commands.EraseIn eid when eid.Type == Commands.EraseIn.EraseType.Display:
int startY, endY;
switch (eid.Direction)
{
case Commands.EraseIn.Parameter.All:
startY = this.topVisibleLine;
endY = this.bottomVisibleLine;
break;
case Commands.EraseIn.Parameter.Before:
startY = this.topVisibleLine;
endY = this.CurrentLine;
break;
case Commands.EraseIn.Parameter.After:
startY = this.CurrentLine;
endY = this.bottomVisibleLine;
break;
default:
return;
}

for (var y = startY; y <= endY; ++y)
{
this.lines[y].Clear();
}
this.HandleEraseInDisplay(eid);
break;
case Commands.EraseIn eil when eil.Type == Commands.EraseIn.EraseType.Line:
int startX, endX;
switch (eil.Direction)
{
case Commands.EraseIn.Parameter.All:
startX = 0;
endX = this.Width - 1;
break;
case Commands.EraseIn.Parameter.Before:
startX = 0;
endX = this.cursorX;
break;
case Commands.EraseIn.Parameter.After:
startX = this.cursorX;
endX = this.Width - 1;
break;
default:
return;
}

for (var x = startX; x <= endX; ++x)
{
this.lines[this.CurrentLine].SetGlyph(x, 0x20);
}
this.HandleEraseInLine(eil);
break;
case Commands.SetCursorPosition cursorPos:
if (cursorPos.PosX > -1)
{
this.cursorX = (short)Math.Min(this.Width - 1, cursorPos.PosX);
}
if (cursorPos.PosY > -1)
{
this.cursorY = (short)Math.Min(this.Height - 1, cursorPos.PosY);
}
case Commands.SetCursorPosition scp:
this.HandleSetCursorPosition(scp);
break;
case Commands.SetMode sm:
switch (sm.Setting)
this.HandleSetMode(sm);
break;
default:
throw new InvalidOperationException($"Unknown CSI command type {cmd.GetType()}.");
}
}

private void HandleCursorMove(Commands.CursorMove cu)
{
switch (cu.Direction)
{
case Commands.CursorMove.CursorDirection.Up:
this.cursorY = (short)Math.Max(0, this.cursorY - cu.Count);
break;
case Commands.CursorMove.CursorDirection.Down:
this.cursorY = (short)Math.Min(this.Height - 1, this.cursorY + cu.Count);
break;
case Commands.CursorMove.CursorDirection.Backward:
this.cursorX = (short)Math.Max(0, this.cursorX - cu.Count);
break;
case Commands.CursorMove.CursorDirection.Forward:
this.cursorX = (short)Math.Min(this.Width - 1, this.cursorX + cu.Count);
break;
}
}

private void HandleEraseCharacter(Commands.EraseCharacter ech)
{
// erase characters starting at the current cursor position and possibly advancing down lines. do not erase below the bottom visible line.
var y = this.CurrentLine;
var x = this.cursorX;
for (var c = 0; c < ech.Count; ++c)
{
this.lines[y].SetGlyph(x, 0x20);
++x;
if (x == this.Width)
{
case Commands.SetMode.Parameter.CursorBlink:
this.CursorBlink = sm.Set;
break;
case Commands.SetMode.Parameter.CursorShow:
this.CursorVisible = sm.Set;
break;
if (++y > this.bottomVisibleLine)
{
break;
}
x = 0;
}
}
}

private void HandleEraseInDisplay(Commands.EraseIn eid)
{
int startY, endY;
switch (eid.Direction)
{
case Commands.EraseIn.Parameter.All:
startY = this.topVisibleLine;
endY = this.bottomVisibleLine;
break;
case Commands.EraseIn.Parameter.Before:
startY = this.topVisibleLine;
endY = this.CurrentLine;
break;
case Commands.EraseIn.Parameter.After:
startY = this.CurrentLine;
endY = this.bottomVisibleLine;
break;
default:
throw new InvalidOperationException($"Unknown CSI command type {cmd.GetType()}.");
return;
}

for (var y = startY; y <= endY; ++y)
{
this.lines[y].Clear();
}
}

private void HandleEraseInLine(Commands.EraseIn eil)
{
int startX, endX;
switch (eil.Direction)
{
case Commands.EraseIn.Parameter.All:
startX = 0;
endX = this.Width - 1;
break;
case Commands.EraseIn.Parameter.Before:
startX = 0;
endX = this.cursorX;
break;
case Commands.EraseIn.Parameter.After:
startX = this.cursorX;
endX = this.Width - 1;
break;
default:
return;
}

for (var x = startX; x <= endX; ++x)
{
this.lines[this.CurrentLine].SetGlyph(x, 0x20);
}
}

private void HandleSetCursorPosition(Commands.SetCursorPosition scp)
{
if (scp.PosX > -1)
{
this.cursorX = (short)Math.Min(this.Width - 1, scp.PosX);
}
if (scp.PosY > -1)
{
this.cursorY = (short)Math.Min(this.Height - 1, scp.PosY);
}
}

private void HandleSetMode(Commands.SetMode sm)
{
switch (sm.Setting)
{
case Commands.SetMode.Parameter.CursorBlink:
this.CursorBlink = sm.Set;
break;
case Commands.SetMode.Parameter.CursorShow:
this.CursorVisible = sm.Set;
break;
}
}

Expand Down
4 changes: 3 additions & 1 deletion src/ConsoleBuffer/ConsoleWrapper.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
namespace ConsoleBuffer
namespace ConsoleBuffer
{
using System;
using System.ComponentModel;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Win32.SafeHandles;

Expand Down Expand Up @@ -159,6 +160,7 @@ private void ReadConsoleTask()
continue;

this.Buffer.Append(input, read);
Logger.Verbose($"read: {Encoding.UTF8.GetString(input, 0, read)}");
this.OnPropertyChanged(nameof(this.Buffer));
}
catch (ObjectDisposedException)
Expand Down

0 comments on commit 88f1ae8

Please sign in to comment.