diff --git a/TrueColorConsole/VTConsole.cs b/TrueColorConsole/VTConsole.cs index 75ff896..415f0eb 100644 --- a/TrueColorConsole/VTConsole.cs +++ b/TrueColorConsole/VTConsole.cs @@ -14,20 +14,37 @@ public static partial class VTConsole { #region Interop - private const uint StdOutputHandle = unchecked((uint) -11); - private const uint StdInputHandle = unchecked((uint) -10); - private static readonly IntPtr InvalidHandleValue = new IntPtr(-1); - - [DllImport("kernel32.dll", SetLastError = true)] - private static extern IntPtr GetStdHandle(uint nStdHandle); - - [DllImport("kernel32.dll", SetLastError = true)] - [return: MarshalAs(UnmanagedType.Bool)] - private static extern bool GetConsoleMode(IntPtr hConsoleHandle, out uint lpMode); + private static class NativeMethods + { + public const uint StdOutputHandle = unchecked((uint) -11); + public const uint StdInputHandle = unchecked((uint) -10); + public static readonly IntPtr InvalidHandleValue = new IntPtr(-1); + + [DllImport("kernel32.dll", SetLastError = true)] + public static extern IntPtr GetStdHandle(uint nStdHandle); + + [DllImport("kernel32.dll", SetLastError = true)] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool GetConsoleMode(IntPtr hConsoleHandle, out uint lpMode); + + [DllImport("kernel32.dll", SetLastError = true)] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool SetConsoleMode(IntPtr hConsoleHandle, uint dwMode); + + [DllImport("kernel32.dll", SetLastError = true)] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool WriteConsole( + IntPtr hConsoleOutput, + [MarshalAs(UnmanagedType.LPArray)] byte[] lpBuffer, + int lpNumberOfCharsToWrite, + out int lpNumberOfCharsToWritten, + IntPtr lpReserved + ); + } private static bool GetConsoleMode(IntPtr hConsoleHandle, out ConsoleModeOutput mode) { - if (!GetConsoleMode(hConsoleHandle, out uint lpMode)) + if (!NativeMethods.GetConsoleMode(hConsoleHandle, out uint lpMode)) { mode = 0; return false; @@ -39,7 +56,7 @@ private static bool GetConsoleMode(IntPtr hConsoleHandle, out ConsoleModeOutput private static bool GetConsoleMode(IntPtr hConsoleHandle, out ConsoleModeInput mode) { - if (!GetConsoleMode(hConsoleHandle, out uint lpMode)) + if (!NativeMethods.GetConsoleMode(hConsoleHandle, out uint lpMode)) { mode = 0; return false; @@ -49,30 +66,16 @@ private static bool GetConsoleMode(IntPtr hConsoleHandle, out ConsoleModeInput m return true; } - [DllImport("kernel32.dll", SetLastError = true)] - [return: MarshalAs(UnmanagedType.Bool)] - private static extern bool SetConsoleMode(IntPtr hConsoleHandle, uint dwMode); - - [DllImport("kernel32.dll", SetLastError = true)] - [return: MarshalAs(UnmanagedType.Bool)] - private static extern bool WriteConsole( - IntPtr hConsoleOutput, - [MarshalAs(UnmanagedType.LPArray)] byte[] lpBuffer, - int lpNumberOfCharsToWrite, - out int lpNumberOfCharsToWritten, - IntPtr lpReserved - ); - private static bool GetStdIn(out IntPtr handle) { - handle = GetStdHandle(StdInputHandle); - return handle != InvalidHandleValue; + handle = NativeMethods.GetStdHandle(NativeMethods.StdInputHandle); + return handle != NativeMethods.InvalidHandleValue; } private static bool GetStdOut(out IntPtr handle) { - handle = GetStdHandle(StdOutputHandle); - return handle != InvalidHandleValue; + handle = NativeMethods.GetStdHandle(NativeMethods.StdOutputHandle); + return handle != NativeMethods.InvalidHandleValue; } #endregion @@ -91,12 +94,24 @@ private static bool GetStdOut(out IntPtr handle) private static ConsoleModeInput _inLast; private static IntPtr _outHandle; private static ConsoleModeOutput _outLast; + private static bool _isEnabled; + + private static readonly bool IsWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows); /// /// Gets if virtual terminal features are enabled. /// [PublicAPI] - public static bool IsEnabled { get; private set; } + public static bool IsEnabled + { + get + { + if (IsWindows) + return _isEnabled; + return true; + } + private set => _isEnabled = value; + } /// /// Gets if virtual terminal features are supported (see Remarks). @@ -147,7 +162,7 @@ bool EnableInput() var mode = _inLast | ConsoleModeInput.EnableVirtualTerminalInput; - return SetConsoleMode(StdIn, (uint) mode); + return NativeMethods.SetConsoleMode(StdIn, (uint) mode); } bool EnableOutput() @@ -163,12 +178,12 @@ bool EnableOutput() if (disableNewLineAutoReturn) mode |= ConsoleModeOutput.DisableNewlineAutoReturn; - if (SetConsoleMode(StdOut, (uint) mode)) + if (NativeMethods.SetConsoleMode(StdOut, (uint) mode)) return true; mode = _outLast | ConsoleModeOutput.EnableVirtualTerminalProcessing; - return SetConsoleMode(StdOut, (uint) mode); + return NativeMethods.SetConsoleMode(StdOut, (uint) mode); } IsEnabled = EnableInput() && EnableOutput(); @@ -185,17 +200,19 @@ bool EnableOutput() [PublicAPI] public static bool Disable() { + if (!IsWindows) + return true; if (!IsEnabled) return false; bool DisableInput() { - return GetStdIn(out var handle) && SetConsoleMode(handle, (uint) _inLast); + return GetStdIn(out var handle) && NativeMethods.SetConsoleMode(handle, (uint) _inLast); } bool DisableOutput() { - return GetStdOut(out var handle) && SetConsoleMode(handle, (uint) _outLast); + return GetStdOut(out var handle) && NativeMethods.SetConsoleMode(handle, (uint) _outLast); } IsEnabled = !(DisableInput() && DisableOutput()); @@ -284,7 +301,12 @@ public static void SetFormat(params VTFormat[] formats) [PublicAPI] public static int WriteFast(byte[] buffer) { - WriteConsole(StdOut, buffer, buffer.Length, out var written, IntPtr.Zero); + if (!IsWindows) + { + Console.Write(Console.OutputEncoding.GetString(buffer)); + return buffer.Length; + } + NativeMethods.WriteConsole(StdOut, buffer, buffer.Length, out var written, IntPtr.Zero); return written; } diff --git a/TrueColorConsoleApp/Program.cs b/TrueColorConsoleApp/Program.cs index e9f78bc..e0b1607 100644 --- a/TrueColorConsoleApp/Program.cs +++ b/TrueColorConsoleApp/Program.cs @@ -1,5 +1,6 @@ using System; using System.Drawing; +using System.Runtime.InteropServices; using System.Text; using System.Threading; using TrueColorConsole; @@ -75,23 +76,31 @@ private static void Example2() private static void Example3() { var plasma = new Plasma(256, 256); - var width = 80; - var height = 40; - - Console.SetWindowSize(width, height); - Console.SetBufferSize(width, height); - Console.SetWindowSize(width, height); // removes bars Console.Title = "Plasma !"; Console.CursorVisible = false; + var width = Console.WindowWidth; + var height = Console.WindowHeight; var builder = new StringBuilder(width * height * 22); + var resetEvent = new AutoResetEvent(true); + using(new Timer(x =>{resetEvent.Set();}, null, TimeSpan.Zero, TimeSpan.FromMilliseconds(1.0/20*1000))) for (var frame = 0; ; frame++) { + if (width != Console.WindowWidth || height != Console.WindowHeight) + { + width = Console.WindowWidth; + height = Console.WindowHeight; + Console.WriteLine(); + builder = new StringBuilder(width * height * 22); + } + else + { + builder.Clear(); + } plasma.PlasmaFrame(frame); - builder.Clear(); - Thread.Sleep((int)(1.0 / 20 * 1000)); + resetEvent.WaitOne(); for (var i = 0; i < width * height; i++) {