|
@@ -18,6 +18,7 @@ namespace Terminal.Gui {
|
|
|
public const int STD_ERROR_HANDLE = -12;
|
|
|
|
|
|
internal IntPtr InputHandle, OutputHandle;
|
|
|
+ IntPtr screenBuffer;
|
|
|
readonly uint originalConsoleMode;
|
|
|
CursorVisibility? initialCursorVisibility = null;
|
|
|
CursorVisibility? currentCursorVisibility = null;
|
|
@@ -39,47 +40,47 @@ namespace Terminal.Gui {
|
|
|
|
|
|
public bool WriteToConsole (Size size, CharInfo [] charInfoBuffer, Coord coords, SmallRect window)
|
|
|
{
|
|
|
- //if (OutputHandle == IntPtr.Zero) {
|
|
|
- // ReadFromConsoleOutput (size, coords, ref window);
|
|
|
- //}
|
|
|
+ if (!IsWindowsTerminal && screenBuffer == IntPtr.Zero) {
|
|
|
+ ReadFromConsoleOutput (size, coords, ref window);
|
|
|
+ }
|
|
|
|
|
|
- return WriteConsoleOutput (OutputHandle, charInfoBuffer, coords, new Coord () { X = window.Left, Y = window.Top }, ref window);
|
|
|
- }
|
|
|
+ if (!initialCursorVisibility.HasValue && GetCursorVisibility (out CursorVisibility visibility)) {
|
|
|
+ initialCursorVisibility = visibility;
|
|
|
+ }
|
|
|
|
|
|
- //public void ReadFromConsoleOutput (Size size, Coord coords, ref SmallRect window)
|
|
|
- //{
|
|
|
- // OutputHandle = CreateConsoleScreenBuffer (
|
|
|
- // DesiredAccess.GenericRead | DesiredAccess.GenericWrite,
|
|
|
- // ShareMode.FileShareRead | ShareMode.FileShareWrite,
|
|
|
- // IntPtr.Zero,
|
|
|
- // 1,
|
|
|
- // IntPtr.Zero
|
|
|
- // );
|
|
|
- // if (ScreenBuffer == INVALID_HANDLE_VALUE) {
|
|
|
- // var err = Marshal.GetLastWin32Error ();
|
|
|
+ return WriteConsoleOutput (IsWindowsTerminal ? OutputHandle : screenBuffer, charInfoBuffer, coords, new Coord () { X = window.Left, Y = window.Top }, ref window);
|
|
|
+ }
|
|
|
|
|
|
- // if (err != 0)
|
|
|
- // throw new System.ComponentModel.Win32Exception (err);
|
|
|
- // }
|
|
|
+ public void ReadFromConsoleOutput (Size size, Coord coords, ref SmallRect window)
|
|
|
+ {
|
|
|
+ screenBuffer = CreateConsoleScreenBuffer (
|
|
|
+ DesiredAccess.GenericRead | DesiredAccess.GenericWrite,
|
|
|
+ ShareMode.FileShareRead | ShareMode.FileShareWrite,
|
|
|
+ IntPtr.Zero,
|
|
|
+ 1,
|
|
|
+ IntPtr.Zero
|
|
|
+ );
|
|
|
+ if (screenBuffer == INVALID_HANDLE_VALUE) {
|
|
|
+ var err = Marshal.GetLastWin32Error ();
|
|
|
|
|
|
- // if (!initialCursorVisibility.HasValue && GetCursorVisibility (out CursorVisibility visibility)) {
|
|
|
- // initialCursorVisibility = visibility;
|
|
|
- // }
|
|
|
+ if (err != 0)
|
|
|
+ throw new System.ComponentModel.Win32Exception (err);
|
|
|
+ }
|
|
|
|
|
|
- // if (!SetConsoleActiveScreenBuffer (ScreenBuffer)) {
|
|
|
- // throw new System.ComponentModel.Win32Exception (Marshal.GetLastWin32Error ());
|
|
|
- // }
|
|
|
+ if (!SetConsoleActiveScreenBuffer (screenBuffer)) {
|
|
|
+ throw new System.ComponentModel.Win32Exception (Marshal.GetLastWin32Error ());
|
|
|
+ }
|
|
|
|
|
|
- // OriginalStdOutChars = new CharInfo [size.Height * size.Width];
|
|
|
+ OriginalStdOutChars = new CharInfo [size.Height * size.Width];
|
|
|
|
|
|
- // if (!ReadConsoleOutput (ScreenBuffer, OriginalStdOutChars, coords, new Coord () { X = 0, Y = 0 }, ref window)) {
|
|
|
- // throw new System.ComponentModel.Win32Exception (Marshal.GetLastWin32Error ());
|
|
|
- // }
|
|
|
- //}
|
|
|
+ if (!ReadConsoleOutput (screenBuffer, OriginalStdOutChars, coords, new Coord () { X = 0, Y = 0 }, ref window)) {
|
|
|
+ throw new System.ComponentModel.Win32Exception (Marshal.GetLastWin32Error ());
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
public bool SetCursorPosition (Coord position)
|
|
|
{
|
|
|
- return SetConsoleCursorPosition (OutputHandle, position);
|
|
|
+ return SetConsoleCursorPosition (IsWindowsTerminal ? OutputHandle : screenBuffer, position);
|
|
|
}
|
|
|
|
|
|
public void SetInitialCursorVisibility ()
|
|
@@ -91,11 +92,11 @@ namespace Terminal.Gui {
|
|
|
|
|
|
public bool GetCursorVisibility (out CursorVisibility visibility)
|
|
|
{
|
|
|
- if (OutputHandle == IntPtr.Zero) {
|
|
|
+ if ((IsWindowsTerminal ? OutputHandle : screenBuffer) == IntPtr.Zero) {
|
|
|
visibility = CursorVisibility.Invisible;
|
|
|
return false;
|
|
|
}
|
|
|
- if (!GetConsoleCursorInfo (OutputHandle, out ConsoleCursorInfo info)) {
|
|
|
+ if (!GetConsoleCursorInfo (IsWindowsTerminal ? OutputHandle : screenBuffer, out ConsoleCursorInfo info)) {
|
|
|
var err = Marshal.GetLastWin32Error ();
|
|
|
if (err != 0) {
|
|
|
throw new System.ComponentModel.Win32Exception (err);
|
|
@@ -148,7 +149,7 @@ namespace Terminal.Gui {
|
|
|
bVisible = ((uint)visibility & 0xFF00) != 0
|
|
|
};
|
|
|
|
|
|
- if (!SetConsoleCursorInfo (OutputHandle, ref info))
|
|
|
+ if (!SetConsoleCursorInfo (IsWindowsTerminal ? OutputHandle : screenBuffer, ref info))
|
|
|
return false;
|
|
|
|
|
|
currentCursorVisibility = visibility;
|
|
@@ -164,28 +165,28 @@ namespace Terminal.Gui {
|
|
|
}
|
|
|
|
|
|
ConsoleMode = originalConsoleMode;
|
|
|
- //if (!SetConsoleActiveScreenBuffer (OutputHandle)) {
|
|
|
- // var err = Marshal.GetLastWin32Error ();
|
|
|
- // Console.WriteLine ("Error: {0}", err);
|
|
|
- //}
|
|
|
+ if (!SetConsoleActiveScreenBuffer (OutputHandle)) {
|
|
|
+ var err = Marshal.GetLastWin32Error ();
|
|
|
+ Console.WriteLine ("Error: {0}", err);
|
|
|
+ }
|
|
|
|
|
|
- //if (ScreenBuffer != IntPtr.Zero) {
|
|
|
- // CloseHandle (ScreenBuffer);
|
|
|
- //}
|
|
|
+ if (screenBuffer != IntPtr.Zero) {
|
|
|
+ CloseHandle (screenBuffer);
|
|
|
+ }
|
|
|
|
|
|
- //ScreenBuffer = IntPtr.Zero;
|
|
|
+ screenBuffer = IntPtr.Zero;
|
|
|
}
|
|
|
|
|
|
internal Size GetConsoleBufferWindow (out Point position)
|
|
|
{
|
|
|
- if (OutputHandle == IntPtr.Zero) {
|
|
|
+ if ((IsWindowsTerminal ? OutputHandle : screenBuffer) == IntPtr.Zero) {
|
|
|
position = Point.Empty;
|
|
|
return Size.Empty;
|
|
|
}
|
|
|
|
|
|
var csbi = new CONSOLE_SCREEN_BUFFER_INFOEX ();
|
|
|
csbi.cbSize = (uint)Marshal.SizeOf (csbi);
|
|
|
- if (!GetConsoleScreenBufferInfoEx (OutputHandle, ref csbi)) {
|
|
|
+ if (!GetConsoleScreenBufferInfoEx ((IsWindowsTerminal ? OutputHandle : screenBuffer), ref csbi)) {
|
|
|
//throw new System.ComponentModel.Win32Exception (Marshal.GetLastWin32Error ());
|
|
|
position = Point.Empty;
|
|
|
return Size.Empty;
|
|
@@ -211,68 +212,70 @@ namespace Terminal.Gui {
|
|
|
return sz;
|
|
|
}
|
|
|
|
|
|
- //internal Size SetConsoleWindow (short cols, short rows)
|
|
|
- //{
|
|
|
- // 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 ());
|
|
|
- // }
|
|
|
- // var maxWinSize = GetLargestConsoleWindowSize (ScreenBuffer);
|
|
|
- // var newCols = Math.Min (cols, maxWinSize.X);
|
|
|
- // var newRows = Math.Min (rows, maxWinSize.Y);
|
|
|
- // csbi.dwSize = new Coord (newCols, Math.Max (newRows, (short)1));
|
|
|
- // csbi.srWindow = new SmallRect (0, 0, newCols, newRows);
|
|
|
- // csbi.dwMaximumWindowSize = new Coord (newCols, newRows);
|
|
|
- // if (!SetConsoleScreenBufferInfoEx (ScreenBuffer, ref csbi)) {
|
|
|
- // throw new System.ComponentModel.Win32Exception (Marshal.GetLastWin32Error ());
|
|
|
- // }
|
|
|
- // var winRect = new SmallRect (0, 0, (short)(newCols - 1), (short)Math.Max (newRows - 1, 0));
|
|
|
- // if (!SetConsoleWindowInfo (OutputHandle, true, ref winRect)) {
|
|
|
- // //throw new System.ComponentModel.Win32Exception (Marshal.GetLastWin32Error ());
|
|
|
- // return new Size (cols, rows);
|
|
|
- // }
|
|
|
- // SetConsoleOutputWindow (csbi);
|
|
|
- // return new Size (winRect.Right + 1, newRows - 1 < 0 ? 0 : winRect.Bottom + 1);
|
|
|
- //}
|
|
|
-
|
|
|
- //void SetConsoleOutputWindow (CONSOLE_SCREEN_BUFFER_INFOEX csbi)
|
|
|
- //{
|
|
|
- // if (ScreenBuffer != IntPtr.Zero && !SetConsoleScreenBufferInfoEx (ScreenBuffer, ref csbi)) {
|
|
|
- // throw new System.ComponentModel.Win32Exception (Marshal.GetLastWin32Error ());
|
|
|
- // }
|
|
|
- //}
|
|
|
-
|
|
|
- //internal Size SetConsoleOutputWindow (out Point position)
|
|
|
- //{
|
|
|
- // if (ScreenBuffer == IntPtr.Zero) {
|
|
|
- // position = Point.Empty;
|
|
|
- // return Size.Empty;
|
|
|
- // }
|
|
|
-
|
|
|
- // 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 ());
|
|
|
- // }
|
|
|
- // var sz = new Size (csbi.srWindow.Right - csbi.srWindow.Left + 1,
|
|
|
- // Math.Max (csbi.srWindow.Bottom - csbi.srWindow.Top + 1, 0));
|
|
|
- // position = new Point (csbi.srWindow.Left, csbi.srWindow.Top);
|
|
|
- // SetConsoleOutputWindow (csbi);
|
|
|
- // var winRect = new SmallRect (0, 0, (short)(sz.Width - 1), (short)Math.Max (sz.Height - 1, 0));
|
|
|
- // if (!SetConsoleScreenBufferInfoEx (OutputHandle, ref csbi)) {
|
|
|
- // throw new System.ComponentModel.Win32Exception (Marshal.GetLastWin32Error ());
|
|
|
- // }
|
|
|
- // if (!SetConsoleWindowInfo (OutputHandle, true, ref winRect)) {
|
|
|
- // throw new System.ComponentModel.Win32Exception (Marshal.GetLastWin32Error ());
|
|
|
- // }
|
|
|
-
|
|
|
- // return sz;
|
|
|
- //}
|
|
|
+ internal Size SetConsoleWindow (short cols, short rows)
|
|
|
+ {
|
|
|
+ var csbi = new CONSOLE_SCREEN_BUFFER_INFOEX ();
|
|
|
+ csbi.cbSize = (uint)Marshal.SizeOf (csbi);
|
|
|
+
|
|
|
+ if (!GetConsoleScreenBufferInfoEx (IsWindowsTerminal ? OutputHandle : screenBuffer, ref csbi)) {
|
|
|
+ throw new System.ComponentModel.Win32Exception (Marshal.GetLastWin32Error ());
|
|
|
+ }
|
|
|
+ var maxWinSize = GetLargestConsoleWindowSize (IsWindowsTerminal ? OutputHandle : screenBuffer);
|
|
|
+ var newCols = Math.Min (cols, maxWinSize.X);
|
|
|
+ var newRows = Math.Min (rows, maxWinSize.Y);
|
|
|
+ csbi.dwSize = new Coord (newCols, Math.Max (newRows, (short)1));
|
|
|
+ csbi.srWindow = new SmallRect (0, 0, newCols, newRows);
|
|
|
+ csbi.dwMaximumWindowSize = new Coord (newCols, newRows);
|
|
|
+ if (!SetConsoleScreenBufferInfoEx (IsWindowsTerminal ? OutputHandle : screenBuffer, ref csbi)) {
|
|
|
+ throw new System.ComponentModel.Win32Exception (Marshal.GetLastWin32Error ());
|
|
|
+ }
|
|
|
+ var winRect = new SmallRect (0, 0, (short)(newCols - 1), (short)Math.Max (newRows - 1, 0));
|
|
|
+ if (!SetConsoleWindowInfo (OutputHandle, true, ref winRect)) {
|
|
|
+ //throw new System.ComponentModel.Win32Exception (Marshal.GetLastWin32Error ());
|
|
|
+ return new Size (cols, rows);
|
|
|
+ }
|
|
|
+ SetConsoleOutputWindow (csbi);
|
|
|
+ return new Size (winRect.Right + 1, newRows - 1 < 0 ? 0 : winRect.Bottom + 1);
|
|
|
+ }
|
|
|
+
|
|
|
+ void SetConsoleOutputWindow (CONSOLE_SCREEN_BUFFER_INFOEX csbi)
|
|
|
+ {
|
|
|
+ if ((IsWindowsTerminal ? OutputHandle : screenBuffer) != IntPtr.Zero && !SetConsoleScreenBufferInfoEx (IsWindowsTerminal ? OutputHandle : screenBuffer, ref csbi)) {
|
|
|
+ throw new System.ComponentModel.Win32Exception (Marshal.GetLastWin32Error ());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ internal Size SetConsoleOutputWindow (out Point position)
|
|
|
+ {
|
|
|
+ if ((IsWindowsTerminal ? OutputHandle : screenBuffer) == IntPtr.Zero) {
|
|
|
+ position = Point.Empty;
|
|
|
+ return Size.Empty;
|
|
|
+ }
|
|
|
+
|
|
|
+ var csbi = new CONSOLE_SCREEN_BUFFER_INFOEX ();
|
|
|
+ csbi.cbSize = (uint)Marshal.SizeOf (csbi);
|
|
|
+ if (!GetConsoleScreenBufferInfoEx (IsWindowsTerminal ? OutputHandle : screenBuffer, ref csbi)) {
|
|
|
+ throw new System.ComponentModel.Win32Exception (Marshal.GetLastWin32Error ());
|
|
|
+ }
|
|
|
+ var sz = new Size (csbi.srWindow.Right - csbi.srWindow.Left + 1,
|
|
|
+ Math.Max (csbi.srWindow.Bottom - csbi.srWindow.Top + 1, 0));
|
|
|
+ position = new Point (csbi.srWindow.Left, csbi.srWindow.Top);
|
|
|
+ SetConsoleOutputWindow (csbi);
|
|
|
+ var winRect = new SmallRect (0, 0, (short)(sz.Width - 1), (short)Math.Max (sz.Height - 1, 0));
|
|
|
+ if (!SetConsoleScreenBufferInfoEx (OutputHandle, ref csbi)) {
|
|
|
+ throw new System.ComponentModel.Win32Exception (Marshal.GetLastWin32Error ());
|
|
|
+ }
|
|
|
+ if (!SetConsoleWindowInfo (OutputHandle, true, ref winRect)) {
|
|
|
+ throw new System.ComponentModel.Win32Exception (Marshal.GetLastWin32Error ());
|
|
|
+ }
|
|
|
+
|
|
|
+ return sz;
|
|
|
+ }
|
|
|
|
|
|
//bool ContinueListeningForConsoleEvents = true;
|
|
|
|
|
|
+ internal bool IsWindowsTerminal { get; set; }
|
|
|
+
|
|
|
public uint ConsoleMode {
|
|
|
get {
|
|
|
GetConsoleMode (InputHandle, out uint v);
|
|
@@ -733,7 +736,7 @@ namespace Terminal.Gui {
|
|
|
WinConsole = new WindowsConsole ();
|
|
|
clipboard = new WindowsClipboard ();
|
|
|
|
|
|
- isWindowsTerminal = Environment.GetEnvironmentVariable ("WT_SESSION") != null || Environment.GetEnvironmentVariable ("VSAPPIDNAME") != null;
|
|
|
+ WinConsole.IsWindowsTerminal = isWindowsTerminal = Environment.GetEnvironmentVariable ("WT_SESSION") != null || Environment.GetEnvironmentVariable ("VSAPPIDNAME") != null;
|
|
|
}
|
|
|
|
|
|
public override void PrepareToRun (MainLoop mainLoop, Action<KeyEvent> keyHandler, Action<KeyEvent> keyDownHandler, Action<KeyEvent> keyUpHandler, Action<MouseEvent> mouseHandler)
|
|
@@ -747,28 +750,28 @@ namespace Terminal.Gui {
|
|
|
|
|
|
mLoop.ProcessInput = (e) => ProcessInput (e);
|
|
|
|
|
|
- //mLoop.WinChanged = (e) => {
|
|
|
- // ChangeWin (e);
|
|
|
- //};
|
|
|
- }
|
|
|
-
|
|
|
- //private void ChangeWin (Size e)
|
|
|
- //{
|
|
|
- // var w = e.Width;
|
|
|
- // if (w == cols - 3 && e.Height < rows) {
|
|
|
- // w += 3;
|
|
|
- // }
|
|
|
- // var newSize = WinConsole.SetConsoleWindow (
|
|
|
- // (short)Math.Max (w, 16), (short)Math.Max (e.Height, 0));
|
|
|
-
|
|
|
- // left = 0;
|
|
|
- // top = 0;
|
|
|
- // cols = newSize.Width;
|
|
|
- // rows = newSize.Height;
|
|
|
- // ResizeScreen ();
|
|
|
- // UpdateOffScreen ();
|
|
|
- // TerminalResized.Invoke ();
|
|
|
- //}
|
|
|
+ mLoop.WinChanged = (e) => {
|
|
|
+ ChangeWin (e);
|
|
|
+ };
|
|
|
+ }
|
|
|
+
|
|
|
+ private void ChangeWin (Size e)
|
|
|
+ {
|
|
|
+ var w = e.Width;
|
|
|
+ if (w == cols - 3 && e.Height < rows) {
|
|
|
+ w += 3;
|
|
|
+ }
|
|
|
+ var newSize = WinConsole.SetConsoleWindow (
|
|
|
+ (short)Math.Max (w, 16), (short)Math.Max (e.Height, 0));
|
|
|
+
|
|
|
+ left = 0;
|
|
|
+ top = 0;
|
|
|
+ cols = newSize.Width;
|
|
|
+ rows = newSize.Height;
|
|
|
+ ResizeScreen ();
|
|
|
+ UpdateOffScreen ();
|
|
|
+ TerminalResized.Invoke ();
|
|
|
+ }
|
|
|
|
|
|
void ProcessInput (WindowsConsole.InputRecord inputEvent)
|
|
|
{
|
|
@@ -892,14 +895,6 @@ namespace Terminal.Gui {
|
|
|
case WindowsConsole.EventType.Focus:
|
|
|
keyModifiers = null;
|
|
|
break;
|
|
|
-
|
|
|
- case WindowsConsole.EventType.WindowBufferSize:
|
|
|
- cols = inputEvent.WindowBufferSizeEvent.size.X;
|
|
|
- rows = inputEvent.WindowBufferSizeEvent.size.Y;
|
|
|
-
|
|
|
- ResizeScreen ();
|
|
|
- TerminalResized.Invoke ();
|
|
|
- break;
|
|
|
}
|
|
|
}
|
|
|
|