Fix merge errors.

This commit is contained in:
BDisp
2024-11-10 16:38:21 +00:00
parent 5e2b611c91
commit 88f4045381
7 changed files with 117 additions and 324 deletions

View File

@@ -30,10 +30,6 @@ public abstract class ConsoleDriver
/// <returns></returns>
public virtual string GetVersionInfo () { return GetType ().Name; }
/// <summary>Suspends the application (e.g. on Linux via SIGTSTP) and upon resume, resets the console driver.</summary>
/// <remarks>This is only implemented in <see cref="CursesDriver"/>.</remarks>
public abstract void Suspend ();
#region ANSI Esc Sequence Handling
// QUESTION: Should this be virtual with a default implementation that does the common stuff?
@@ -94,9 +90,6 @@ public abstract class ConsoleDriver
}
}
/// <summary>Updates the screen to reflect all the changes that have been done to the display buffer</summary>
public abstract void Refresh ();
/// <summary>
/// Gets the column last set by <see cref="Move"/>. <see cref="Col"/> and <see cref="Row"/> are used by
/// <see cref="AddRune(Rune)"/> and <see cref="AddStr"/> to determine where to add content.
@@ -181,28 +174,6 @@ public abstract class ConsoleDriver
/// <summary>The topmost row in the terminal.</summary>
internal virtual int Top { get; set; } = 0;
private Rectangle _clip;
/// <summary>
/// Gets or sets the clip rectangle that <see cref="AddRune(Rune)"/> and <see cref="AddStr(string)"/> are subject
/// to.
/// </summary>
/// <value>The rectangle describing the of <see cref="Clip"/> region.</value>
public Rectangle Clip
{
get => _clip;
set
{
if (_clip == value)
{
return;
}
// Don't ever let Clip be bigger than Screen
_clip = Rectangle.Intersect (Screen, value);
}
}
/// <summary>Adds the specified rune to the display at the current cursor position.</summary>
/// <remarks>
/// <para>
@@ -420,19 +391,23 @@ public abstract class ConsoleDriver
/// </remarks>
/// <param name="rect">The Screen-relative rectangle.</param>
/// <param name="rune">The Rune used to fill the rectangle</param>
public void FillRect (Rectangle rect, Rune rune = default)
internal void FillRect (Rectangle rect, Rune rune = default)
{
rect = Rectangle.Intersect (rect, Clip);
// BUGBUG: This should be a method on Region
rect = Rectangle.Intersect (rect, Clip?.GetBounds () ?? Screen);
lock (Contents!)
{
for (int r = rect.Y; r < rect.Y + rect.Height; r++)
{
for (int c = rect.X; c < rect.X + rect.Width; c++)
{
Contents [r, c] = new ()
if (!IsValidLocation (rune, c, r))
{
Rune = rune != default (Rune) ? rune : (Rune)' ',
continue;
}
Contents [r, c] = new Cell
{
Rune = (rune != default ? rune : (Rune)' '),
Attribute = CurrentAttribute, IsDirty = true
};
_dirtyLines! [r] = true;
@@ -498,41 +473,6 @@ public abstract class ConsoleDriver
}
}
/// <summary>Determines if the terminal cursor should be visible or not and sets it accordingly.</summary>
/// <returns><see langword="true"/> upon success</returns>
public abstract bool EnsureCursorVisibility ();
/// <summary>Fills the specified rectangle with the specified rune, using <see cref="CurrentAttribute"/></summary>
/// <remarks>
/// The value of <see cref="Clip"/> is honored. Any parts of the rectangle not in the clip will not be drawn.
/// </remarks>
/// <param name="rect">The Screen-relative rectangle.</param>
/// <param name="rune">The Rune used to fill the rectangle</param>
internal void FillRect (Rectangle rect, Rune rune = default)
{
// BUGBUG: This should be a method on Region
rect = Rectangle.Intersect (rect, Clip?.GetBounds () ?? Screen);
lock (Contents!)
{
for (int r = rect.Y; r < rect.Y + rect.Height; r++)
{
for (int c = rect.X; c < rect.X + rect.Width; c++)
{
if (!IsValidLocation (rune, c, r))
{
continue;
}
Contents [r, c] = new Cell
{
Rune = (rune != default ? rune : (Rune)' '),
Attribute = CurrentAttribute, IsDirty = true
};
_dirtyLines! [r] = true;
}
}
}
}
/// <summary>
/// Fills the specified rectangle with the specified <see langword="char"/>. This method is a convenience method
/// that calls <see cref="FillRect(Rectangle, Rune)"/>.
@@ -554,17 +494,6 @@ public abstract class ConsoleDriver
/// <returns><see langword="true"/> upon success</returns>
public abstract bool GetCursorVisibility (out CursorVisibility visibility);
/// <summary>Sets the position of the terminal cursor to <see cref="Col"/> and <see cref="Row"/>.</summary>
public abstract void UpdateCursor ();
/// <summary>Tests if the specified rune is supported by the driver.</summary>
/// <param name="rune"></param>
/// <returns>
/// <see langword="true"/> if the rune can be properly presented; <see langword="false"/> if the driver does not
/// support displaying this rune.
/// </returns>
public virtual bool IsRuneSupported (Rune rune) { return Rune.IsValid (rune.Value); }
/// <summary>Tests whether the specified coordinate are valid for drawing the specified Rune.</summary>
/// <param name="rune">Used to determine if one or two columns are required.</param>
/// <param name="col">The column.</param>
@@ -586,27 +515,6 @@ public abstract class ConsoleDriver
}
}
// TODO: Make internal once Menu is upgraded
/// <summary>
/// Updates <see cref="Col"/> and <see cref="Row"/> to the specified column and row in <see cref="Contents"/>.
/// Used by <see cref="AddRune(Rune)"/> and <see cref="AddStr"/> to determine where to add content.
/// </summary>
/// <remarks>
/// <para>This does not move the cursor on the screen, it only updates the internal state of the driver.</para>
/// <para>
/// If <paramref name="col"/> or <paramref name="row"/> are negative or beyond <see cref="Cols"/> and
/// <see cref="Rows"/>, the method still sets those properties.
/// </para>
/// </remarks>
/// <param name="col">Column to move to.</param>
/// <param name="row">Row to move to.</param>
public virtual void Move (int col, int row)
{
//Debug.Assert (col >= 0 && row >= 0 && col < Contents.GetLength(1) && row < Contents.GetLength(0));
Col = col;
Row = row;
}
/// <summary>Called when the terminal size changes. Fires the <see cref="SizeChanged"/> event.</summary>
/// <param name="args"></param>
internal void OnSizeChanged (SizeChangedEventArgs args) { SizeChanged?.Invoke (this, args); }
@@ -630,6 +538,9 @@ public abstract class ConsoleDriver
/// <returns><see langword="true"/> upon success</returns>
public abstract bool SetCursorVisibility (CursorVisibility visibility);
/// <summary>The event fired when the terminal is resized.</summary>
public event EventHandler<SizeChangedEventArgs>? SizeChanged;
#endregion Cursor Handling
/// <summary>Suspends the application (e.g. on Linux via SIGTSTP) and upon resume, resets the console driver.</summary>

