diff --git a/VtNetCore/VirtualTerminal/Model/TerminalAttribute.cs b/VtNetCore/VirtualTerminal/Model/TerminalAttribute.cs
index 5bbf813..b5863cb 100644
--- a/VtNetCore/VirtualTerminal/Model/TerminalAttribute.cs
+++ b/VtNetCore/VirtualTerminal/Model/TerminalAttribute.cs
@@ -1,6 +1,8 @@
namespace VtNetCore.VirtualTerminal.Model
{
using System;
+ using System.Collections.Generic;
+ using System.Linq;
using VtNetCore.VirtualTerminal.Enums;
///
@@ -8,21 +10,21 @@
///
public class TerminalAttribute
{
- private static readonly ushort BrightBit = 0x0040;
- private static readonly ushort UnderscoreBit = 0x0080;
- private static readonly ushort StandoutBit = 0x0100;
- private static readonly ushort BlinkBit = 0x0200;
- private static readonly ushort ReverseBit = 0x0400;
- private static readonly ushort HiddenBit = 0x0800;
- private static readonly ushort ProtectionBits = 0x3000;
+ public TerminalColor ForegroundRgb { get; set; } = TerminalColorsLookup[ETerminalColor.Black];
- private ushort InternalBits =
- (ushort)ETerminalColor.White | // ForegroundColor
- (ushort)ETerminalColor.Black; // BackgroundColor
+ public TerminalColor BackgroundRgb { get; set; } = TerminalColorsLookup[ETerminalColor.White];
- public TerminalColor ForegroundRgb { get; set; }
-
- public TerminalColor BackgroundRgb { get; set; }
+ public static readonly Dictionary TerminalColorsLookup = new Dictionary()
+ {
+ { ETerminalColor.Black, new TerminalColor(ETerminalColor.Black, false) },
+ { ETerminalColor.Red, new TerminalColor(ETerminalColor.Red, false) },
+ { ETerminalColor.Green, new TerminalColor(ETerminalColor.Green, false) },
+ { ETerminalColor.Yellow,new TerminalColor(ETerminalColor.Yellow, false) },
+ { ETerminalColor.Blue, new TerminalColor(ETerminalColor.Blue, false) },
+ { ETerminalColor.Magenta, new TerminalColor(ETerminalColor.Magenta, false) },
+ { ETerminalColor.Cyan, new TerminalColor(ETerminalColor.Cyan, false) },
+ { ETerminalColor.White, new TerminalColor(ETerminalColor.White, true) }
+ };
public override bool Equals(object obj)
{
@@ -60,8 +62,11 @@ public override bool Equals(object obj)
)
return false;
- return
- InternalBits == other.InternalBits;
+ return Bright == other.Bright &&
+ Standout == other.Standout &&
+ Underscore == other.Underscore &&
+ Blink == other.Blink &&
+ Reverse == other.Reverse;
}
public override int GetHashCode()
@@ -76,11 +81,11 @@ public ETerminalColor ForegroundColor
{
get
{
- return (ETerminalColor)(InternalBits & 0x7);
+ return TerminalColorsLookup.Single(x => x.Value == ForegroundRgb).Key;
}
set
{
- InternalBits = (ushort)((InternalBits & 0xFFF8) | (ushort)value);
+ ForegroundRgb = TerminalColorsLookup[value];
}
}
@@ -92,11 +97,11 @@ public ETerminalColor BackgroundColor
{
get
{
- return (ETerminalColor)((InternalBits >> 3) & 0x7);
+ return TerminalColorsLookup.Single(x => x.Value == BackgroundRgb).Key;
}
set
{
- InternalBits = (ushort)((InternalBits & 0xFFC7) | ((int)value << 3));
+ BackgroundRgb = TerminalColorsLookup[value];
}
}
@@ -106,126 +111,38 @@ public ETerminalColor BackgroundColor
///
/// This is an old naming system and should be udpated
///
- public bool Bright
- {
- get
- {
- return (InternalBits & BrightBit) == BrightBit;
- }
- set
- {
- if (value)
- InternalBits |= BrightBit;
- else
- InternalBits = (ushort)((InternalBits & ~BrightBit) & 0xFFFF);
- }
- }
+ public bool Bright { get; set; } = false;
///
/// Unclear what this is
///
/// TODO : Figure out what Standout text is
- public bool Standout
- {
- get
- {
- return (InternalBits & StandoutBit) == StandoutBit;
- }
- set
- {
- if (value)
- InternalBits |= StandoutBit;
- else
- InternalBits = (ushort)((InternalBits & ~StandoutBit) & 0xFFFF);
- }
- }
+ public bool Standout { get; set; } = false;
///
/// Sets the text as having a line beneath the character
///
- public bool Underscore
- {
- get
- {
- return (InternalBits & UnderscoreBit) == UnderscoreBit;
- }
- set
- {
- if (value)
- InternalBits |= UnderscoreBit;
- else
- InternalBits = (ushort)((InternalBits & ~UnderscoreBit) & 0xFFFF);
- }
- }
+ public bool Underscore { get; set; } = false;
///
/// Sets the blink attribute
///
- public bool Blink
- {
- get
- {
- return (InternalBits & BlinkBit) == BlinkBit;
- }
- set
- {
- if (value)
- InternalBits |= BlinkBit;
- else
- InternalBits = (ushort)((InternalBits & ~BlinkBit) & 0xFFFF);
- }
- }
+ public bool Blink { get; set; } = false;
///
/// Reverses the foreground and the background colors of the text
///
- public bool Reverse
- {
- get
- {
- return (InternalBits & ReverseBit) == ReverseBit;
- }
- set
- {
- if (value)
- InternalBits |= ReverseBit;
- else
- InternalBits = (ushort)((InternalBits & ~ReverseBit) & 0xFFFF);
- }
- }
+ public bool Reverse { get; set; } = false;
///
/// Specifies that the character should not be displayed.
///
- public bool Hidden
- {
- get
- {
- return (InternalBits & HiddenBit) == HiddenBit;
- }
- set
- {
- if (value)
- InternalBits |= HiddenBit;
- else
- InternalBits = (ushort)((InternalBits & ~HiddenBit) & 0xFFFF);
- }
- }
+ public bool Hidden { get; set; } = false;
///
/// Specifies that the character should not be erased on SEL and SED operations.
///
- public int Protected
- {
- get
- {
- return (InternalBits & ProtectionBits) >> 12;
- }
- set
- {
- InternalBits = (ushort)((InternalBits & ~ProtectionBits) | ((value & 0x3) << 12));
- }
- }
+ public int Protected { get; set; } = 0;
///
/// Returns a deep copy of the attribute
@@ -235,9 +152,15 @@ public TerminalAttribute Clone()
{
return new TerminalAttribute
{
- InternalBits = InternalBits,
ForegroundRgb = ForegroundRgb == null ? null : new TerminalColor(ForegroundRgb),
- BackgroundRgb = BackgroundRgb == null ? null : new TerminalColor(BackgroundRgb)
+ BackgroundRgb = BackgroundRgb == null ? null : new TerminalColor(BackgroundRgb),
+ Bright = Bright,
+ Standout = Standout,
+ Underscore = Underscore,
+ Blink = Blink,
+ Reverse = Reverse,
+ Hidden = Hidden,
+ Protected = Protected
};
}
@@ -251,9 +174,15 @@ public TerminalAttribute Inverse
{
return new TerminalAttribute
{
- InternalBits = (ushort)((InternalBits & 0xFFC0) | ((InternalBits & 0x0007) << 3) | ((InternalBits >> 3) & 0x0007)),
ForegroundRgb = BackgroundRgb == null ? null : new TerminalColor(BackgroundRgb),
BackgroundRgb = ForegroundRgb == null ? null : new TerminalColor(ForegroundRgb),
+ Bright = Bright,
+ Standout = Standout,
+ Underscore = Underscore,
+ Blink = Blink,
+ Reverse = Reverse,
+ Hidden = Hidden,
+ Protected = Protected
};
}
}
diff --git a/VtNetCore/VirtualTerminal/VirtualTerminalController.cs b/VtNetCore/VirtualTerminal/VirtualTerminalController.cs
index cd24780..29a2b68 100644
--- a/VtNetCore/VirtualTerminal/VirtualTerminalController.cs
+++ b/VtNetCore/VirtualTerminal/VirtualTerminalController.cs
@@ -44,6 +44,8 @@ public class VirtualTerminalController : IVirtualTerminalController
private EActiveBuffer ActiveBuffer { get; set; } = EActiveBuffer.Normal;
+ public bool IsActiveBufferNormal => ActiveBuffer == EActiveBuffer.Normal;
+
///
/// The logical top row of the view port. This translates relative to the buffer
///
@@ -304,6 +306,16 @@ public VirtualTerminalController()
///
public EventHandler SizeChanged;
+ ///
+ /// Emitted when a change to the characters on the terminal occurs
+ ///
+ public event Action OnCharacterChanged;
+
+ ///
+ /// Emitted when the buffer is changed
+ ///
+ public event Action OnScreenBufferChanged;
+
///
/// Enables storing of raw text for scripting tools
///
@@ -831,6 +843,8 @@ public void FullReset()
LastMousePosition.Set(-1, -1);
+ OnScreenBufferChanged?.Invoke();
+
ChangeCount++;
}
@@ -1977,6 +1991,8 @@ public void EnableNormalBuffer()
alternativeBufferTopRow = TopRow;
TopRow = normalBufferTopRow;
+ OnScreenBufferChanged?.Invoke();
+
ChangeCount++;
}
@@ -1993,6 +2009,8 @@ public void EnableAlternateBuffer()
normalBufferTopRow = TopRow;
TopRow = alternativeBufferTopRow;
+ OnScreenBufferChanged?.Invoke();
+
ChangeCount++;
}
@@ -2194,9 +2212,12 @@ public void SetLeftAndRightMargins(int left, int right)
SetCursorPosition(1, 1);
}
+ public bool InEraseState = false;
+
public void EraseLine(bool ignoreProtected = true)
{
LogController("EraseLine(ignoreProtected: " + ignoreProtected + ")");
+ InEraseState = true;
for (var i = 0; i < Columns; i++)
SetCharacter(i, CursorState.CurrentRow, ' ', CursorState.Attributes, ignoreProtected);
@@ -2205,12 +2226,14 @@ public void EraseLine(bool ignoreProtected = true)
while (line.Count > Columns)
line.RemoveAt(line.Count - 1);
+ InEraseState = false;
ChangeCount++;
}
public void EraseToEndOfLine(bool ignoreProtected=true)
{
LogController("EraseToEndOfLine(ignoreProtected: " + ignoreProtected + ")");
+ InEraseState = true;
for (var i = CursorState.CurrentColumn; i < Columns; i++)
SetCharacter(i, CursorState.CurrentRow, ' ', CursorState.Attributes, ignoreProtected);
@@ -2231,12 +2254,14 @@ public void EraseToEndOfLine(bool ignoreProtected=true)
);
}
+ InEraseState = false;
ChangeCount++;
}
public void EraseToStartOfLine(bool ignoreProtected = true)
{
LogController("EraseToStartOfLine(ignoreProtected: " + ignoreProtected + ")");
+ InEraseState = true;
for (var i = 0; i < Columns && i <= CursorState.CurrentColumn; i++)
SetCharacter(i, CursorState.CurrentRow, ' ', CursorState.Attributes, ignoreProtected);
@@ -2245,6 +2270,7 @@ public void EraseToStartOfLine(bool ignoreProtected = true)
while (line.Count > Columns)
line.RemoveAt(line.Count - 1);
+ InEraseState = false;
ChangeCount++;
}
@@ -2252,6 +2278,7 @@ public void EraseBelow(bool ignoreProtected = true)
{
// TODO : Optimize
LogController("EraseBelow(ignoreProtected: " + ignoreProtected + ")");
+ InEraseState = true;
for (var y = CursorState.CurrentRow + 1; y < VisibleRows; y++)
{
@@ -2266,12 +2293,15 @@ public void EraseBelow(bool ignoreProtected = true)
for (var x = CursorState.CurrentColumn; x < VisibleColumns; x++)
SetCharacter(x, CursorState.CurrentRow, ' ', CursorState.Attributes, ignoreProtected);
+
+ InEraseState = false;
}
public void EraseAbove(bool ignoreProtected = true)
{
// TODO : Optimize
LogController("EraseAbove(ignoreProtected: " + ignoreProtected + ")");
+ InEraseState = true;
for (var y = CursorState.CurrentRow - 1; y >= 0; y--)
{
@@ -2285,12 +2315,15 @@ public void EraseAbove(bool ignoreProtected = true)
for (var x = 0; x <= CursorState.CurrentColumn; x++)
SetCharacter(x, CursorState.CurrentRow, ' ', CursorState.Attributes, ignoreProtected);
+
+ InEraseState = false;
}
public void DeleteLines(int count)
{
// TODO : Verify it works with scroll range
LogController("DeleteLines(count:" + count.ToString() + ")");
+ InEraseState = true;
if (
CursorState.CurrentRow < ScrollTop ||
@@ -2338,6 +2371,7 @@ public void DeleteLines(int count)
}
}
+ InEraseState = false;
ChangeCount++;
}
@@ -2806,6 +2840,8 @@ private TerminalCharacter SetCharacter(int currentColumn, int currentRow, char c
character.CombiningCharacters = "";
}
+ OnCharacterChanged(currentRow, currentColumn, attribute, ch);
+
return character;
}