View File

@@ -70,22 +70,22 @@ internal class CursesDriver : ConsoleDriver
if (consoleKey == ConsoleKey.Packet)
{
var mod = new ConsoleModifiers ();
//var mod = new ConsoleModifiers ();
if (shift)
{
mod |= ConsoleModifiers.Shift;
}
//if (shift)
//{
// mod |= ConsoleModifiers.Shift;
//}
if (alt)
{
mod |= ConsoleModifiers.Alt;
}
//if (alt)
//{
// mod |= ConsoleModifiers.Alt;
//}
if (control)
{
mod |= ConsoleModifiers.Control;
}
//if (control)
//{
// mod |= ConsoleModifiers.Control;
//}
var cKeyInfo = new ConsoleKeyInfo (keyChar, consoleKey, shift, alt, control);
cKeyInfo = ConsoleKeyMapping.DecodeVKPacketToKConsoleKeyInfo (cKeyInfo);
@@ -96,8 +96,8 @@ internal class CursesDriver : ConsoleDriver
key = (KeyCode)keyChar;
}
OnKeyDown (new Key (key));
OnKeyUp (new Key (key));
OnKeyDown (new (key));
OnKeyUp (new (key));
//OnKeyPressed (new KeyEventArgsEventArgs (key));
}
@@ -118,10 +118,10 @@ internal class CursesDriver : ConsoleDriver
if (visibility != CursorVisibility.Invisible)
{
Console.Out.Write (
EscSeqUtils.CSI_SetCursorStyle (
(EscSeqUtils.DECSCUSR_Style)(((int)visibility >> 24)
& 0xFF)
)
AnsiEscapeSequenceRequestUtils.CSI_SetCursorStyle (
(AnsiEscapeSequenceRequestUtils.DECSCUSR_Style)(((int)visibility >> 24)
& 0xFF)
)
);
}
@@ -134,7 +134,7 @@ internal class CursesDriver : ConsoleDriver
{
if (!RunningUnitTests)
{
Console.Out.Write (EscSeqUtils.CSI_EnableMouseEvents);
Console.Out.Write (AnsiEscapeSequenceRequestUtils.CSI_EnableMouseEvents);
}
}
@@ -142,7 +142,7 @@ internal class CursesDriver : ConsoleDriver
{
if (!RunningUnitTests)
{
Console.Out.Write (EscSeqUtils.CSI_DisableMouseEvents);
Console.Out.Write (AnsiEscapeSequenceRequestUtils.CSI_DisableMouseEvents);
}
}
@@ -170,14 +170,18 @@ internal class CursesDriver : ConsoleDriver
if (!RunningUnitTests && Col >= 0 && Col < Cols && Row >= 0 && Row < Rows)
{
Curses.move (Row, Col);
if (Force16Colors)
{
Curses.move (Row, Col);
Curses.raw ();
Curses.noecho ();
Curses.refresh ();
}
else
{
_mainLoopDriver?.WriteRaw (AnsiEscapeSequenceRequestUtils.CSI_SetCursorPosition (Row + 1, Col + 1));
}
}
}
@@ -399,8 +403,6 @@ internal class CursesDriver : ConsoleDriver
return updated;
}
#endregion Screen and Contents
#region Color Handling
public override bool SupportsTrueColor => true;
@@ -531,8 +533,6 @@ internal class CursesDriver : ConsoleDriver
#endregion
#region Cursor Support
private CursorVisibility? _currentCursorVisibility;
private CursorVisibility? _initialCursorVisibility;
@@ -568,118 +568,6 @@ internal class CursesDriver : ConsoleDriver
return true;
}
/// <inheritdoc/>
public override bool SetCursorVisibility (CursorVisibility visibility)
{
if (_initialCursorVisibility.HasValue == false)
{
return false;
}
if (!RunningUnitTests)
{
Curses.curs_set (((int)visibility >> 16) & 0x000000FF);
}
if (visibility != CursorVisibility.Invisible)
{
Console.Out.Write (
AnsiEscapeSequenceRequestUtils.CSI_SetCursorStyle (
(AnsiEscapeSequenceRequestUtils.DECSCUSR_Style)(((int)visibility >> 24)
& 0xFF)
)
);
}
_currentCursorVisibility = visibility;
return true;
}
public override void UpdateCursor ()
{
EnsureCursorVisibility ();
if (!RunningUnitTests && Col >= 0 && Col < Cols && Row >= 0 && Row < Rows)
{
if (Force16Colors)
{
Curses.move (Row, Col);
Curses.raw ();
Curses.noecho ();
Curses.refresh ();
}
else
{
_mainLoopDriver?.WriteRaw (AnsiEscapeSequenceRequestUtils.CSI_SetCursorPosition (Row + 1, Col + 1));
}
}
}
#endregion Cursor Support
#region Keyboard Support
public override void SendKeys (char keyChar, ConsoleKey consoleKey, bool shift, bool alt, bool control)
{
KeyCode key;
if (consoleKey == ConsoleKey.Packet)
{
//var mod = new ConsoleModifiers ();
//if (shift)
//{
// mod |= ConsoleModifiers.Shift;
//}
//if (alt)
//{
// mod |= ConsoleModifiers.Alt;
//}
//if (control)
//{
// mod |= ConsoleModifiers.Control;
//}
var cKeyInfo = new ConsoleKeyInfo (keyChar, consoleKey, shift, alt, control);
cKeyInfo = ConsoleKeyMapping.DecodeVKPacketToKConsoleKeyInfo (cKeyInfo);
key = ConsoleKeyMapping.MapConsoleKeyInfoToKeyCode (cKeyInfo);
}
else
{
key = (KeyCode)keyChar;
}
OnKeyDown (new (key));
OnKeyUp (new (key));
//OnKeyPressed (new KeyEventArgsEventArgs (key));
}
#endregion Keyboard Support
#region Mouse Support
public void StartReportingMouseMoves ()
{
if (!RunningUnitTests)
{
Console.Out.Write (AnsiEscapeSequenceRequestUtils.CSI_EnableMouseEvents);
}
}
public void StopReportingMouseMoves ()
{
if (!RunningUnitTests)
{
Console.Out.Write (AnsiEscapeSequenceRequestUtils.CSI_DisableMouseEvents);
}
}
#endregion Mouse Support
private bool SetCursorPosition (int col, int row)
{
// + 1 is needed because non-Windows is based on 1 instead of 0 and
@@ -875,8 +763,6 @@ internal class CursesDriver : ConsoleDriver
return false;
}
#region Low-Level Unix Stuff
private readonly ManualResetEventSlim _waitAnsiResponse = new (false);
private CancellationTokenSource? _ansiResponseTokenSource;
@@ -1028,6 +914,4 @@ internal static class Platform
[DllImport ("libc")]
private static extern int uname (nint buf);
}
#endregion Low-Level Unix Stuff
}

View File

@@ -14,12 +14,6 @@ internal class NetDriver : ConsoleDriver
public bool IsWinPlatform { get; private set; }
public NetWinVTConsole? NetWinConsole { get; private set; }
public override void Refresh ()
{
UpdateScreen ();
UpdateCursor ();
}
public override void Suspend ()
{
if (Environment.OSVersion.Platform != PlatformID.Unix)
@@ -52,17 +46,16 @@ internal class NetDriver : ConsoleDriver
StartReportingMouseMoves ();
}
#region Screen and Contents
public override void UpdateScreen ()
public override bool UpdateScreen ()
{
bool updated = false;
if (RunningUnitTests
|| _winSizeChanging
|| Console.WindowHeight < 1
|| Contents?.Length != Rows * Cols
|| Rows != Console.WindowHeight)
{
return;
return updated;
}
var top = 0;
@@ -80,7 +73,7 @@ internal class NetDriver : ConsoleDriver
{
if (Console.WindowHeight < 1)
{
return;
return updated;
}
if (!_dirtyLines! [row])
@@ -90,9 +83,10 @@ internal class NetDriver : ConsoleDriver
if (!SetCursorPosition (0, row))
{
return;
return updated;
}
updated = true;
_dirtyLines [row] = false;
output.Clear ();
@@ -138,30 +132,33 @@ internal class NetDriver : ConsoleDriver
{
output.Append (
AnsiEscapeSequenceRequestUtils.CSI_SetGraphicsRendition (
MapColors (
(ConsoleColor)attr.Background.GetClosestNamedColor16 (),
false
),
MapColors ((ConsoleColor)attr.Foreground.GetClosestNamedColor16 ())
)
MapColors (
(ConsoleColor)attr.Background
.GetClosestNamedColor16 (),
false
),
MapColors (
(ConsoleColor)attr.Foreground
.GetClosestNamedColor16 ())
)
);
}
else
{
output.Append (
AnsiEscapeSequenceRequestUtils.CSI_SetForegroundColorRGB (
attr.Foreground.R,
attr.Foreground.G,
attr.Foreground.B
)
attr.Foreground.R,
attr.Foreground.G,
attr.Foreground.B
)
);
output.Append (
AnsiEscapeSequenceRequestUtils.CSI_SetBackgroundColorRGB (
attr.Background.R,
attr.Background.G,
attr.Background.B
)
attr.Background.R,
attr.Background.G,
attr.Background.B
)
);
}
}
@@ -199,7 +196,7 @@ internal class NetDriver : ConsoleDriver
Console.Write (output);
}
foreach (SixelToRender s in Application.Sixel)
foreach (var s in Application.Sixel)
{
if (!string.IsNullOrWhiteSpace (s.SixelData))
{
@@ -221,9 +218,9 @@ internal class NetDriver : ConsoleDriver
lastCol += outputWidth;
outputWidth = 0;
}
}
#endregion Screen and Contents
return updated;
}
#region Init/End/MainLoop
@@ -821,7 +818,7 @@ internal class NetDriver : ConsoleDriver
}
}
private void ResizeScreen ()
public virtual void ResizeScreen ()
{
// Not supported on Unix.
if (IsWinPlatform)
@@ -846,18 +843,17 @@ internal class NetDriver : ConsoleDriver
}
#pragma warning restore CA1416
}
// INTENT: Why are these eating the exceptions?
// Comments would be good here.
catch (IOException)
{
// CONCURRENCY: Unsynchronized access to Clip is not safe.
Clip = new (0, 0, Cols, Rows);
Clip = new (Screen);
}
catch (ArgumentOutOfRangeException)
{
// CONCURRENCY: Unsynchronized access to Clip is not safe.
Clip = new (0, 0, Cols, Rows);
Clip = new (Screen);
}
}
else
@@ -866,7 +862,7 @@ internal class NetDriver : ConsoleDriver
}
// CONCURRENCY: Unsynchronized access to Clip is not safe.
Clip = new (0, 0, Cols, Rows);
Clip = new (Screen);
}
#endregion Low-Level DotNet tuff

View File

@@ -29,19 +29,20 @@ internal class NetMainLoop : IMainLoopDriver
{
ArgumentNullException.ThrowIfNull (consoleDriver);
_netEvents = new (consoleDriver);
if (!ConsoleDriver.RunningUnitTests)
{
_netEvents = new (consoleDriver);
}
}
void IMainLoopDriver.Setup (MainLoop mainLoop)
{
_mainLoop = mainLoop;
if (ConsoleDriver.RunningUnitTests)
if (!ConsoleDriver.RunningUnitTests)
{
return;
Task.Run (NetInputHandler, _inputHandlerTokenSource.Token);
}
Task.Run (NetInputHandler, _inputHandlerTokenSource.Token);
}
void IMainLoopDriver.Wakeup () { _eventReady.Set (); }

View File

@@ -517,33 +517,33 @@ internal class WindowsConsole
_inputReadyCancellationTokenSource = null;
}
//internal Size GetConsoleBufferWindow (out Point position)
//{
// if (_screenBuffer == nint.Zero)
// {
// position = Point.Empty;
internal Size GetConsoleBufferWindow (out Point position)
{
if (_outputHandle == nint.Zero)
{
position = Point.Empty;
// return Size.Empty;
// }
return Size.Empty;
}
// var csbi = new CONSOLE_SCREEN_BUFFER_INFOEX ();
// csbi.cbSize = (uint)Marshal.SizeOf (csbi);
var csbi = new CONSOLE_SCREEN_BUFFER_INFOEX ();
csbi.cbSize = (uint)Marshal.SizeOf (csbi);
// if (!GetConsoleScreenBufferInfoEx (_screenBuffer, ref csbi))
// {
// //throw new System.ComponentModel.Win32Exception (Marshal.GetLastWin32Error ());
// position = Point.Empty;
if (!GetConsoleScreenBufferInfoEx (_outputHandle, ref csbi))
{
//throw new System.ComponentModel.Win32Exception (Marshal.GetLastWin32Error ());
position = Point.Empty;
// return Size.Empty;
// }
return Size.Empty;
}
// Size sz = new (
// csbi.srWindow.Right - csbi.srWindow.Left + 1,
// csbi.srWindow.Bottom - csbi.srWindow.Top + 1);
// position = new (csbi.srWindow.Left, csbi.srWindow.Top);
Size sz = new (
csbi.srWindow.Right - csbi.srWindow.Left + 1,
csbi.srWindow.Bottom - csbi.srWindow.Top + 1);
position = new (csbi.srWindow.Left, csbi.srWindow.Top);
// return sz;
//}
return sz;
}
internal Size GetConsoleOutputWindow (out Point position)
{

View File

@@ -117,16 +117,6 @@ internal class WindowsDriver : ConsoleDriver
public override bool IsRuneSupported (Rune rune) { return base.IsRuneSupported (rune) && rune.IsBmp; }
public override void Refresh ()
{
if (!RunningUnitTests)
{
UpdateScreen ();
//WinConsole?.SetInitialCursorVisibility ();
UpdateCursor ();
}
}
public override void SendKeys (char keyChar, ConsoleKey key, bool shift, bool alt, bool control)
{
var input = new WindowsConsole.InputRecord
@@ -289,6 +279,11 @@ internal class WindowsDriver : ConsoleDriver
public override void UpdateCursor ()
{
if (RunningUnitTests)
{
return;
}
if (Col < 0 || Row < 0 || Col >= Cols || Row >= Rows)
{
GetCursorVisibility (out CursorVisibility cursorVisibility);
@@ -382,13 +377,14 @@ internal class WindowsDriver : ConsoleDriver
#endregion Cursor Handling
public override void UpdateScreen ()
public override bool UpdateScreen ()
{
Size windowSize = WinConsole?.GetConsoleOutputWindow (out Point _) ?? new Size (Cols, Rows);
bool updated = false;
Size windowSize = WinConsole?.GetConsoleBufferWindow (out Point _) ?? new Size (Cols, Rows);
if (!windowSize.IsEmpty && (windowSize.Width != Cols || windowSize.Height != Rows))
{
return;
return updated;
}
var bufferCoords = new WindowsConsole.Coord
@@ -405,6 +401,7 @@ internal class WindowsDriver : ConsoleDriver
}
_dirtyLines [row] = false;
updated = true;
for (var col = 0; col < Cols; col++)
{
@@ -463,6 +460,8 @@ internal class WindowsDriver : ConsoleDriver
}
WindowsConsole.SmallRect.MakeEmpty (ref _damageRegion);
return updated;
}
internal override void End ()
@@ -502,6 +501,7 @@ internal class WindowsDriver : ConsoleDriver
Size winSize = WinConsole.GetConsoleOutputWindow (out Point _);
Cols = winSize.Width;
Rows = winSize.Height;
OnSizeChanged (new SizeChangedEventArgs (new (Cols, Rows)));
}
WindowsConsole.SmallRect.MakeEmpty (ref _damageRegion);
@@ -524,7 +524,7 @@ internal class WindowsDriver : ConsoleDriver
_outputBuffer = new WindowsConsole.ExtendedCharInfo [Rows * Cols];
// CONCURRENCY: Unsynchronized access to Clip is not safe.
Clip = new (0, 0, Cols, Rows);
Clip = new (Screen);
_damageRegion = new WindowsConsole.SmallRect
{
@@ -613,11 +613,12 @@ internal class WindowsDriver : ConsoleDriver
Cols = inputEvent.WindowBufferSizeEvent._size.X;
Rows = inputEvent.WindowBufferSizeEvent._size.Y;
Application.Screen = new (0, 0, Cols, Rows);
ResizeScreen ();
ClearContents ();
Application.Top?.SetNeedsLayout ();
Application.Refresh ();
Application.LayoutAndDraw ();
break;
#endif
@@ -961,7 +962,7 @@ internal class WindowsDriver : ConsoleDriver
{
_outputBuffer = new WindowsConsole.ExtendedCharInfo [Rows * Cols];
// CONCURRENCY: Unsynchronized access to Clip is not safe.
Clip = new (0, 0, Cols, Rows);
Clip = new (Screen);
_damageRegion = new WindowsConsole.SmallRect
{

View File

@@ -414,16 +414,16 @@ public sealed class AnsiEscapeSequenceRequests : Scenario
// _graphView.ScrollOffset = new PointF(,0);
if (_sentSeries.Points.Count > 0 || _answeredSeries.Points.Count > 0)
{
_graphView.SetNeedsDisplay ();
_graphView.SetNeedsDraw ();
}
}
private void UpdateResponses ()
{
_lblSummary.Text = GetSummary ();
_lblSummary.SetNeedsDisplay ();
_lblSummary.SetNeedsDraw ();
_lblErrorSummary.Text = GetSummaryErrors ();
_lblErrorSummary.SetNeedsDisplay ();
_lblErrorSummary.SetNeedsDraw ();
}
}