From 1be2939f257bc89136bd6ea2ee04cdf75d12f3f0 Mon Sep 17 00:00:00 2001 From: Gilles Khouzam Date: Fri, 11 Aug 2017 16:35:53 -0700 Subject: [PATCH 01/89] Population of the console repository with the ColorTool --- .gitignore | 253 ++++++++++++ README.md | 10 + tools/ColorTool/ColorTool.sln | 22 + tools/ColorTool/ColorTool/App.config | 6 + tools/ColorTool/ColorTool/ColorTool.csproj | 69 ++++ tools/ColorTool/ColorTool/ConsoleAPI.cs | 68 ++++ tools/ColorTool/ColorTool/ISchemeParser.cs | 12 + tools/ColorTool/ColorTool/IniSchemeParser.cs | 153 +++++++ tools/ColorTool/ColorTool/Program.cs | 282 +++++++++++++ .../ColorTool/Properties/AssemblyInfo.cs | 34 ++ .../ColorTool/ColorTool/Resources.Designer.cs | 134 +++++++ tools/ColorTool/ColorTool/Resources.resx | 159 ++++++++ tools/ColorTool/ColorTool/XmlSchemeParser.cs | 178 +++++++++ tools/ColorTool/LICENSE | 21 + tools/ColorTool/README.md | 44 ++ tools/ColorTool/ThirdPartyNotices.md | 51 +++ tools/ColorTool/all.bat | 14 + tools/ColorTool/build.bat | 63 +++ .../ColorTool/schemes/OneHalfDark.itermcolors | 376 ++++++++++++++++++ .../schemes/OneHalfLight.itermcolors | 376 ++++++++++++++++++ tools/ColorTool/schemes/campbell-legacy.ini | 21 + tools/ColorTool/schemes/campbell.ini | 21 + tools/ColorTool/schemes/cmd-legacy.ini | 21 + .../schemes/deuteranopia.itermcolors | 293 ++++++++++++++ .../schemes/solarized_dark.itermcolors | 243 +++++++++++ .../schemes/solarized_light.itermcolors | 289 ++++++++++++++ 26 files changed, 3213 insertions(+) create mode 100644 .gitignore create mode 100644 README.md create mode 100644 tools/ColorTool/ColorTool.sln create mode 100644 tools/ColorTool/ColorTool/App.config create mode 100644 tools/ColorTool/ColorTool/ColorTool.csproj create mode 100644 tools/ColorTool/ColorTool/ConsoleAPI.cs create mode 100644 tools/ColorTool/ColorTool/ISchemeParser.cs create mode 100644 tools/ColorTool/ColorTool/IniSchemeParser.cs create mode 100644 tools/ColorTool/ColorTool/Program.cs create mode 100644 tools/ColorTool/ColorTool/Properties/AssemblyInfo.cs create mode 100644 tools/ColorTool/ColorTool/Resources.Designer.cs create mode 100644 tools/ColorTool/ColorTool/Resources.resx create mode 100644 tools/ColorTool/ColorTool/XmlSchemeParser.cs create mode 100644 tools/ColorTool/LICENSE create mode 100644 tools/ColorTool/README.md create mode 100644 tools/ColorTool/ThirdPartyNotices.md create mode 100644 tools/ColorTool/all.bat create mode 100644 tools/ColorTool/build.bat create mode 100644 tools/ColorTool/schemes/OneHalfDark.itermcolors create mode 100644 tools/ColorTool/schemes/OneHalfLight.itermcolors create mode 100644 tools/ColorTool/schemes/campbell-legacy.ini create mode 100644 tools/ColorTool/schemes/campbell.ini create mode 100644 tools/ColorTool/schemes/cmd-legacy.ini create mode 100644 tools/ColorTool/schemes/deuteranopia.itermcolors create mode 100644 tools/ColorTool/schemes/solarized_dark.itermcolors create mode 100644 tools/ColorTool/schemes/solarized_light.itermcolors diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000..ff1b97869c --- /dev/null +++ b/.gitignore @@ -0,0 +1,253 @@ +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. + +# User-specific files +*.suo +*.user +*.userosscache +*.sln.docstates + +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +bld/ +[Bb]in/ +[Oo]bj/ +[Ll]og/ + +# Visual Studio 2015 cache/options directory +.vs/ +# Uncomment if you have tasks that create the project's static files in wwwroot +#wwwroot/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +# NUNIT +*.VisualState.xml +TestResult.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +# DNX +project.lock.json +artifacts/ + +*_i.c +*_p.c +*_i.h +*.ilk +*.meta +*.obj +*.pch +*.pdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opendb +*.opensdf +*.sdf +*.cachefile +*.VC.db +*.VC.VC.opendb + +# Visual Studio profiler +*.psess +*.vsp +*.vspx +*.sap + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# JustCode is a .NET coding add-in +.JustCode + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# NCrunch +_NCrunch_* +.*crunch*.local.xml +nCrunchTemp_* + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml +# TODO: Comment the next line if you want to checkin your web deploy settings +# but database connection strings (with potential passwords) will be unencrypted +*.pubxml +*.publishproj + +# Microsoft Azure Web App publish settings. Comment the next line if you want to +# checkin your Azure Web App publish settings, but sensitive information contained +# in these scripts will be unencrypted +PublishScripts/ + +# NuGet Packages +*.nupkg +# The packages folder can be ignored because of Package Restore +**/packages/* +# except build/, which is used as an MSBuild target. +!**/packages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/packages/repositories.config +# NuGet v3's project.json files produces more ignoreable files +*.nuget.props +*.nuget.targets + +# Microsoft Azure Build Output +csx/ +*.build.csdef + +# Microsoft Azure Emulator +ecf/ +rcf/ + +# Windows Store app package directories and files +AppPackages/ +BundleArtifacts/ +Package.StoreAssociation.xml +_pkginfo.txt + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!*.[Cc]ache/ + +# Others +ClientBin/ +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.pfx +*.publishsettings +node_modules/ +orleans.codegen.cs + +# Since there are multiple workflows, uncomment next line to ignore bower_components +# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) +#bower_components/ + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm + +# SQL Server files +*.mdf +*.ldf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings + +# Microsoft Fakes +FakesAssemblies/ + +# GhostDoc plugin setting file +*.GhostDoc.xml + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt + +# Visual Studio LightSwitch build output +**/*.HTMLClient/GeneratedArtifacts +**/*.DesktopClient/GeneratedArtifacts +**/*.DesktopClient/ModelManifest.xml +**/*.Server/GeneratedArtifacts +**/*.Server/ModelManifest.xml +_Pvt_Extensions + +# Paket dependency manager +.paket/paket.exe +paket-files/ + +# FAKE - F# Make +.fake/ + +# JetBrains Rider +.idea/ +*.sln.iml +*.exe diff --git a/README.md b/README.md new file mode 100644 index 0000000000..b4516d98c4 --- /dev/null +++ b/README.md @@ -0,0 +1,10 @@ +# Console + +This is the Official Windows Console Github Repo. +Here you'll find assorted console tools in the `tools/` directory, such as the + [ColorTool](https://github.com/Microsoft/Console/tree/master/tools/ColorTool). + +## Issues + +We will be monitoring and responding to issues as best we can. +Please attempt to avoid filing duplicates of open or closed items when possible. diff --git a/tools/ColorTool/ColorTool.sln b/tools/ColorTool/ColorTool.sln new file mode 100644 index 0000000000..4e8aa959d5 --- /dev/null +++ b/tools/ColorTool/ColorTool.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.26228.12 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ColorTool", "ColorTool\ColorTool.csproj", "{97F4550F-5775-4E40-8ECF-A03479884120}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {97F4550F-5775-4E40-8ECF-A03479884120}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {97F4550F-5775-4E40-8ECF-A03479884120}.Debug|Any CPU.Build.0 = Debug|Any CPU + {97F4550F-5775-4E40-8ECF-A03479884120}.Release|Any CPU.ActiveCfg = Release|Any CPU + {97F4550F-5775-4E40-8ECF-A03479884120}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/tools/ColorTool/ColorTool/App.config b/tools/ColorTool/ColorTool/App.config new file mode 100644 index 0000000000..9d2c7adf3b --- /dev/null +++ b/tools/ColorTool/ColorTool/App.config @@ -0,0 +1,6 @@ + + + + + + diff --git a/tools/ColorTool/ColorTool/ColorTool.csproj b/tools/ColorTool/ColorTool/ColorTool.csproj new file mode 100644 index 0000000000..4592e70a67 --- /dev/null +++ b/tools/ColorTool/ColorTool/ColorTool.csproj @@ -0,0 +1,69 @@ + + + + + Debug + AnyCPU + {97F4550F-5775-4E40-8ECF-A03479884120} + Exe + ColorTool + colortool + v4.7 + 512 + true + + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + + + + + + + + + True + True + Resources.resx + + + + + + + + + PublicResXFileCodeGenerator + Resources.Designer.cs + + + + \ No newline at end of file diff --git a/tools/ColorTool/ColorTool/ConsoleAPI.cs b/tools/ColorTool/ColorTool/ConsoleAPI.cs new file mode 100644 index 0000000000..4e438111f0 --- /dev/null +++ b/tools/ColorTool/ColorTool/ConsoleAPI.cs @@ -0,0 +1,68 @@ +// +// Copyright (C) Microsoft. All rights reserved. +// Licensed under the terms described in the LICENSE file in the root of this project. +// + +using System; +using System.Runtime.InteropServices; + +namespace ColorTool +{ + class ConsoleAPI + { + //////////////////////////////////////////////////////////////////////// + [StructLayout(LayoutKind.Sequential)] + public struct COORD + { + public short X; + public short Y; + } + + public struct SMALL_RECT + { + public short Left; + public short Top; + public short Right; + public short Bottom; + } + + [StructLayout(LayoutKind.Sequential)] + public struct CONSOLE_SCREEN_BUFFER_INFO_EX + { + public uint cbSize; + public COORD dwSize; + public COORD dwCursorPosition; + public short wAttributes; + public SMALL_RECT srWindow; + public COORD dwMaximumWindowSize; + + public ushort wPopupAttributes; + public bool bFullscreenSupported; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] + public uint[] ColorTable; + + public static CONSOLE_SCREEN_BUFFER_INFO_EX Create() + { + return new CONSOLE_SCREEN_BUFFER_INFO_EX { cbSize = 96 }; + } + } + + [DllImport("kernel32.dll", SetLastError = true)] + public static extern IntPtr GetStdHandle(int nStdHandle); + + [DllImport("kernel32.dll", SetLastError = true)] + public static extern bool GetConsoleScreenBufferInfoEx(IntPtr hConsoleOutput, ref CONSOLE_SCREEN_BUFFER_INFO_EX ConsoleScreenBufferInfo); + + [DllImport("kernel32.dll", SetLastError = true)] + public static extern bool SetConsoleScreenBufferInfoEx(IntPtr ConsoleOutput, ref CONSOLE_SCREEN_BUFFER_INFO_EX ConsoleScreenBufferInfoEx); + //////////////////////////////////////////////////////////////////////// + + public static uint RGB(int r, int g, int b) + { + return (uint)r + (((uint)g) << 8) + (((uint)b) << 16); + } + + public const int COLOR_TABLE_SIZE = 16; + } +} diff --git a/tools/ColorTool/ColorTool/ISchemeParser.cs b/tools/ColorTool/ColorTool/ISchemeParser.cs new file mode 100644 index 0000000000..df8cfcec2d --- /dev/null +++ b/tools/ColorTool/ColorTool/ISchemeParser.cs @@ -0,0 +1,12 @@ +// +// Copyright (C) Microsoft. All rights reserved. +// Licensed under the terms described in the LICENSE file in the root of this project. +// + +namespace ColorTool +{ + interface ISchemeParser + { + uint[] ParseScheme(string schemeName); + } +} diff --git a/tools/ColorTool/ColorTool/IniSchemeParser.cs b/tools/ColorTool/ColorTool/IniSchemeParser.cs new file mode 100644 index 0000000000..3b1789f57c --- /dev/null +++ b/tools/ColorTool/ColorTool/IniSchemeParser.cs @@ -0,0 +1,153 @@ +// +// Copyright (C) Microsoft. All rights reserved. +// Licensed under the terms described in the LICENSE file in the root of this project. +// + +using System; +using System.Text; +using System.Runtime.InteropServices; +using static ColorTool.ConsoleAPI; +using System.IO; + +namespace ColorTool +{ + class IniSchemeParser : ISchemeParser + { + [DllImport("kernel32")] + private static extern int GetPrivateProfileString(string section, string key, string def, StringBuilder retVal, int size, string filePath); + + // These are in Windows Color table order - BRG, not RGB. + static string[] COLOR_NAMES = { + "DARK_BLACK", + "DARK_BLUE", + "DARK_GREEN", + "DARK_CYAN", + "DARK_RED", + "DARK_MAGENTA", + "DARK_YELLOW", + "DARK_WHITE", + "BRIGHT_BLACK", + "BRIGHT_BLUE", + "BRIGHT_GREEN", + "BRIGHT_CYAN", + "BRIGHT_RED", + "BRIGHT_MAGENTA", + "BRIGHT_YELLOW", + "BRIGHT_WHITE" + }; + + static uint ParseHex(string arg) + { + System.Drawing.Color col = System.Drawing.ColorTranslator.FromHtml(arg); + return RGB(col.R, col.G, col.B); + } + + static uint ParseRgb(string arg) + { + int[] components = { 0, 0, 0}; + string[] args = arg.Split(','); + if (args.Length != components.Length) throw new Exception("Invalid color format \"" + arg + "\""); + if (args.Length != 3) throw new Exception("Invalid color format \"" + arg + "\""); + for (int i = 0; i < args.Length; i++){ + components[i] = Int32.Parse(args[i]); + } + + return RGB(components[0], components[1], components[2]); + } + + static uint ParseColor(string arg) + { + if (arg[0] == '#') + { + return ParseHex(arg.Substring(1)); + } + else + { + return ParseRgb(arg); + } + } + + // TODO: Abstract the locating of a scheme into a function the implementation can call into + // Both parsers duplicate the searching, they should just pass in their extension and + // a callback for initally validating the file + static string FindIniScheme(string schemeName) + { + string exeDir = System.IO.Directory.GetParent(System.Reflection.Assembly.GetEntryAssembly().Location).FullName; + string filename = schemeName + ".ini"; + string exeSchemes = exeDir + "/schemes/"; + string cwd = "./"; + string cwdSchemes = "./schemes/"; + // Search order, for argument "name", where 'exe' is the dir of the exe. + // 1. ./name + // 2. ./name.ini + // 3. ./schemes/name + // 4. ./schemes/name.ini + // 5. exe/schemes/name + // 6. exe/schemes/name.ini + // 7. name (as an absolute path) + string[] paths = { + cwd + schemeName, + cwd + filename, + cwdSchemes + schemeName, + cwdSchemes + filename, + exeSchemes + schemeName, + exeSchemes + filename, + schemeName, + }; + foreach (string path in paths) + { + if (File.Exists(path)) + { + return path; + } + } + return null; + } + + public uint[] ParseScheme(string schemeName) + { + bool success = true; + + string filename = FindIniScheme(schemeName); + if (filename == null) return null; + + string[] tableStrings = new string[COLOR_TABLE_SIZE]; + uint[] colorTable = null; + + for (int i = 0; i < COLOR_TABLE_SIZE; i++) + { + string name = COLOR_NAMES[i]; + StringBuilder buffer = new StringBuilder(512); + GetPrivateProfileString("table", name, null, buffer, 512, filename); + + tableStrings[i] = buffer.ToString(); + if (tableStrings[i].Length <= 0) + { + success = false; + Console.WriteLine(string.Format(Resources.IniParseError, filename, name, tableStrings[i])); + break; + } + } + + if (success) + { + try + { + colorTable = new uint[COLOR_TABLE_SIZE]; + for (int i = 0; i < COLOR_TABLE_SIZE; i++) + { + colorTable[i] = ParseColor(tableStrings[i]); + } + } + catch (Exception /*e*/) + { + Console.WriteLine(string.Format(Resources.IniLoadError, filename)); + + colorTable = null; + } + } + + return colorTable; + } + } +} diff --git a/tools/ColorTool/ColorTool/Program.cs b/tools/ColorTool/ColorTool/Program.cs new file mode 100644 index 0000000000..1f56047f22 --- /dev/null +++ b/tools/ColorTool/ColorTool/Program.cs @@ -0,0 +1,282 @@ +// +// Copyright (C) Microsoft. All rights reserved. +// Licensed under the terms described in the LICENSE file in the root of this project. +// + +using System; +using static ColorTool.ConsoleAPI; +using Microsoft.Win32; +using System.Reflection; + +namespace ColorTool +{ + class Program + { + static int DARK_BLACK = 0; + static int DARK_BLUE = 1; + static int DARK_GREEN = 2; + static int DARK_CYAN = 3; + static int DARK_RED = 4; + static int DARK_MAGENTA = 5; + static int DARK_YELLOW = 6; + static int DARK_WHITE = 7; + static int BRIGHT_BLACK = 8; + static int BRIGHT_BLUE = 9; + static int BRIGHT_GREEN = 10; + static int BRIGHT_CYAN = 11; + static int BRIGHT_RED = 12; + static int BRIGHT_MAGENTA = 13; + static int BRIGHT_YELLOW = 14; + static int BRIGHT_WHITE = 15; + + static int[] saneFgs = { + DARK_BLACK , + DARK_RED , + DARK_GREEN , + DARK_YELLOW , + DARK_BLUE , + DARK_MAGENTA , + DARK_CYAN , + DARK_WHITE , + BRIGHT_BLACK , + BRIGHT_RED , + BRIGHT_GREEN , + BRIGHT_YELLOW , + BRIGHT_MAGENTA , + BRIGHT_BLUE , + BRIGHT_CYAN , + BRIGHT_WHITE + }; + + // This is the order of colors when output by the table. + static int[] outputFgs = { + BRIGHT_WHITE , + DARK_BLACK , + BRIGHT_BLACK , + DARK_RED , + BRIGHT_RED , + DARK_GREEN , + BRIGHT_GREEN , + DARK_YELLOW , + BRIGHT_YELLOW , + DARK_BLUE , + BRIGHT_BLUE , + DARK_MAGENTA , + BRIGHT_MAGENTA , + DARK_CYAN , + BRIGHT_CYAN , + DARK_WHITE , + BRIGHT_WHITE + }; + + static int[] saneBgs = { + DARK_BLACK , + DARK_RED , + DARK_GREEN , + DARK_YELLOW , + DARK_BLUE , + DARK_MAGENTA , + DARK_CYAN , + DARK_WHITE + }; + + static bool quiteMode = false; + static bool setDefaults = false; + static bool setProperties = true; + + static void Usage() + { + Console.WriteLine(Resources.Usage); + } + + static void Version() + { + //System.Reflection.Assembly.GetEntryAssembly(); + //AssemblyName.GetAssemblyName(@"c:\path\to\file.dll").Version; + string exePath = System.Reflection.Assembly.GetEntryAssembly().Location; + Version ver = AssemblyName.GetAssemblyName(exePath).Version; + Console.WriteLine("colortool v" + ver); + } + + static void PrintTable() + { + ConsoleColor[] colors = (ConsoleColor[])ConsoleColor.GetValues(typeof(ConsoleColor)); + // Save the current background and foreground colors. + ConsoleColor currentBackground = Console.BackgroundColor; + ConsoleColor currentForeground = Console.ForegroundColor; + string test = " gYw "; + string[] FGs = { + "m", + "1m", + "30m", + "1;30m", + "31m", + "1;31m", + "32m", + "1;32m", + "33m", + "1;33m", + "34m", + "1;34m", + "35m", + "1;35m", + "36m", + "1;36m", + "37m", + "1;37m" + }; + string[] BGs = { + "m", + "40m", + "41m", + "42m", + "43m", + "44m", + "45m", + "46m", + "47m" + }; + + Console.Write("\t"); + for (int bg = 0; bg < BGs.Length; bg++) + { + if (bg > 0) Console.Write(" "); + Console.Write(" "); + Console.Write(bg == 0 ? " " : BGs[bg]); + Console.Write(" "); + } + Console.WriteLine(); + + for (int fg = 0; fg < FGs.Length; fg++) + { + Console.ForegroundColor = currentForeground; + Console.BackgroundColor = currentBackground; + + if (fg >= 0) Console.Write(FGs[fg] + "\t"); + + if (fg == 0) Console.ForegroundColor = currentForeground; + else Console.ForegroundColor = colors[outputFgs[fg - 1]]; + + for (int bg = 0; bg < BGs.Length; bg++) + { + if (bg > 0) Console.Write(" "); + if (bg == 0) + Console.BackgroundColor = currentBackground; + else Console.BackgroundColor = colors[saneBgs[bg - 1]]; + Console.Write(test); + Console.BackgroundColor = currentBackground; + } + Console.Write("\n"); + + } + Console.Write("\n"); + } + + static bool SetProperties(uint[] colorTable) + { + CONSOLE_SCREEN_BUFFER_INFO_EX csbiex = CONSOLE_SCREEN_BUFFER_INFO_EX.Create(); + int STD_OUTPUT_HANDLE = -11; + IntPtr hOut = GetStdHandle(STD_OUTPUT_HANDLE); + bool success = GetConsoleScreenBufferInfoEx(hOut, ref csbiex); + if (success) + { + csbiex.srWindow.Bottom++; + for (int i = 0; i < 16; i++) + { + csbiex.ColorTable[i] = colorTable[i]; + } + SetConsoleScreenBufferInfoEx(hOut, ref csbiex); + } + if (success) + { + if (!quiteMode) + { + PrintTable(); + } + } + return success; + } + static bool SetDefaults(uint[] colorTable) + { + RegistryKey consoleKey = Registry.CurrentUser.OpenSubKey("Console", true); + for (int i = 0; i < colorTable.Length; i++) + { + string valueName = "ColorTable" + (i < 10 ? "0" : "") + i; + consoleKey.SetValue(valueName, colorTable[i], RegistryValueKind.DWord); + } + Console.WriteLine(Resources.WroteToDefaults); + return true; + } + + + static void Main(string[] args) + { + if (args.Length < 1) + { + Usage(); + return; + } + + foreach (string arg in args) + { + switch (arg) + { + case "-q": + case "--quiet": + quiteMode = true; + break; + case "-d": + case "--defaults": + setDefaults = true; + setProperties = false; + break; + case "-b": + case "--both": + setDefaults = true; + setProperties = true; + break; + case "-?": + case "--help": + Usage(); + return; + case "-v": + case "--version": + Version(); + return; + default: + break; + } + } + + string schemeName = args[args.Length - 1]; + + uint[] colorTable = null; + ISchemeParser[] parsers = { new XmlSchemeParser(), new IniSchemeParser() }; + foreach (var parser in parsers) + { + uint[] table = parser.ParseScheme(schemeName); + if (table != null) + { + colorTable = table; + break; + } + } + + if (colorTable == null) + { + Console.WriteLine(string.Format(Resources.SchemeNotFound, schemeName)); + return; + } + + if (setDefaults) + { + SetDefaults(colorTable); + } + if (setProperties) + { + SetProperties(colorTable); + } + } + + } +} diff --git a/tools/ColorTool/ColorTool/Properties/AssemblyInfo.cs b/tools/ColorTool/ColorTool/Properties/AssemblyInfo.cs new file mode 100644 index 0000000000..d0698c57f4 --- /dev/null +++ b/tools/ColorTool/ColorTool/Properties/AssemblyInfo.cs @@ -0,0 +1,34 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("ColorTool")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("ColorTool")] +[assembly: AssemblyCopyright("Copyright © 2017")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("97f4550f-5775-4e40-8ecf-a03479884120")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +[assembly: AssemblyVersion("1.0.*")] diff --git a/tools/ColorTool/ColorTool/Resources.Designer.cs b/tools/ColorTool/ColorTool/Resources.Designer.cs new file mode 100644 index 0000000000..e053d6d114 --- /dev/null +++ b/tools/ColorTool/ColorTool/Resources.Designer.cs @@ -0,0 +1,134 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace ColorTool { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + public class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + public static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("ColorTool.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + public static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// Looks up a localized string similar to Error loading ini file "{0}". + /// + public static string IniLoadError { + get { + return ResourceManager.GetString("IniLoadError", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Error loading ini file "{0}" + /// for key "{1}" + /// the value "{2}" is invalid. + /// + public static string IniParseError { + get { + return ResourceManager.GetString("IniParseError", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Invalid Color. + /// + public static string InvalidColor { + get { + return ResourceManager.GetString("InvalidColor", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Invalid scheme - did not find 16 colors. + /// + public static string InvalidNumberOfColors { + get { + return ResourceManager.GetString("InvalidNumberOfColors", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Could not find or load "{0}". + /// + public static string SchemeNotFound { + get { + return ResourceManager.GetString("SchemeNotFound", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Usage: + /// colortool.exe [options] <schemename> + ///ColorTool is a utility for helping to set the color palette of the Windows Console. + ///By default, applies the colors in the specified .itermcolors or .ini file to the current console window. + ///This does NOT save the properties automatically. For that, you'll need to open the properties sheet and hit "Ok". + ///Included should be a `schemes/` directory with a selection of schemes of both formats for examples. + ///Feel free to add your own prefered scheme to that direc [rest of string was truncated]";. + /// + public static string Usage { + get { + return ResourceManager.GetString("Usage", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Wrote selected scheme to the defaults.. + /// + public static string WroteToDefaults { + get { + return ResourceManager.GetString("WroteToDefaults", resourceCulture); + } + } + } +} diff --git a/tools/ColorTool/ColorTool/Resources.resx b/tools/ColorTool/ColorTool/Resources.resx new file mode 100644 index 0000000000..e999e0daab --- /dev/null +++ b/tools/ColorTool/ColorTool/Resources.resx @@ -0,0 +1,159 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Error loading ini file "{0}" + + + Error loading ini file "{0}" + for key "{1}" + the value "{2}" is invalid + + + Invalid Color + + + Invalid scheme - did not find 16 colors + + + Could not find or load "{0}" + + + Usage: + colortool.exe [options] <schemename> +ColorTool is a utility for helping to set the color palette of the Windows Console. +By default, applies the colors in the specified .itermcolors or .ini file to the current console window. +This does NOT save the properties automatically. For that, you'll need to open the properties sheet and hit "Ok". +Included should be a `schemes/` directory with a selection of schemes of both formats for examples. +Feel free to add your own prefered scheme to that directory. +Arguments: + <schemename>: The name of a color scheme. ct will try to first load it as an .itermcolors color scheme. + If that fails, it will look for it as an .ini file color scheme. +Options: + -?, --help : Display this help message + -q, --quiet : Don't print the color table after applying + -d, --defaults : Apply the scheme to only the defaults in the registry + -b, --both : Apply the scheme to both the current console and the defaults. + -v, --version : Display the version number + + + + Wrote selected scheme to the defaults. + + \ No newline at end of file diff --git a/tools/ColorTool/ColorTool/XmlSchemeParser.cs b/tools/ColorTool/ColorTool/XmlSchemeParser.cs new file mode 100644 index 0000000000..7afea4d8d0 --- /dev/null +++ b/tools/ColorTool/ColorTool/XmlSchemeParser.cs @@ -0,0 +1,178 @@ +// +// Copyright (C) Microsoft. All rights reserved. +// Licensed under the terms described in the LICENSE file in the root of this project. +// +using System; +using System.Xml; +using static ColorTool.ConsoleAPI; + +namespace ColorTool +{ + class XmlSchemeParser : ISchemeParser + { + // In Windows Color Table order + static string[] PLIST_COLOR_NAMES = { + "Ansi 0 Color", // DARK_BLACK + "Ansi 4 Color", // DARK_BLUE + "Ansi 2 Color", // DARK_GREEN + "Ansi 6 Color", // DARK_CYAN + "Ansi 1 Color", // DARK_RED + "Ansi 5 Color", // DARK_MAGENTA + "Ansi 3 Color", // DARK_YELLOW + "Ansi 7 Color", // DARK_WHITE + "Ansi 8 Color", // BRIGHT_BLACK + "Ansi 12 Color", // BRIGHT_BLUE + "Ansi 10 Color", // BRIGHT_GREEN + "Ansi 14 Color", // BRIGHT_CYAN + "Ansi 9 Color", // BRIGHT_RED + "Ansi 13 Color", // BRIGHT_MAGENTA + "Ansi 11 Color", // BRIGHT_YELLOW + "Ansi 15 Color" // BRIGHT_WHITE + }; + static string RED_KEY = "Red Component"; + static string GREEN_KEY = "Green Component"; + static string BLUE_KEY = "Blue Component"; + + static bool parseRgbFromXml(XmlNode components, ref uint rgb) + { + int r = -1; + int g = -1; + int b = -1; + + foreach (XmlNode c in components.ChildNodes) + { + if (c.Name == "key") + { + if (c.InnerText == RED_KEY) + { + r = (int)(255 * Convert.ToDouble(c.NextSibling.InnerText)); + } + else if (c.InnerText == GREEN_KEY) + { + g = (int)(255 * Convert.ToDouble(c.NextSibling.InnerText)); + } + else if (c.InnerText == BLUE_KEY) + { + b = (int)(255 * Convert.ToDouble(c.NextSibling.InnerText)); + } + else + { + continue; + } + } + } + if (r < 0 || g < 0 || b < 0) + { + Console.WriteLine(Resources.InvalidColor); + return false; + } + rgb = RGB(r, g, b); + return true; + } + + + static XmlDocument loadXmlScheme(string schemeName) + { + XmlDocument xmlDoc = new XmlDocument(); // Create an XML document object + string exeDir = System.IO.Directory.GetParent(System.Reflection.Assembly.GetEntryAssembly().Location).FullName; + bool found = false; + string filename = schemeName + ".itermcolors"; + string exeSchemes = exeDir + "/schemes/"; + string cwd = "./"; + string cwdSchemes = "./schemes/"; + // Search order, for argument "name", where 'exe' is the dir of the exe. + // 1. ./name + // 2. ./name.itermcolors + // 3. ./schemes/name + // 4. ./schemes/name.itermcolors + // 5. exe/schemes/name + // 6. exe/schemes/name.itermcolors + // 7. name (as an absolute path) + string[] paths = { + cwd + schemeName, + cwd + filename, + cwdSchemes + schemeName, + cwdSchemes + filename, + exeSchemes + schemeName, + exeSchemes + filename, + schemeName, + }; + foreach (string path in paths) + { + try + { + xmlDoc.Load(path); + found = true; + break; + } + catch (Exception /*e*/) + { + // We can either fail to find the file, + // or fail to parse the XML here. + } + } + + if (!found) + { + return null; + } + return xmlDoc; + } + + + public uint[] ParseScheme(string schemeName) + { + XmlDocument xmlDoc = loadXmlScheme(schemeName); // Create an XML document object + if (xmlDoc == null) return null; + XmlNode root = xmlDoc.GetElementsByTagName("dict")[0]; + XmlNodeList children = root.ChildNodes; + + uint[] colorTable = new uint[COLOR_TABLE_SIZE]; + int colorsFound = 0; + bool success = false; + foreach (XmlNode tableEntry in children) + { + if (tableEntry.Name == "key") + { + int index = -1; + for (int i = 0; i < COLOR_TABLE_SIZE; i++) + { + if (PLIST_COLOR_NAMES[i] == tableEntry.InnerText) + { + index = i; + break; + } + } + if (index == -1) + { + continue; + } + uint rgb = 0; ; + XmlNode components = tableEntry.NextSibling; + success = parseRgbFromXml(components, ref rgb); + if (!success) + { + break; + } + else + { + colorTable[index] = rgb; + colorsFound++; + } + } + + } + if (colorsFound < COLOR_TABLE_SIZE) + { + Console.WriteLine(Resources.InvalidNumberOfColors); + success = false; + } + if (!success) + { + return null; + } + return colorTable; + + } + } +} diff --git a/tools/ColorTool/LICENSE b/tools/ColorTool/LICENSE new file mode 100644 index 0000000000..21071075c2 --- /dev/null +++ b/tools/ColorTool/LICENSE @@ -0,0 +1,21 @@ + MIT License + + Copyright (c) Microsoft Corporation. All rights reserved. + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE diff --git a/tools/ColorTool/README.md b/tools/ColorTool/README.md new file mode 100644 index 0000000000..c381a57961 --- /dev/null +++ b/tools/ColorTool/README.md @@ -0,0 +1,44 @@ +# ColorTool - colortool.exe + +``` +Usage: + colortool.exe [options] ; +ColorTool is a utility for helping to set the color palette of the Windows Console. +By default, applies the colors in the specified .itermcolors or .ini file to the current console window. +This does NOT save the properties automatically. For that, you'll need to open the properties sheet and hit "Ok". +Included should be a `schemes/` directory with a selection of schemes of both formats for examples. +Feel free to add your own prefered scheme to that directory. +Arguments: + : The name of a color scheme. ct will try to first load it as an .itermcolors color scheme. + If that fails, it will look for it as an .ini file color scheme. +Options: + -?, --help : Display this help message + -q, --quiet : Don't print the color table after applying + -d, --defaults : Apply the scheme to only the defaults in the registry + -b, --both : Apply the scheme to both the current console and the defaults. + -v, --version : Display the version number +``` + +## Included Schemes + + Included are two important color schemes in .ini file format - `cmd-legacy` and `campbell`. + + * `cmd-legacy` is the legacy color scheme of the Windows Console, before July 2017 + + * `campbell` is the new default scheme used by the Windows Console Host, as of the Fall Creator's Update. + + There are a few other schemes in that directory in both .ini format and .itermcolors. + +## Adding Schemes + + You can also add color schemes to the colortool easily. Take any existing scheme in `.itemcolors` format, and paste it in the `schemes/` directory. + + I recommend the excellent [iTerm2-Color-Schemes](https://github.com/mbadolato/iTerm2-Color-Schemes) repo, which has TONS of schemes to chose from, and previews. + +## Building + + Either build with Visual Studio, or use the included `build.bat` from the commandline to try and auto-detect your msbuild version. + +## Contributing + + This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments. diff --git a/tools/ColorTool/ThirdPartyNotices.md b/tools/ColorTool/ThirdPartyNotices.md new file mode 100644 index 0000000000..8c02c37428 --- /dev/null +++ b/tools/ColorTool/ThirdPartyNotices.md @@ -0,0 +1,51 @@ +Third Party Notices +=================== +This software is based on or incorporates material from the projects listed below (collectively, “Third-Party Code”). Please Note: Microsoft is not the original author of the Third-Party Code. The original copyright notice and license text under which Microsoft received the Third-Party Code are set forth below. Such licenses and notices are provided solely for your information. Unless otherwise noted below, Microsoft, not the third party, licenses this Third-Party Code to you under the terms by which you received the Microsoft software or the service. Microsoft reserves all other rights not expressly granted, whether by implication, estoppel or otherwise. + +Do Not Translate or Localize + + +One Half Dark and One Half Light Schemes +---------------------------------------- + +Copyright (c) 2016 Son A. Pham + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +Solarized Dark and Light Schemes +-------------------------------- +Copyright (c) 2011 Ethan Schoonover + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. \ No newline at end of file diff --git a/tools/ColorTool/all.bat b/tools/ColorTool/all.bat new file mode 100644 index 0000000000..8602076c42 --- /dev/null +++ b/tools/ColorTool/all.bat @@ -0,0 +1,14 @@ +@echo off + +rem all.bat +rem This tool can be used to iterate over all the schemes you have installed +rem To help find one that you like. Simply press Ctrl+C when you get to one you like. +rem Note: You will likely destroy your current console window's history. +rem Only the most recent theme is visible in the console. +rem All of the previously viewed tables will display the current scheme's colors. + +for %%i in (schemes\*) do ( + echo %%i + ct.exe "%%i" + pause +) \ No newline at end of file diff --git a/tools/ColorTool/build.bat b/tools/ColorTool/build.bat new file mode 100644 index 0000000000..e39dc3d8e4 --- /dev/null +++ b/tools/ColorTool/build.bat @@ -0,0 +1,63 @@ +@echo off + +rem Add path to MSBuild Binaries +set MSBUILD=() +if exist "%ProgramFiles(x86)%\Microsoft Visual Studio\2017\Community\MSBuild\15.0\Bin\msbuild.exe" ( + set MSBUILD="%ProgramFiles(x86)%\Microsoft Visual Studio\2017\Community\MSBuild\15.0\Bin\msbuild.exe" + goto :FOUND_MSBUILD +) +if exist "%ProgramFiles%\Microsoft Visual Studio\2017\Community\MSBuild\15.0\Bin\msbuild.exe" ( + set MSBUILD="%ProgramFiles%\Microsoft Visual Studio\2017\Community\MSBuild\15.0\Bin\msbuild.exe" + goto :FOUND_MSBUILD +) +if exist "%ProgramFiles(x86)%\Microsoft Visual Studio\2017\Enterprise\MSBuild\15.0\Bin\msbuild.exe" ( + set MSBUILD="%ProgramFiles(x86)%\Microsoft Visual Studio\2017\Enterprise\MSBuild\15.0\Bin\msbuild.exe" + goto :FOUND_MSBUILD +) +if exist "%ProgramFiles%\Microsoft Visual Studio\2017\Enterprise\MSBuild\15.0\Bin\msbuild.exe" ( + set MSBUILD="%ProgramFiles%\Microsoft Visual Studio\2017\Enterprise\MSBuild\15.0\Bin\msbuild.exe" + goto :FOUND_MSBUILD +) +if exist "%ProgramFiles(x86)%\MSBuild\14.0\bin" ( + set MSBUILD="%ProgramFiles(x86)%\MSBuild\14.0\bin\msbuild.exe" + goto :FOUND_MSBUILD +) +if exist "%ProgramFiles%\MSBuild\14.0\bin" ( + set MSBUILD="%ProgramFiles%\MSBuild\14.0\bin\msbuild.exe" + goto :FOUND_MSBUILD +) + +if %MSBUILD%==() ( + echo "I couldn't find MSBuild on your PC. Make sure it's installed somewhere, and if it's not in the above if statements (in build.bat), add it." + goto :EXIT +) +:FOUND_MSBUILD +set _MSBUILD_TARGET=Build +set _MSBUILD_CONFIG=Debug + +:ARGS_LOOP +if (%1) == () goto :POST_ARGS_LOOP +if (%1) == (clean) ( + set _MSBUILD_TARGET=Clean,Build +) +if (%1) == (rel) ( + set _MSBUILD_CONFIG=Release +) +shift +goto :ARGS_LOOP + +:POST_ARGS_LOOP +%MSBUILD% %~dp0ColorTool.sln /t:%_MSBUILD_TARGET% /m /nr:true /p:Configuration=%_MSBUILD_CONFIG% + +if (%ERRORLEVEL%) == (0) ( + echo. + echo Created exe in: + echo %~dp0ColorTool\bin\%_MSBUILD_CONFIG%\colortool.exe + echo. + echo Copying exe to root of project... + copy %~dp0ColorTool\bin\%_MSBUILD_CONFIG%\colortool.exe %~dp0colortool.exe + echo Done. + echo. +) + +:EXIT \ No newline at end of file diff --git a/tools/ColorTool/schemes/OneHalfDark.itermcolors b/tools/ColorTool/schemes/OneHalfDark.itermcolors new file mode 100644 index 0000000000..50987c8fab --- /dev/null +++ b/tools/ColorTool/schemes/OneHalfDark.itermcolors @@ -0,0 +1,376 @@ + + + + + + Ansi 0 Color + + Alpha Component + 1 + Blue Component + 0.203921568627 + Color Space + Calibrated + Green Component + 0.172549019608 + Red Component + 0.156862745098 + + Ansi 1 Color + + Alpha Component + 1 + Blue Component + 0.458823529412 + Color Space + Calibrated + Green Component + 0.423529411765 + Red Component + 0.878431372549 + + Ansi 10 Color + + Alpha Component + 1 + Blue Component + 0.474509803922 + Color Space + Calibrated + Green Component + 0.764705882353 + Red Component + 0.596078431373 + + Ansi 11 Color + + Alpha Component + 1 + Blue Component + 0.482352941176 + Color Space + Calibrated + Green Component + 0.752941176471 + Red Component + 0.898039215686 + + Ansi 12 Color + + Alpha Component + 1 + Blue Component + 0.937254901961 + Color Space + Calibrated + Green Component + 0.686274509804 + Red Component + 0.380392156863 + + Ansi 13 Color + + Alpha Component + 1 + Blue Component + 0.866666666667 + Color Space + Calibrated + Green Component + 0.470588235294 + Red Component + 0.776470588235 + + Ansi 14 Color + + Alpha Component + 1 + Blue Component + 0.760784313725 + Color Space + Calibrated + Green Component + 0.713725490196 + Red Component + 0.337254901961 + + Ansi 15 Color + + Alpha Component + 1 + Blue Component + 0.894117647059 + Color Space + Calibrated + Green Component + 0.874509803922 + Red Component + 0.862745098039 + + Ansi 2 Color + + Alpha Component + 1 + Blue Component + 0.474509803922 + Color Space + Calibrated + Green Component + 0.764705882353 + Red Component + 0.596078431373 + + Ansi 3 Color + + Alpha Component + 1 + Blue Component + 0.482352941176 + Color Space + Calibrated + Green Component + 0.752941176471 + Red Component + 0.898039215686 + + Ansi 4 Color + + Alpha Component + 1 + Blue Component + 0.937254901961 + Color Space + Calibrated + Green Component + 0.686274509804 + Red Component + 0.380392156863 + + Ansi 5 Color + + Alpha Component + 1 + Blue Component + 0.866666666667 + Color Space + Calibrated + Green Component + 0.470588235294 + Red Component + 0.776470588235 + + Ansi 6 Color + + Alpha Component + 1 + Blue Component + 0.760784313725 + Color Space + Calibrated + Green Component + 0.713725490196 + Red Component + 0.337254901961 + + Ansi 7 Color + + Alpha Component + 1 + Blue Component + 0.894117647059 + Color Space + Calibrated + Green Component + 0.874509803922 + Red Component + 0.862745098039 + + Ansi 8 Color + + Alpha Component + 1 + Blue Component + 0.203921568627 + Color Space + Calibrated + Green Component + 0.172549019608 + Red Component + 0.156862745098 + + Ansi 9 Color + + Alpha Component + 1 + Blue Component + 0.458823529412 + Color Space + Calibrated + Green Component + 0.423529411765 + Red Component + 0.878431372549 + + Background Color + + Alpha Component + 1 + Blue Component + 0.203921568627 + Color Space + Calibrated + Green Component + 0.172549019608 + Red Component + 0.156862745098 + + Badge Color + + Alpha Component + 0.5 + Blue Component + 0.0 + Color Space + Calibrated + Green Component + 0.0 + Red Component + 1 + + Bold Color + + Alpha Component + 1 + Blue Component + 0.74901962280273438 + Color Space + Calibrated + Green Component + 0.69803923368453979 + Red Component + 0.67058825492858887 + + Cursor Color + + Alpha Component + 1 + Blue Component + 0.8 + Color Space + Calibrated + Green Component + 0.701960784314 + Red Component + 0.639215686275 + + Cursor Guide Color + + Alpha Component + 0.25 + Blue Component + 0.250980392157 + Color Space + Calibrated + Green Component + 0.211764705882 + Red Component + 0.192156862745 + + Cursor Text Color + + Alpha Component + 1 + Blue Component + 0.894117647059 + Color Space + Calibrated + Green Component + 0.874509803922 + Red Component + 0.862745098039 + + Foreground Color + + Alpha Component + 1 + Blue Component + 0.894117647059 + Color Space + Calibrated + Green Component + 0.874509803922 + Red Component + 0.862745098039 + + Link Color + + Alpha Component + 1 + Blue Component + 0.937254901961 + Color Space + Calibrated + Green Component + 0.686274509804 + Red Component + 0.380392156863 + + Selected Text Color + + Alpha Component + 1 + Blue Component + 0.894117647059 + Color Space + Calibrated + Green Component + 0.874509803922 + Red Component + 0.862745098039 + + Selection Color + + Alpha Component + 1 + Blue Component + 0.364705882353 + Color Space + Calibrated + Green Component + 0.305882352941 + Red Component + 0.278431372549 + + + \ No newline at end of file diff --git a/tools/ColorTool/schemes/OneHalfLight.itermcolors b/tools/ColorTool/schemes/OneHalfLight.itermcolors new file mode 100644 index 0000000000..5039196027 --- /dev/null +++ b/tools/ColorTool/schemes/OneHalfLight.itermcolors @@ -0,0 +1,376 @@ + + + + + + Ansi 0 Color + + Alpha Component + 1 + Blue Component + 0.258823529412 + Color Space + Calibrated + Green Component + 0.227450980392 + Red Component + 0.219607843137 + + Ansi 1 Color + + Alpha Component + 1 + Blue Component + 0.286274509804 + Color Space + Calibrated + Green Component + 0.337254901961 + Red Component + 0.894117647059 + + Ansi 10 Color + + Alpha Component + 1 + Blue Component + 0.474509803922 + Color Space + Calibrated + Green Component + 0.764705882353 + Red Component + 0.596078431373 + + Ansi 11 Color + + Alpha Component + 1 + Blue Component + 0.482352941176 + Color Space + Calibrated + Green Component + 0.752941176471 + Red Component + 0.898039215686 + + Ansi 12 Color + + Alpha Component + 1 + Blue Component + 0.937254901961 + Color Space + Calibrated + Green Component + 0.686274509804 + Red Component + 0.380392156863 + + Ansi 13 Color + + Alpha Component + 1 + Blue Component + 0.866666666667 + Color Space + Calibrated + Green Component + 0.470588235294 + Red Component + 0.776470588235 + + Ansi 14 Color + + Alpha Component + 1 + Blue Component + 0.760784313725 + Color Space + Calibrated + Green Component + 0.713725490196 + Red Component + 0.337254901961 + + Ansi 15 Color + + Alpha Component + 1 + Blue Component + 1.0 + Color Space + Calibrated + Green Component + 1.0 + Red Component + 1.0 + + Ansi 2 Color + + Alpha Component + 1 + Blue Component + 0.309803921569 + Color Space + Calibrated + Green Component + 0.63137254902 + Red Component + 0.313725490196 + + Ansi 3 Color + + Alpha Component + 1 + Blue Component + 0.00392156862745 + Color Space + Calibrated + Green Component + 0.517647058824 + Red Component + 0.756862745098 + + Ansi 4 Color + + Alpha Component + 1 + Blue Component + 0.737254901961 + Color Space + Calibrated + Green Component + 0.517647058824 + Red Component + 0.00392156862745 + + Ansi 5 Color + + Alpha Component + 1 + Blue Component + 0.643137254902 + Color Space + Calibrated + Green Component + 0.149019607843 + Red Component + 0.650980392157 + + Ansi 6 Color + + Alpha Component + 1 + Blue Component + 0.701960784314 + Color Space + Calibrated + Green Component + 0.592156862745 + Red Component + 0.0352941176471 + + Ansi 7 Color + + Alpha Component + 1 + Blue Component + 0.980392156863 + Color Space + Calibrated + Green Component + 0.980392156863 + Red Component + 0.980392156863 + + Ansi 8 Color + + Alpha Component + 1 + Blue Component + 0.36862745098 + Color Space + Calibrated + Green Component + 0.321568627451 + Red Component + 0.309803921569 + + Ansi 9 Color + + Alpha Component + 1 + Blue Component + 0.458823529412 + Color Space + Calibrated + Green Component + 0.423529411765 + Red Component + 0.878431372549 + + Background Color + + Alpha Component + 1 + Blue Component + 0.980392156863 + Color Space + Calibrated + Green Component + 0.980392156863 + Red Component + 0.980392156863 + + Badge Color + + Alpha Component + 0.5 + Blue Component + 0.0 + Color Space + Calibrated + Green Component + 0.0 + Red Component + 1 + + Bold Color + + Alpha Component + 1 + Blue Component + 0.74901962280273438 + Color Space + Calibrated + Green Component + 0.69803923368453979 + Red Component + 0.67058825492858887 + + Cursor Color + + Alpha Component + 1 + Blue Component + 1.0 + Color Space + Calibrated + Green Component + 0.807843137255 + Red Component + 0.749019607843 + + Cursor Guide Color + + Alpha Component + 0.25 + Blue Component + 0.941176470588 + Color Space + Calibrated + Green Component + 0.941176470588 + Red Component + 0.941176470588 + + Cursor Text Color + + Alpha Component + 1 + Blue Component + 0.258823529412 + Color Space + Calibrated + Green Component + 0.227450980392 + Red Component + 0.219607843137 + + Foreground Color + + Alpha Component + 1 + Blue Component + 0.258823529412 + Color Space + Calibrated + Green Component + 0.227450980392 + Red Component + 0.219607843137 + + Link Color + + Alpha Component + 1 + Blue Component + 0.737254901961 + Color Space + Calibrated + Green Component + 0.517647058824 + Red Component + 0.00392156862745 + + Selected Text Color + + Alpha Component + 1 + Blue Component + 0.258823529412 + Color Space + Calibrated + Green Component + 0.227450980392 + Red Component + 0.219607843137 + + Selection Color + + Alpha Component + 1 + Blue Component + 1.0 + Color Space + Calibrated + Green Component + 0.807843137255 + Red Component + 0.749019607843 + + + \ No newline at end of file diff --git a/tools/ColorTool/schemes/campbell-legacy.ini b/tools/ColorTool/schemes/campbell-legacy.ini new file mode 100644 index 0000000000..0374bbb4e9 --- /dev/null +++ b/tools/ColorTool/schemes/campbell-legacy.ini @@ -0,0 +1,21 @@ +[table] +DARK_BLACK = 19,17,23 +DARK_BLUE = 6,54,222 +DARK_GREEN = 57,151,50 +DARK_CYAN = 48,151,168 +DARK_RED = 185,0,5 +DARK_MAGENTA = 141,2,180 +DARK_YELLOW = 187,182,0 +DARK_WHITE = 192,190,197 +BRIGHT_BLACK = 85,82,92 +BRIGHT_BLUE = 62,109,253 +BRIGHT_GREEN = 11,213,0 +BRIGHT_CYAN = 128,205,253 +BRIGHT_RED = 237,57,96 +BRIGHT_MAGENTA = 198,2,253 +BRIGHT_YELLOW = 255,247,149 +BRIGHT_WHITE = 240,239,241 + +[info] +name = Campbell-Legacy +author = paulcam \ No newline at end of file diff --git a/tools/ColorTool/schemes/campbell.ini b/tools/ColorTool/schemes/campbell.ini new file mode 100644 index 0000000000..6ce99f6f3b --- /dev/null +++ b/tools/ColorTool/schemes/campbell.ini @@ -0,0 +1,21 @@ +[table] +DARK_BLACK = 12,12,12 +DARK_BLUE = 0,55,218 +DARK_GREEN = 19,161,14 +DARK_CYAN = 58,150,221 +DARK_RED = 197,15,31 +DARK_MAGENTA = 136,23,152 +DARK_YELLOW = 193,156,0 +DARK_WHITE = 204,204,204 +BRIGHT_BLACK = 118,118,118 +BRIGHT_BLUE = 59,120,255 +BRIGHT_GREEN = 22,198,12 +BRIGHT_CYAN = 97,214,214 +BRIGHT_RED = 231,72,86 +BRIGHT_MAGENTA = 180,0,158 +BRIGHT_YELLOW = 249,241,165 +BRIGHT_WHITE = 242,242,242 + +[info] +name = Campbell +author = crloew \ No newline at end of file diff --git a/tools/ColorTool/schemes/cmd-legacy.ini b/tools/ColorTool/schemes/cmd-legacy.ini new file mode 100644 index 0000000000..39ee2f4de0 --- /dev/null +++ b/tools/ColorTool/schemes/cmd-legacy.ini @@ -0,0 +1,21 @@ +[table] +DARK_BLACK = 0, 0, 0 +DARK_BLUE = 0, 0, 128 +DARK_GREEN = 0, 128, 0 +DARK_CYAN = 0, 128, 128 +DARK_RED = 128, 0, 0 +DARK_MAGENTA = 128, 0, 128 +DARK_YELLOW = 128, 128, 0 +DARK_WHITE = 192, 192, 192 +BRIGHT_BLACK = 128, 128, 128 +BRIGHT_BLUE = 0, 0, 255 +BRIGHT_GREEN = 0, 255, 0 +BRIGHT_CYAN = 0, 255, 255 +BRIGHT_RED = 255, 0, 0 +BRIGHT_MAGENTA = 255, 0, 255 +BRIGHT_YELLOW = 255, 255, 0 +BRIGHT_WHITE = 255, 255, 255 + +[info] +name = cmd-legacy +author = unknown \ No newline at end of file diff --git a/tools/ColorTool/schemes/deuteranopia.itermcolors b/tools/ColorTool/schemes/deuteranopia.itermcolors new file mode 100644 index 0000000000..beb56369fb --- /dev/null +++ b/tools/ColorTool/schemes/deuteranopia.itermcolors @@ -0,0 +1,293 @@ + + + + + + Ansi 0 Color + + Color Space + sRGB + Blue Component + 0 + Green Component + 0 + Red Component + 0 + + Ansi 1 Color + + Color Space + sRGB + Blue Component + 0 + Green Component + 0.6 + Red Component + 0.6 + + Ansi 10 Color + + Color Space + sRGB + Blue Component + 1 + Green Component + 0 + Red Component + 0 + + Ansi 11 Color + + Color Space + sRGB + Blue Component + 0.7490196078431373 + Green Component + 1 + Red Component + 1 + + Ansi 12 Color + + Color Space + sRGB + Blue Component + 1 + Green Component + 0.5019607843137255 + Red Component + 0.5019607843137255 + + Ansi 13 Color + + Color Space + sRGB + Blue Component + 0.5019607843137255 + Green Component + 1 + Red Component + 1 + + Ansi 14 Color + + Color Space + sRGB + Blue Component + 1 + Green Component + 0.7490196078431373 + Red Component + 0.7490196078431373 + + Ansi 15 Color + + Color Space + sRGB + Blue Component + 1 + Green Component + 1 + Red Component + 1 + + Ansi 2 Color + + Color Space + sRGB + Blue Component + 0.6 + Green Component + 0 + Red Component + 0 + + Ansi 3 Color + + Color Space + sRGB + Blue Component + 0.45098039215686275 + Green Component + 0.6 + Red Component + 0.6 + + Ansi 4 Color + + Color Space + sRGB + Blue Component + 0.6 + Green Component + 0.30196078431372547 + Red Component + 0.30196078431372547 + + Ansi 5 Color + + Color Space + sRGB + Blue Component + 0.30196078431372547 + Green Component + 0.6 + Red Component + 0.6 + + Ansi 6 Color + + Color Space + sRGB + Blue Component + 0.6 + Green Component + 0.45098039215686275 + Red Component + 0.45098039215686275 + + Ansi 7 Color + + Color Space + sRGB + Blue Component + 0.7686274509803922 + Green Component + 0.7686274509803922 + Red Component + 0.7686274509803922 + + Ansi 8 Color + + Color Space + sRGB + Blue Component + 0.4235294117647059 + Green Component + 0.4235294117647059 + Red Component + 0.4235294117647059 + + Ansi 9 Color + + Color Space + sRGB + Blue Component + 0 + Green Component + 1 + Red Component + 1 + + Background Color + + Color Space + sRGB + Blue Component + 0 + Green Component + 0 + Red Component + 0 + + Bold Color + + Color Space + sRGB + Blue Component + 0.7686274509803922 + Green Component + 0.7686274509803922 + Red Component + 0.7686274509803922 + + Cursor Color + + Color Space + sRGB + Blue Component + 0.7686274509803922 + Green Component + 0.7686274509803922 + Red Component + 0.7686274509803922 + + Cursor Text Color + + Color Space + sRGB + Blue Component + 0 + Green Component + 0 + Red Component + 0 + + Foreground Color + + Color Space + sRGB + Blue Component + 0.7686274509803922 + Green Component + 0.7686274509803922 + Red Component + 0.7686274509803922 + + Selected Text Color + + Color Space + sRGB + Blue Component + 0.7686274509803922 + Green Component + 0.7686274509803922 + Red Component + 0.7686274509803922 + + Selection Color + + Color Space + sRGB + Blue Component + 0 + Green Component + 0 + Red Component + 0 + + + diff --git a/tools/ColorTool/schemes/solarized_dark.itermcolors b/tools/ColorTool/schemes/solarized_dark.itermcolors new file mode 100644 index 0000000000..4a727fb700 --- /dev/null +++ b/tools/ColorTool/schemes/solarized_dark.itermcolors @@ -0,0 +1,243 @@ + + + + + + Ansi 0 Color + + Blue Component + 0.19370138645172119 + Green Component + 0.15575926005840302 + Red Component + 0.0 + + Ansi 1 Color + + Blue Component + 0.14145714044570923 + Green Component + 0.10840655118227005 + Red Component + 0.81926977634429932 + + Ansi 10 Color + + Blue Component + 0.38298487663269043 + Green Component + 0.35665956139564514 + Red Component + 0.27671992778778076 + + Ansi 11 Color + + Blue Component + 0.43850564956665039 + Green Component + 0.40717673301696777 + Red Component + 0.32436618208885193 + + Ansi 12 Color + + Blue Component + 0.51685798168182373 + Green Component + 0.50962930917739868 + Red Component + 0.44058024883270264 + + Ansi 13 Color + + Blue Component + 0.72908437252044678 + Green Component + 0.33896297216415405 + Red Component + 0.34798634052276611 + + Ansi 14 Color + + Blue Component + 0.56363654136657715 + Green Component + 0.56485837697982788 + Red Component + 0.50599193572998047 + + Ansi 15 Color + + Blue Component + 0.86405980587005615 + Green Component + 0.95794391632080078 + Red Component + 0.98943418264389038 + + Ansi 2 Color + + Blue Component + 0.020208755508065224 + Green Component + 0.54115492105484009 + Red Component + 0.44977453351020813 + + Ansi 3 Color + + Blue Component + 0.023484811186790466 + Green Component + 0.46751424670219421 + Red Component + 0.64746475219726562 + + Ansi 4 Color + + Blue Component + 0.78231418132781982 + Green Component + 0.46265947818756104 + Red Component + 0.12754884362220764 + + Ansi 5 Color + + Blue Component + 0.43516635894775391 + Green Component + 0.10802463442087173 + Red Component + 0.77738940715789795 + + Ansi 6 Color + + Blue Component + 0.52502274513244629 + Green Component + 0.57082360982894897 + Red Component + 0.14679534733295441 + + Ansi 7 Color + + Blue Component + 0.79781103134155273 + Green Component + 0.89001238346099854 + Red Component + 0.91611063480377197 + + Ansi 8 Color + + Blue Component + 0.15170273184776306 + Green Component + 0.11783610284328461 + Red Component + 0.0 + + Ansi 9 Color + + Blue Component + 0.073530435562133789 + Green Component + 0.21325300633907318 + Red Component + 0.74176257848739624 + + Background Color + + Blue Component + 0.15170273184776306 + Green Component + 0.11783610284328461 + Red Component + 0.0 + + Bold Color + + Blue Component + 0.56363654136657715 + Green Component + 0.56485837697982788 + Red Component + 0.50599193572998047 + + Cursor Color + + Blue Component + 0.51685798168182373 + Green Component + 0.50962930917739868 + Red Component + 0.44058024883270264 + + Cursor Text Color + + Blue Component + 0.19370138645172119 + Green Component + 0.15575926005840302 + Red Component + 0.0 + + Foreground Color + + Blue Component + 0.51685798168182373 + Green Component + 0.50962930917739868 + Red Component + 0.44058024883270264 + + Selected Text Color + + Blue Component + 0.56363654136657715 + Green Component + 0.56485837697982788 + Red Component + 0.50599193572998047 + + Selection Color + + Blue Component + 0.19370138645172119 + Green Component + 0.15575926005840302 + Red Component + 0.0 + + + \ No newline at end of file diff --git a/tools/ColorTool/schemes/solarized_light.itermcolors b/tools/ColorTool/schemes/solarized_light.itermcolors new file mode 100644 index 0000000000..b39cc7714c --- /dev/null +++ b/tools/ColorTool/schemes/solarized_light.itermcolors @@ -0,0 +1,289 @@ + + + + + + Ansi 0 Color + + Color Space + sRGB + Blue Component + 0.8901960784313725 + Green Component + 0.9647058823529412 + Red Component + 0.9921568627450981 + + Ansi 1 Color + + Color Space + sRGB + Blue Component + 0.1843137254901961 + Green Component + 0.19607843137254902 + Red Component + 0.8627450980392157 + + Ansi 10 Color + + Color Space + sRGB + Blue Component + 0 + Green Component + 0.6 + Red Component + 0.5215686274509804 + + Ansi 11 Color + + Color Space + sRGB + Blue Component + 0 + Green Component + 0.5372549019607843 + Red Component + 0.7098039215686275 + + Ansi 12 Color + + Color Space + sRGB + Blue Component + 0.8235294117647058 + Green Component + 0.5450980392156862 + Red Component + 0.14901960784313725 + + Ansi 13 Color + + Color Space + sRGB + Blue Component + 0.7686274509803922 + Green Component + 0.44313725490196076 + Red Component + 0.4235294117647059 + + Ansi 14 Color + + Color Space + sRGB + Blue Component + 0.596078431372549 + Green Component + 0.6313725490196078 + Red Component + 0.16470588235294117 + + Ansi 15 Color + + Color Space + sRGB + Blue Component + 0.4588235294117647 + Green Component + 0.43137254901960786 + Red Component + 0.34509803921568627 + + Ansi 2 Color + + Color Space + sRGB + Blue Component + 0 + Green Component + 0.6 + Red Component + 0.5215686274509804 + + Ansi 3 Color + + Color Space + sRGB + Blue Component + 0 + Green Component + 0.5372549019607843 + Red Component + 0.7098039215686275 + + Ansi 4 Color + + Color Space + sRGB + Blue Component + 0.8235294117647058 + Green Component + 0.5450980392156862 + Red Component + 0.14901960784313725 + + Ansi 5 Color + + Color Space + sRGB + Blue Component + 0.7686274509803922 + Green Component + 0.44313725490196076 + Red Component + 0.4235294117647059 + + Ansi 6 Color + + Color Space + sRGB + Blue Component + 0.596078431372549 + Green Component + 0.6313725490196078 + Red Component + 0.16470588235294117 + + Ansi 7 Color + + Color Space + sRGB + Blue Component + 0.6313725490196078 + Green Component + 0.6313725490196078 + Red Component + 0.5764705882352941 + + Ansi 8 Color + + Color Space + sRGB + Blue Component + 0.5137254901960784 + Green Component + 0.4823529411764706 + Red Component + 0.396078431372549 + + Ansi 9 Color + + Color Space + sRGB + Blue Component + 0.1843137254901961 + Green Component + 0.19607843137254902 + Red Component + 0.8627450980392157 + + Background Color + + Color Space + sRGB + Blue Component + 0.8901960784313725 + Green Component + 0.9647058823529412 + Red Component + 0.9921568627450981 + + Bold Color + + Color Space + sRGB + Blue Component + 0.4588235294117647 + Green Component + 0.43137254901960786 + Red Component + 0.34509803921568627 + + Cursor Color + + Color Space + sRGB + Blue Component + 0.4588235294117647 + Green Component + 0.43137254901960786 + Red Component + 0.34509803921568627 + + Cursor Text Color + + Color Space + sRGB + Blue Component + 0.8901960784313725 + Green Component + 0.9647058823529412 + Red Component + 0.9921568627450981 + + Foreground Color + + Color Space + sRGB + Blue Component + 0.4588235294117647 + Green Component + 0.43137254901960786 + Red Component + 0.34509803921568627 + + Selected Text Color + + Color Space + sRGB + Blue Component + 0.4588235294117647 + Green Component + 0.43137254901960786 + Red Component + 0.34509803921568627 + + Selection Color + + Color Space + sRGB + Blue Component + 0.8901960784313725 + Green Component + 0.9647058823529412 + Red Component + 0.9921568627450981 + + + From a313826830707b132a20718b16caba351bd3cbab Mon Sep 17 00:00:00 2001 From: Jutta Klebe Date: Sat, 12 Aug 2017 14:18:31 +0200 Subject: [PATCH 02/89] Use invariant culture for parsing double values --- tools/ColorTool/ColorTool/XmlSchemeParser.cs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/tools/ColorTool/ColorTool/XmlSchemeParser.cs b/tools/ColorTool/ColorTool/XmlSchemeParser.cs index 7afea4d8d0..a28aea54e5 100644 --- a/tools/ColorTool/ColorTool/XmlSchemeParser.cs +++ b/tools/ColorTool/ColorTool/XmlSchemeParser.cs @@ -3,6 +3,7 @@ // Licensed under the terms described in the LICENSE file in the root of this project. // using System; +using System.Globalization; using System.Xml; using static ColorTool.ConsoleAPI; @@ -45,15 +46,15 @@ namespace ColorTool { if (c.InnerText == RED_KEY) { - r = (int)(255 * Convert.ToDouble(c.NextSibling.InnerText)); + r = (int)(255 * Convert.ToDouble(c.NextSibling.InnerText, CultureInfo.InvariantCulture)); } else if (c.InnerText == GREEN_KEY) { - g = (int)(255 * Convert.ToDouble(c.NextSibling.InnerText)); + g = (int)(255 * Convert.ToDouble(c.NextSibling.InnerText, CultureInfo.InvariantCulture)); } else if (c.InnerText == BLUE_KEY) { - b = (int)(255 * Convert.ToDouble(c.NextSibling.InnerText)); + b = (int)(255 * Convert.ToDouble(c.NextSibling.InnerText, CultureInfo.InvariantCulture)); } else { From b0d43f8067c1484698defda5862c4d08ca95b6ea Mon Sep 17 00:00:00 2001 From: Lachlan Picking Date: Sat, 12 Aug 2017 22:48:42 +1000 Subject: [PATCH 03/89] Add an option to print the colour table for the current scheme --- tools/ColorTool/ColorTool/Program.cs | 4 ++++ tools/ColorTool/ColorTool/Resources.resx | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/tools/ColorTool/ColorTool/Program.cs b/tools/ColorTool/ColorTool/Program.cs index 1f56047f22..476e5866ed 100644 --- a/tools/ColorTool/ColorTool/Program.cs +++ b/tools/ColorTool/ColorTool/Program.cs @@ -221,6 +221,10 @@ namespace ColorTool { switch (arg) { + case "-c": + case "--current": + PrintTable(); + return; case "-q": case "--quiet": quiteMode = true; diff --git a/tools/ColorTool/ColorTool/Resources.resx b/tools/ColorTool/ColorTool/Resources.resx index e999e0daab..7f369ffd6e 100644 --- a/tools/ColorTool/ColorTool/Resources.resx +++ b/tools/ColorTool/ColorTool/Resources.resx @@ -147,11 +147,11 @@ Arguments: If that fails, it will look for it as an .ini file color scheme. Options: -?, --help : Display this help message + -c, --current : Print the color table for the currently applied scheme -q, --quiet : Don't print the color table after applying -d, --defaults : Apply the scheme to only the defaults in the registry -b, --both : Apply the scheme to both the current console and the defaults. - -v, --version : Display the version number - + -v, --version : Display the version number Wrote selected scheme to the defaults. From c0f5c3e14979f82d74c23de25512a1509dc21341 Mon Sep 17 00:00:00 2001 From: Lachlan Picking Date: Sat, 12 Aug 2017 22:51:43 +1000 Subject: [PATCH 04/89] Update README --- tools/ColorTool/README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/ColorTool/README.md b/tools/ColorTool/README.md index c381a57961..ca04c44ae0 100644 --- a/tools/ColorTool/README.md +++ b/tools/ColorTool/README.md @@ -2,7 +2,7 @@ ``` Usage: - colortool.exe [options] ; + colortool.exe [options] ColorTool is a utility for helping to set the color palette of the Windows Console. By default, applies the colors in the specified .itermcolors or .ini file to the current console window. This does NOT save the properties automatically. For that, you'll need to open the properties sheet and hit "Ok". @@ -13,6 +13,7 @@ Arguments: If that fails, it will look for it as an .ini file color scheme. Options: -?, --help : Display this help message + -c, --current : Print the color table for the currently applied scheme -q, --quiet : Don't print the color table after applying -d, --defaults : Apply the scheme to only the defaults in the registry -b, --both : Apply the scheme to both the current console and the defaults. From 0a423074a33b7cbbee3b3f175a125f567c43f04f Mon Sep 17 00:00:00 2001 From: oising Date: Sat, 12 Aug 2017 14:22:08 -0400 Subject: [PATCH 05/89] retarget csproj from net47 to net46 --- tools/ColorTool/ColorTool/ColorTool.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/ColorTool/ColorTool/ColorTool.csproj b/tools/ColorTool/ColorTool/ColorTool.csproj index 4592e70a67..46974cc065 100644 --- a/tools/ColorTool/ColorTool/ColorTool.csproj +++ b/tools/ColorTool/ColorTool/ColorTool.csproj @@ -8,7 +8,7 @@ Exe ColorTool colortool - v4.7 + v4.6 512 true From a88194e8915d1e8572a43ddbfb770d3bd61ed8ad Mon Sep 17 00:00:00 2001 From: Daniel Podder Date: Sat, 12 Aug 2017 17:21:00 -0700 Subject: [PATCH 06/89] Default to msbuild.exe on PATH if found --- tools/ColorTool/build.bat | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tools/ColorTool/build.bat b/tools/ColorTool/build.bat index e39dc3d8e4..2b18d09b4f 100644 --- a/tools/ColorTool/build.bat +++ b/tools/ColorTool/build.bat @@ -2,6 +2,10 @@ rem Add path to MSBuild Binaries set MSBUILD=() +for /f "usebackq tokens=*" %%f in (`where.exe msbuild.exe 2^>nul`) do ( + set MSBUILD="%%~ff" + goto :FOUND_MSBUILD +) if exist "%ProgramFiles(x86)%\Microsoft Visual Studio\2017\Community\MSBuild\15.0\Bin\msbuild.exe" ( set MSBUILD="%ProgramFiles(x86)%\Microsoft Visual Studio\2017\Community\MSBuild\15.0\Bin\msbuild.exe" goto :FOUND_MSBUILD From 10d1f05c8d78a48c59b6598a3530e77f21820704 Mon Sep 17 00:00:00 2001 From: Xanthalas Date: Sun, 13 Aug 2017 11:13:18 +0100 Subject: [PATCH 07/89] Fix variable name (from quite to quiet). --- tools/ColorTool/ColorTool/Program.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/ColorTool/ColorTool/Program.cs b/tools/ColorTool/ColorTool/Program.cs index 1f56047f22..89caf4b842 100644 --- a/tools/ColorTool/ColorTool/Program.cs +++ b/tools/ColorTool/ColorTool/Program.cs @@ -80,7 +80,7 @@ namespace ColorTool DARK_WHITE }; - static bool quiteMode = false; + static bool quietMode = false; static bool setDefaults = false; static bool setProperties = true; @@ -189,7 +189,7 @@ namespace ColorTool } if (success) { - if (!quiteMode) + if (!quietMode) { PrintTable(); } @@ -223,7 +223,7 @@ namespace ColorTool { case "-q": case "--quiet": - quiteMode = true; + quietMode = true; break; case "-d": case "--defaults": From 7ed7650a6b7ed94fb019bcf6421a33d1de341d7d Mon Sep 17 00:00:00 2001 From: Christiaan Rakowski Date: Sun, 13 Aug 2017 22:23:57 +0200 Subject: [PATCH 08/89] Added support for using VS 2017 Build Tools --- tools/ColorTool/build.bat | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/tools/ColorTool/build.bat b/tools/ColorTool/build.bat index e39dc3d8e4..35cb0d30cb 100644 --- a/tools/ColorTool/build.bat +++ b/tools/ColorTool/build.bat @@ -18,6 +18,10 @@ if exist "%ProgramFiles%\Microsoft Visual Studio\2017\Enterprise\MSBuild\15.0\Bi set MSBUILD="%ProgramFiles%\Microsoft Visual Studio\2017\Enterprise\MSBuild\15.0\Bin\msbuild.exe" goto :FOUND_MSBUILD ) +if exist "%ProgramFiles(x86)%\Microsoft Visual Studio\2017\BuildTools\MSBuild\15.0\Bin\MSBuild.exe" ( + set MSBUILD="%ProgramFiles(x86)%\Microsoft Visual Studio\2017\BuildTools\MSBuild\15.0\Bin\MSBuild.exe" + goto :FOUND_MSBUILD +) if exist "%ProgramFiles(x86)%\MSBuild\14.0\bin" ( set MSBUILD="%ProgramFiles(x86)%\MSBuild\14.0\bin\msbuild.exe" goto :FOUND_MSBUILD @@ -30,7 +34,7 @@ if exist "%ProgramFiles%\MSBuild\14.0\bin" ( if %MSBUILD%==() ( echo "I couldn't find MSBuild on your PC. Make sure it's installed somewhere, and if it's not in the above if statements (in build.bat), add it." goto :EXIT -) +) :FOUND_MSBUILD set _MSBUILD_TARGET=Build set _MSBUILD_CONFIG=Debug @@ -47,7 +51,7 @@ shift goto :ARGS_LOOP :POST_ARGS_LOOP -%MSBUILD% %~dp0ColorTool.sln /t:%_MSBUILD_TARGET% /m /nr:true /p:Configuration=%_MSBUILD_CONFIG% +%MSBUILD% %~dp0ColorTool.sln /t:%_MSBUILD_TARGET% /m /nr:true /p:Configuration=%_MSBUILD_CONFIG% if (%ERRORLEVEL%) == (0) ( echo. From b1fb72f23783e7f5db134b17b107ab3ae9d3dcf7 Mon Sep 17 00:00:00 2001 From: Michael Niksa Date: Mon, 14 Aug 2017 12:31:11 -0700 Subject: [PATCH 09/89] Add build badge for color tool master. --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index b4516d98c4..657255adcc 100644 --- a/README.md +++ b/README.md @@ -8,3 +8,8 @@ Here you'll find assorted console tools in the `tools/` directory, such as the We will be monitoring and responding to issues as best we can. Please attempt to avoid filing duplicates of open or closed items when possible. + +## Build Status + +|---|---| +|tools/ColorTool|![](https://microsoft.visualstudio.com/_apis/public/build/definitions/c93e867a-8815-43c1-92c4-e7dd5404f1e1/17023/badge)| \ No newline at end of file From dd4f1fd296ed6dd1f5473a68be32c1d9f76efbba Mon Sep 17 00:00:00 2001 From: Michael Niksa Date: Mon, 14 Aug 2017 12:34:26 -0700 Subject: [PATCH 10/89] try to trigger github markdown for tables by removing end | --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 657255adcc..a96ba679d6 100644 --- a/README.md +++ b/README.md @@ -11,5 +11,6 @@ Please attempt to avoid filing duplicates of open or closed items when possible. ## Build Status -|---|---| -|tools/ColorTool|![](https://microsoft.visualstudio.com/_apis/public/build/definitions/c93e867a-8815-43c1-92c4-e7dd5404f1e1/17023/badge)| \ No newline at end of file + +---|--- +tools/ColorTool|![](https://microsoft.visualstudio.com/_apis/public/build/definitions/c93e867a-8815-43c1-92c4-e7dd5404f1e1/17023/badge) \ No newline at end of file From 27fa917ada0ba8dbb685a2408a443630626b453d Mon Sep 17 00:00:00 2001 From: Michael Niksa Date: Mon, 14 Aug 2017 12:35:23 -0700 Subject: [PATCH 11/89] Add a table header and see if *that* triggers GitHub to make a markdown table. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a96ba679d6..d54407e5a8 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,6 @@ Please attempt to avoid filing duplicates of open or closed items when possible. ## Build Status - +Project|Build Status ---|--- tools/ColorTool|![](https://microsoft.visualstudio.com/_apis/public/build/definitions/c93e867a-8815-43c1-92c4-e7dd5404f1e1/17023/badge) \ No newline at end of file From 067cf3a29bbbbc4d9ba1c540fe7719c3f0d5249a Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Mon, 14 Aug 2017 13:29:39 -0700 Subject: [PATCH 12/89] Add a switch for exporting settings As suggested by #6 --- tools/ColorTool/ColorTool/IniSchemeParser.cs | 2 +- tools/ColorTool/ColorTool/Program.cs | 52 ++++++++++++++++++- .../ColorTool/ColorTool/Resources.Designer.cs | 9 ++++ tools/ColorTool/ColorTool/Resources.resx | 7 ++- 4 files changed, 66 insertions(+), 4 deletions(-) diff --git a/tools/ColorTool/ColorTool/IniSchemeParser.cs b/tools/ColorTool/ColorTool/IniSchemeParser.cs index 3b1789f57c..224b296f46 100644 --- a/tools/ColorTool/ColorTool/IniSchemeParser.cs +++ b/tools/ColorTool/ColorTool/IniSchemeParser.cs @@ -17,7 +17,7 @@ namespace ColorTool private static extern int GetPrivateProfileString(string section, string key, string def, StringBuilder retVal, int size, string filePath); // These are in Windows Color table order - BRG, not RGB. - static string[] COLOR_NAMES = { + public static string[] COLOR_NAMES = { "DARK_BLACK", "DARK_BLUE", "DARK_GREEN", diff --git a/tools/ColorTool/ColorTool/Program.cs b/tools/ColorTool/ColorTool/Program.cs index b2a5002ebe..6399729d8c 100644 --- a/tools/ColorTool/ColorTool/Program.cs +++ b/tools/ColorTool/ColorTool/Program.cs @@ -89,6 +89,11 @@ namespace ColorTool Console.WriteLine(Resources.Usage); } + static void OutputUsage() + { + Console.WriteLine(Resources.OutputUsage); + } + static void Version() { //System.Reflection.Assembly.GetEntryAssembly(); @@ -196,6 +201,7 @@ namespace ColorTool } return success; } + static bool SetDefaults(uint[] colorTable) { RegistryKey consoleKey = Registry.CurrentUser.OpenSubKey("Console", true); @@ -208,6 +214,37 @@ namespace ColorTool return true; } + static bool ExportCurrentAsIni(string outputPath) + { + CONSOLE_SCREEN_BUFFER_INFO_EX csbiex = CONSOLE_SCREEN_BUFFER_INFO_EX.Create(); + int STD_OUTPUT_HANDLE = -11; + IntPtr hOut = GetStdHandle(STD_OUTPUT_HANDLE); + bool success = GetConsoleScreenBufferInfoEx(hOut, ref csbiex); + if (success) + { + using (System.IO.StreamWriter file = new System.IO.StreamWriter(outputPath)) + { + file.WriteLine("[table]"); + for (int i = 0; i < 16; i++) + { + string line = IniSchemeParser.COLOR_NAMES[i]; + line += " = "; + uint color = csbiex.ColorTable[i]; + uint r = color & (0x000000ff); + uint g = (color & (0x0000ff00)) >> 8; + uint b = (color & (0x00ff0000)) >> 16; + line += r + "," + g + "," + b; + file.WriteLine(line); + } + } + } + else + { + Console.WriteLine("Failed to get conosle information."); + } + return success; + } + static void Main(string[] args) { @@ -216,9 +253,9 @@ namespace ColorTool Usage(); return; } - - foreach (string arg in args) + for (int i = 0; i < args.Length; i++) { + string arg = args[i]; switch (arg) { case "-c": @@ -247,6 +284,17 @@ namespace ColorTool case "--version": Version(); return; + case "-o": + case "--output": + if (i+1 < args.Length) + { + ExportCurrentAsIni(args[i + 1]); + } + else + { + OutputUsage(); + } + return; default: break; } diff --git a/tools/ColorTool/ColorTool/Resources.Designer.cs b/tools/ColorTool/ColorTool/Resources.Designer.cs index e053d6d114..379c408f0b 100644 --- a/tools/ColorTool/ColorTool/Resources.Designer.cs +++ b/tools/ColorTool/ColorTool/Resources.Designer.cs @@ -98,6 +98,15 @@ namespace ColorTool { } } + /// + /// Looks up a localized string similar to Usage: colortool -o <filename>. + /// + public static string OutputUsage { + get { + return ResourceManager.GetString("OutputUsage", resourceCulture); + } + } + /// /// Looks up a localized string similar to Could not find or load "{0}". /// diff --git a/tools/ColorTool/ColorTool/Resources.resx b/tools/ColorTool/ColorTool/Resources.resx index 7f369ffd6e..d9b0420ab4 100644 --- a/tools/ColorTool/ColorTool/Resources.resx +++ b/tools/ColorTool/ColorTool/Resources.resx @@ -131,6 +131,9 @@ Invalid scheme - did not find 16 colors + + Usage: colortool -o <filename> + Could not find or load "{0}" @@ -151,7 +154,9 @@ Options: -q, --quiet : Don't print the color table after applying -d, --defaults : Apply the scheme to only the defaults in the registry -b, --both : Apply the scheme to both the current console and the defaults. - -v, --version : Display the version number + -v, --version : Display the version number + -o, --output <filename> : output the current color table to an file (in .ini format) + Wrote selected scheme to the defaults. From 4964aad780bc58b8f6ec4c049ea388e3dc61b042 Mon Sep 17 00:00:00 2001 From: Michael Ratanapintha Date: Mon, 14 Aug 2017 15:11:46 -0700 Subject: [PATCH 13/89] ColorTool: Restore old console colors after printing the console table Unfortunately, when you run `.\colortool.exe --current`, you might notice that the color of the prompt printed after the program finishes is slightly different from what it was before you ran the program. This changelist fixes the issue by restoring the old console colors after the program finishes printing the color table. Testing: manual --- tools/ColorTool/ColorTool/Program.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tools/ColorTool/ColorTool/Program.cs b/tools/ColorTool/ColorTool/Program.cs index b2a5002ebe..d65507d514 100644 --- a/tools/ColorTool/ColorTool/Program.cs +++ b/tools/ColorTool/ColorTool/Program.cs @@ -170,6 +170,10 @@ namespace ColorTool } Console.Write("\n"); + + // Reset foreground and background colors + Console.ForegroundColor = currentForeground; + Console.BackgroundColor = currentBackground; } static bool SetProperties(uint[] colorTable) From f757ecaa29e409445c60aa84e66813c47a660e4c Mon Sep 17 00:00:00 2001 From: Michael Ratanapintha Date: Mon, 14 Aug 2017 21:49:42 -0700 Subject: [PATCH 14/89] ColorTool: Fix the included all.bat batch file This batch file doesn't work if you use build.bat to build the program, as all.bat looks for ct.exe rather than colortool.exe. Fortunately, fixing the batch file is almost as easy as working around its bug manually. --- tools/ColorTool/all.bat | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/ColorTool/all.bat b/tools/ColorTool/all.bat index 8602076c42..8161cba5ed 100644 --- a/tools/ColorTool/all.bat +++ b/tools/ColorTool/all.bat @@ -9,6 +9,6 @@ rem All of the previously viewed tables will display the current scheme's co for %%i in (schemes\*) do ( echo %%i - ct.exe "%%i" + .\colortool.exe "%%i" pause -) \ No newline at end of file +) From c12f5a9157812f2161ee8dd82ee9f13421094970 Mon Sep 17 00:00:00 2001 From: Lachlan Picking Date: Fri, 18 Aug 2017 10:49:01 +1000 Subject: [PATCH 15/89] Fix typos in colortool help message and README --- tools/ColorTool/ColorTool/Resources.resx | 2 +- tools/ColorTool/README.md | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/tools/ColorTool/ColorTool/Resources.resx b/tools/ColorTool/ColorTool/Resources.resx index 7f369ffd6e..503cdd2f8f 100644 --- a/tools/ColorTool/ColorTool/Resources.resx +++ b/tools/ColorTool/ColorTool/Resources.resx @@ -141,7 +141,7 @@ ColorTool is a utility for helping to set the color palette of the Windows Conso By default, applies the colors in the specified .itermcolors or .ini file to the current console window. This does NOT save the properties automatically. For that, you'll need to open the properties sheet and hit "Ok". Included should be a `schemes/` directory with a selection of schemes of both formats for examples. -Feel free to add your own prefered scheme to that directory. +Feel free to add your own preferred scheme to that directory. Arguments: <schemename>: The name of a color scheme. ct will try to first load it as an .itermcolors color scheme. If that fails, it will look for it as an .ini file color scheme. diff --git a/tools/ColorTool/README.md b/tools/ColorTool/README.md index ca04c44ae0..5ebdd1ce67 100644 --- a/tools/ColorTool/README.md +++ b/tools/ColorTool/README.md @@ -7,7 +7,7 @@ ColorTool is a utility for helping to set the color palette of the Windows Conso By default, applies the colors in the specified .itermcolors or .ini file to the current console window. This does NOT save the properties automatically. For that, you'll need to open the properties sheet and hit "Ok". Included should be a `schemes/` directory with a selection of schemes of both formats for examples. -Feel free to add your own prefered scheme to that directory. +Feel free to add your own preferred scheme to that directory. Arguments: : The name of a color scheme. ct will try to first load it as an .itermcolors color scheme. If that fails, it will look for it as an .ini file color scheme. @@ -32,13 +32,13 @@ Options: ## Adding Schemes - You can also add color schemes to the colortool easily. Take any existing scheme in `.itemcolors` format, and paste it in the `schemes/` directory. + You can also add color schemes to the colortool easily. Take any existing scheme in `.itermcolors` format, and paste it in the `schemes/` directory. - I recommend the excellent [iTerm2-Color-Schemes](https://github.com/mbadolato/iTerm2-Color-Schemes) repo, which has TONS of schemes to chose from, and previews. + I recommend the excellent [iTerm2-Color-Schemes](https://github.com/mbadolato/iTerm2-Color-Schemes) repo, which has TONS of schemes to choose from, and previews. ## Building - Either build with Visual Studio, or use the included `build.bat` from the commandline to try and auto-detect your msbuild version. + Either build with Visual Studio, or use the included `build.bat` from the command line to try and auto-detect your msbuild version. ## Contributing From 9bd6053664fda6a96cc7047b82274315f7601287 Mon Sep 17 00:00:00 2001 From: Taylor Southwick Date: Mon, 28 Aug 2017 10:06:45 -0700 Subject: [PATCH 16/89] Dynamically generate list of parsers --- tools/ColorTool/ColorTool/ISchemeParser.cs | 2 ++ tools/ColorTool/ColorTool/IniSchemeParser.cs | 9 ++++++--- tools/ColorTool/ColorTool/Program.cs | 20 +++++++++++++------ .../ColorTool/ColorTool/Resources.Designer.cs | 4 ++-- tools/ColorTool/ColorTool/Resources.resx | 5 ++++- tools/ColorTool/ColorTool/XmlSchemeParser.cs | 2 ++ 6 files changed, 30 insertions(+), 12 deletions(-) diff --git a/tools/ColorTool/ColorTool/ISchemeParser.cs b/tools/ColorTool/ColorTool/ISchemeParser.cs index df8cfcec2d..150ca35cca 100644 --- a/tools/ColorTool/ColorTool/ISchemeParser.cs +++ b/tools/ColorTool/ColorTool/ISchemeParser.cs @@ -7,6 +7,8 @@ namespace ColorTool { interface ISchemeParser { + string Name { get; } + uint[] ParseScheme(string schemeName); } } diff --git a/tools/ColorTool/ColorTool/IniSchemeParser.cs b/tools/ColorTool/ColorTool/IniSchemeParser.cs index 3b1789f57c..80ea47f13c 100644 --- a/tools/ColorTool/ColorTool/IniSchemeParser.cs +++ b/tools/ColorTool/ColorTool/IniSchemeParser.cs @@ -16,7 +16,7 @@ namespace ColorTool [DllImport("kernel32")] private static extern int GetPrivateProfileString(string section, string key, string def, StringBuilder retVal, int size, string filePath); - // These are in Windows Color table order - BRG, not RGB. + // These are in Windows Color table order - BRG, not RGB. static string[] COLOR_NAMES = { "DARK_BLACK", "DARK_BLUE", @@ -36,6 +36,8 @@ namespace ColorTool "BRIGHT_WHITE" }; + public string Name => "INI File Parser"; + static uint ParseHex(string arg) { System.Drawing.Color col = System.Drawing.ColorTranslator.FromHtml(arg); @@ -44,11 +46,12 @@ namespace ColorTool static uint ParseRgb(string arg) { - int[] components = { 0, 0, 0}; + int[] components = { 0, 0, 0 }; string[] args = arg.Split(','); if (args.Length != components.Length) throw new Exception("Invalid color format \"" + arg + "\""); if (args.Length != 3) throw new Exception("Invalid color format \"" + arg + "\""); - for (int i = 0; i < args.Length; i++){ + for (int i = 0; i < args.Length; i++) + { components[i] = Int32.Parse(args[i]); } diff --git a/tools/ColorTool/ColorTool/Program.cs b/tools/ColorTool/ColorTool/Program.cs index d65507d514..00c0a5d087 100644 --- a/tools/ColorTool/ColorTool/Program.cs +++ b/tools/ColorTool/ColorTool/Program.cs @@ -3,10 +3,12 @@ // Licensed under the terms described in the LICENSE file in the root of this project. // -using System; -using static ColorTool.ConsoleAPI; using Microsoft.Win32; +using System; +using System.Collections.Generic; +using System.Linq; using System.Reflection; +using static ColorTool.ConsoleAPI; namespace ColorTool { @@ -86,7 +88,8 @@ namespace ColorTool static void Usage() { - Console.WriteLine(Resources.Usage); + Console.WriteLine(Resources.Usage, + string.Join($"{Environment.NewLine} ", GetParsers().Select(p => p.Name))); } static void Version() @@ -136,7 +139,7 @@ namespace ColorTool "46m", "47m" }; - + Console.Write("\t"); for (int bg = 0; bg < BGs.Length; bg++) { @@ -259,8 +262,7 @@ namespace ColorTool string schemeName = args[args.Length - 1]; uint[] colorTable = null; - ISchemeParser[] parsers = { new XmlSchemeParser(), new IniSchemeParser() }; - foreach (var parser in parsers) + foreach (var parser in GetParsers()) { uint[] table = parser.ParseScheme(schemeName); if (table != null) @@ -286,5 +288,11 @@ namespace ColorTool } } + private static IEnumerable GetParsers() + { + return typeof(Program).Assembly.GetTypes() + .Where(t => !t.IsAbstract && typeof(ISchemeParser).IsAssignableFrom(t)) + .Select(t => (ISchemeParser)Activator.CreateInstance(t)); + } } } diff --git a/tools/ColorTool/ColorTool/Resources.Designer.cs b/tools/ColorTool/ColorTool/Resources.Designer.cs index e053d6d114..a609f9af4a 100644 --- a/tools/ColorTool/ColorTool/Resources.Designer.cs +++ b/tools/ColorTool/ColorTool/Resources.Designer.cs @@ -19,7 +19,7 @@ namespace ColorTool { // class via a tool like ResGen or Visual Studio. // To add or remove a member, edit your .ResX file then rerun ResGen // with the /str option, or rebuild your VS project. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] public class Resources { @@ -114,7 +114,7 @@ namespace ColorTool { ///By default, applies the colors in the specified .itermcolors or .ini file to the current console window. ///This does NOT save the properties automatically. For that, you'll need to open the properties sheet and hit "Ok". ///Included should be a `schemes/` directory with a selection of schemes of both formats for examples. - ///Feel free to add your own prefered scheme to that direc [rest of string was truncated]";. + ///Feel free to add your own preferred scheme to that dire [rest of string was truncated]";. /// public static string Usage { get { diff --git a/tools/ColorTool/ColorTool/Resources.resx b/tools/ColorTool/ColorTool/Resources.resx index 503cdd2f8f..dc5bee9ed3 100644 --- a/tools/ColorTool/ColorTool/Resources.resx +++ b/tools/ColorTool/ColorTool/Resources.resx @@ -151,7 +151,10 @@ Options: -q, --quiet : Don't print the color table after applying -d, --defaults : Apply the scheme to only the defaults in the registry -b, --both : Apply the scheme to both the current console and the defaults. - -v, --version : Display the version number + -v, --version : Display the version number + +Available importers: + {0} Wrote selected scheme to the defaults. diff --git a/tools/ColorTool/ColorTool/XmlSchemeParser.cs b/tools/ColorTool/ColorTool/XmlSchemeParser.cs index a28aea54e5..d1b1424b1b 100644 --- a/tools/ColorTool/ColorTool/XmlSchemeParser.cs +++ b/tools/ColorTool/ColorTool/XmlSchemeParser.cs @@ -34,6 +34,8 @@ namespace ColorTool static string GREEN_KEY = "Green Component"; static string BLUE_KEY = "Blue Component"; + public string Name => "iTerm Parser"; + static bool parseRgbFromXml(XmlNode components, ref uint rgb) { int r = -1; From 7ae6ee6e00e5d31b2637a848fa7dc4ba28d9ba5b Mon Sep 17 00:00:00 2001 From: Taylor Southwick Date: Mon, 28 Aug 2017 10:20:25 -0700 Subject: [PATCH 17/89] Use simpler csproj format --- tools/ColorTool/ColorTool/ColorTool.csproj | 71 ++----------------- .../ColorTool/Properties/AssemblyInfo.cs | 34 --------- 2 files changed, 5 insertions(+), 100 deletions(-) delete mode 100644 tools/ColorTool/ColorTool/Properties/AssemblyInfo.cs diff --git a/tools/ColorTool/ColorTool/ColorTool.csproj b/tools/ColorTool/ColorTool/ColorTool.csproj index 46974cc065..74cfdb4aeb 100644 --- a/tools/ColorTool/ColorTool/ColorTool.csproj +++ b/tools/ColorTool/ColorTool/ColorTool.csproj @@ -1,69 +1,8 @@ - - - + + - Debug - AnyCPU - {97F4550F-5775-4E40-8ECF-A03479884120} Exe - ColorTool - colortool - v4.6 - 512 - true - + net46 - - AnyCPU - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - AnyCPU - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - - - - - - - - - - - - - - - - - - True - True - Resources.resx - - - - - - - - - PublicResXFileCodeGenerator - Resources.Designer.cs - - - - \ No newline at end of file + + diff --git a/tools/ColorTool/ColorTool/Properties/AssemblyInfo.cs b/tools/ColorTool/ColorTool/Properties/AssemblyInfo.cs deleted file mode 100644 index d0698c57f4..0000000000 --- a/tools/ColorTool/ColorTool/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,34 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("ColorTool")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("ColorTool")] -[assembly: AssemblyCopyright("Copyright © 2017")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("97f4550f-5775-4e40-8ecf-a03479884120")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -[assembly: AssemblyVersion("1.0.*")] From fe7a2d00fa308794a7158adf05dbcdd77b045150 Mon Sep 17 00:00:00 2001 From: Hugo van Rijswijk Date: Mon, 11 Sep 2017 20:19:33 +0200 Subject: [PATCH 18/89] Add option to view available color schemes --- tools/ColorTool/ColorTool/ConsoleAPI.cs | 6 ++ tools/ColorTool/ColorTool/Program.cs | 81 ++++++++++++++++++++---- tools/ColorTool/ColorTool/Resources.resx | 1 + tools/ColorTool/README.md | 1 + 4 files changed, 78 insertions(+), 11 deletions(-) diff --git a/tools/ColorTool/ColorTool/ConsoleAPI.cs b/tools/ColorTool/ColorTool/ConsoleAPI.cs index 4e438111f0..56cc115d69 100644 --- a/tools/ColorTool/ColorTool/ConsoleAPI.cs +++ b/tools/ColorTool/ColorTool/ConsoleAPI.cs @@ -56,6 +56,12 @@ namespace ColorTool [DllImport("kernel32.dll", SetLastError = true)] public static extern bool SetConsoleScreenBufferInfoEx(IntPtr ConsoleOutput, ref CONSOLE_SCREEN_BUFFER_INFO_EX ConsoleScreenBufferInfoEx); + + [DllImport("kernel32.dll", SetLastError = true)] + public static extern bool SetConsoleMode(IntPtr hConsoleHandle, int mode); + + [DllImport("kernel32.dll", SetLastError = true)] + public static extern bool GetConsoleMode(IntPtr handle, out int mode); //////////////////////////////////////////////////////////////////////// public static uint RGB(int r, int g, int b) diff --git a/tools/ColorTool/ColorTool/Program.cs b/tools/ColorTool/ColorTool/Program.cs index d65507d514..0b94b9d5d5 100644 --- a/tools/ColorTool/ColorTool/Program.cs +++ b/tools/ColorTool/ColorTool/Program.cs @@ -4,9 +4,13 @@ // using System; +using System.Drawing; +using System.IO; +using System.Linq; using static ColorTool.ConsoleAPI; using Microsoft.Win32; using System.Reflection; +using System.Runtime.InteropServices; namespace ColorTool { @@ -176,6 +180,54 @@ namespace ColorTool Console.BackgroundColor = currentBackground; } + static void PrintSchemes() + { + if (Directory.Exists("./schemes")) + { + IntPtr handle = GetStdHandle(-11); + GetConsoleMode(handle, out var mode); + SetConsoleMode(handle, mode | 0x4); + + int consoleWidth = Console.WindowWidth; + string fgText = " gYw "; + foreach (string schemeName in Directory.GetFiles("./schemes/").Select(Path.GetFileName)) + { + uint[] colorTable = GetSchemeUints(schemeName); + if (colorTable != null) + { + string colors = string.Empty; + for (var index = 0; index < 8; index++) + { + uint t = colorTable[index]; + var color = UIntToColor(t); + // Set the background color to the color in the scheme, plus some text to show how it looks + colors += $"\x1b[48;2;{color.R};{color.G};{color.B}m{fgText}"; + } + // Align scheme colors right, or on newline if it doesn't fit + int schemeTextLength = fgText.Length * 8; + int bufferLength = consoleWidth - (schemeName.Length + schemeTextLength); + + string bufferString = bufferLength >= 0 + ? new string(' ', bufferLength) + : "\n" + new string(' ', consoleWidth - schemeTextLength); + + string outputString = schemeName + bufferString + colors; + Console.WriteLine(outputString); + Console.ResetColor(); + } + } + } + } + + private static Color UIntToColor(uint color) + { + byte a = (byte)(color >> 24); + byte r = (byte)(color >> 16); + byte g = (byte)(color >> 8); + byte b = (byte)(color >> 0); + return Color.FromArgb(a, r, g, b); + } + static bool SetProperties(uint[] colorTable) { CONSOLE_SCREEN_BUFFER_INFO_EX csbiex = CONSOLE_SCREEN_BUFFER_INFO_EX.Create(); @@ -251,6 +303,10 @@ namespace ColorTool case "--version": Version(); return; + case "-s": + case "--schemes": + PrintSchemes(); + return; default: break; } @@ -258,17 +314,7 @@ namespace ColorTool string schemeName = args[args.Length - 1]; - uint[] colorTable = null; - ISchemeParser[] parsers = { new XmlSchemeParser(), new IniSchemeParser() }; - foreach (var parser in parsers) - { - uint[] table = parser.ParseScheme(schemeName); - if (table != null) - { - colorTable = table; - break; - } - } + uint[] colorTable = GetSchemeUints(schemeName); if (colorTable == null) { @@ -286,5 +332,18 @@ namespace ColorTool } } + private static uint[] GetSchemeUints(string schemeName) + { + ISchemeParser[] parsers = {new XmlSchemeParser(), new IniSchemeParser()}; + foreach (var parser in parsers) + { + uint[] table = parser.ParseScheme(schemeName); + if (table != null) + { + return table; + } + } + return null; + } } } diff --git a/tools/ColorTool/ColorTool/Resources.resx b/tools/ColorTool/ColorTool/Resources.resx index 503cdd2f8f..63a4875028 100644 --- a/tools/ColorTool/ColorTool/Resources.resx +++ b/tools/ColorTool/ColorTool/Resources.resx @@ -151,6 +151,7 @@ Options: -q, --quiet : Don't print the color table after applying -d, --defaults : Apply the scheme to only the defaults in the registry -b, --both : Apply the scheme to both the current console and the defaults. + -s, --schemes : Displays all available schemes -v, --version : Display the version number diff --git a/tools/ColorTool/README.md b/tools/ColorTool/README.md index 5ebdd1ce67..fba2abbae8 100644 --- a/tools/ColorTool/README.md +++ b/tools/ColorTool/README.md @@ -17,6 +17,7 @@ Options: -q, --quiet : Don't print the color table after applying -d, --defaults : Apply the scheme to only the defaults in the registry -b, --both : Apply the scheme to both the current console and the defaults. + -s, --schemes : Display all available schemes -v, --version : Display the version number ``` From a8c1100bfaf1981ebefc715f42ac099339b3368d Mon Sep 17 00:00:00 2001 From: Rich Turner Date: Mon, 11 Sep 2017 14:46:11 -0700 Subject: [PATCH 19/89] Created --- ISSUE_TEMPLATE.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 ISSUE_TEMPLATE.md diff --git a/ISSUE_TEMPLATE.md b/ISSUE_TEMPLATE.md new file mode 100644 index 0000000000..626b5a6cae --- /dev/null +++ b/ISSUE_TEMPLATE.md @@ -0,0 +1,13 @@ +This bug-tracker is monitored by Windows Console development team and other technical types. **We like detail!** + +If you have a feature request, please post to [the UserVoice](https://wpdev.uservoice.com/forums/266908). + +> **Important: When reporting BSODs or security issues, DO NOT attach memory dumps, logs, or traces to Github issues**. Instead, send dumps/traces to secure@microsoft.com, referencing the GitHub bug number. + +Please use this form and describe your issue, concisely but precisely, with as much detail as possible + +* Your Windows build number: (Type `ver` at a Windows Command Prompt) + +* What you're doing and what's happening: (Copy & paste specific commands and their output, or include screen shots) + +* What's wrong / what should be happening instead: From e9d52f7f0f6a6b40f5d7548068c09f0304dc89b8 Mon Sep 17 00:00:00 2001 From: Rich Turner Date: Mon, 11 Sep 2017 14:49:09 -0700 Subject: [PATCH 20/89] Update ISSUE_TEMPLATE.md --- ISSUE_TEMPLATE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ISSUE_TEMPLATE.md b/ISSUE_TEMPLATE.md index 626b5a6cae..8b82efec1d 100644 --- a/ISSUE_TEMPLATE.md +++ b/ISSUE_TEMPLATE.md @@ -2,7 +2,7 @@ This bug-tracker is monitored by Windows Console development team and other tech If you have a feature request, please post to [the UserVoice](https://wpdev.uservoice.com/forums/266908). -> **Important: When reporting BSODs or security issues, DO NOT attach memory dumps, logs, or traces to Github issues**. Instead, send dumps/traces to secure@microsoft.com, referencing the GitHub bug number. +> **Important: When reporting BSODs or security issues, DO NOT attach memory dumps, logs, or traces to Github issues**. Instead, send dumps/traces to secure@microsoft.com, referencing this GitHub issue. Please use this form and describe your issue, concisely but precisely, with as much detail as possible From f052ca5dc420b7604f0227419f6cacc05ff7c0da Mon Sep 17 00:00:00 2001 From: Rich Turner Date: Sun, 8 Oct 2017 14:30:31 -0700 Subject: [PATCH 21/89] Updated readme --- README.md | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index d54407e5a8..83e0796cf3 100644 --- a/README.md +++ b/README.md @@ -1,16 +1,23 @@ -# Console - -This is the Official Windows Console Github Repo. -Here you'll find assorted console tools in the `tools/` directory, such as the - [ColorTool](https://github.com/Microsoft/Console/tree/master/tools/ColorTool). +# Welcome to the official Windows Console issues & samples repo! ## Issues -We will be monitoring and responding to issues as best we can. -Please attempt to avoid filing duplicates of open or closed items when possible. +This is not a formal support channel and that support is offered on a best-effort basis. However, this repo is actively monitored by the Windows Console engineering team who love to receive issue reports containing as much detail as possible, especially issues containing repro-steps, and screenshots :) -## Build Status +### Code of Conduct +This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact opencode@microsoft.com with any additional questions or comments. + +In addition, the team reserve the right to actively manage issues, closing duplicates or resolved issues, etc., and would appreciate it if you would avoid creating duplicates of existing items by searching issues _before_ filing a new issue. + +We'll monitor and respond to issues as best we can. Your patience is appreciated! + +## Tools & Samples +You'll also find assorted Console tools, samples, including the following: + +* [ColorTool](https://github.com/Microsoft/Console/tree/master/tools/ColorTool). + +### Tool Build Status Project|Build Status ---|--- -tools/ColorTool|![](https://microsoft.visualstudio.com/_apis/public/build/definitions/c93e867a-8815-43c1-92c4-e7dd5404f1e1/17023/badge) \ No newline at end of file +tools/ColorTool|![](https://microsoft.visualstudio.com/_apis/public/build/definitions/c93e867a-8815-43c1-92c4-e7dd5404f1e1/17023/badge) From dc9cab01cd210728de0ef110071fa80fd4c7fcf3 Mon Sep 17 00:00:00 2001 From: Rich Turner Date: Sun, 8 Oct 2017 14:34:48 -0700 Subject: [PATCH 22/89] Update README.md --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 83e0796cf3..7beff4be75 100644 --- a/README.md +++ b/README.md @@ -2,15 +2,15 @@ ## Issues -This is not a formal support channel and that support is offered on a best-effort basis. However, this repo is actively monitored by the Windows Console engineering team who love to receive issue reports containing as much detail as possible, especially issues containing repro-steps, and screenshots :) +This repo is monitored by the Windows Console engineering team, and provides a best-effort, informal support option for the community. Your patience is appreciated! + +The Windows Console engineering team greatly appreciate issues containing concise, detailed issues containing repro-steps, and screenshots where appropriate :) ### Code of Conduct This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact opencode@microsoft.com with any additional questions or comments. In addition, the team reserve the right to actively manage issues, closing duplicates or resolved issues, etc., and would appreciate it if you would avoid creating duplicates of existing items by searching issues _before_ filing a new issue. -We'll monitor and respond to issues as best we can. Your patience is appreciated! - ## Tools & Samples You'll also find assorted Console tools, samples, including the following: From 889e19a05acce4ab7c3c62b15ec354b57f037093 Mon Sep 17 00:00:00 2001 From: Bjarke Lindberg Date: Fri, 13 Oct 2017 11:03:00 +0200 Subject: [PATCH 23/89] Check for VS 2017 Professional in build.bat --- tools/ColorTool/build.bat | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tools/ColorTool/build.bat b/tools/ColorTool/build.bat index f21d2faef9..3a6a28e017 100644 --- a/tools/ColorTool/build.bat +++ b/tools/ColorTool/build.bat @@ -14,6 +14,14 @@ if exist "%ProgramFiles%\Microsoft Visual Studio\2017\Community\MSBuild\15.0\Bin set MSBUILD="%ProgramFiles%\Microsoft Visual Studio\2017\Community\MSBuild\15.0\Bin\msbuild.exe" goto :FOUND_MSBUILD ) +if exist "%ProgramFiles(x86)%\Microsoft Visual Studio\2017\Professional\MSBuild\15.0\Bin\msbuild.exe" ( + set MSBUILD="%ProgramFiles(x86)%\Microsoft Visual Studio\2017\Professional\MSBuild\15.0\Bin\msbuild.exe" + goto :FOUND_MSBUILD +) +if exist "%ProgramFiles%\Microsoft Visual Studio\2017\Professional\MSBuild\15.0\Bin\msbuild.exe" ( + set MSBUILD="%ProgramFiles%\Microsoft Visual Studio\2017\Professional\MSBuild\15.0\Bin\msbuild.exe" + goto :FOUND_MSBUILD +) if exist "%ProgramFiles(x86)%\Microsoft Visual Studio\2017\Enterprise\MSBuild\15.0\Bin\msbuild.exe" ( set MSBUILD="%ProgramFiles(x86)%\Microsoft Visual Studio\2017\Enterprise\MSBuild\15.0\Bin\msbuild.exe" goto :FOUND_MSBUILD From 5b47a58a3a9d114b29528eedcaa93b2f263b4f22 Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Fri, 13 Oct 2017 16:09:49 -0700 Subject: [PATCH 24/89] Prototype support for WSL --- tools/ColorTool/ColorTool/ConsoleAPI.cs | 21 +++++++++ tools/ColorTool/ColorTool/Program.cs | 57 ++++++++++++++++++++++++- 2 files changed, 77 insertions(+), 1 deletion(-) diff --git a/tools/ColorTool/ColorTool/ConsoleAPI.cs b/tools/ColorTool/ColorTool/ConsoleAPI.cs index 4e438111f0..c7003e99de 100644 --- a/tools/ColorTool/ColorTool/ConsoleAPI.cs +++ b/tools/ColorTool/ColorTool/ConsoleAPI.cs @@ -56,12 +56,33 @@ namespace ColorTool [DllImport("kernel32.dll", SetLastError = true)] public static extern bool SetConsoleScreenBufferInfoEx(IntPtr ConsoleOutput, ref CONSOLE_SCREEN_BUFFER_INFO_EX ConsoleScreenBufferInfoEx); + + [DllImport("kernel32.dll", SetLastError = true)] + public static extern bool WriteConsole( + IntPtr hConsoleOutput, + string lpBuffer, + uint nNumberOfCharsToWrite, + out uint lpNumberOfCharsWritten, + IntPtr lpReserved + ); //////////////////////////////////////////////////////////////////////// public static uint RGB(int r, int g, int b) { return (uint)r + (((uint)g) << 8) + (((uint)b) << 16); } + public static uint Rvalue(uint rgb) + { + return rgb & 0x000000ff; + } + public static uint Gvalue(uint rgb) + { + return rgb & 0x0000ff00 >> 8; + } + public static uint Bvalue(uint rgb) + { + return (rgb & 0x00ff0000) >> 16; + } public const int COLOR_TABLE_SIZE = 16; } diff --git a/tools/ColorTool/ColorTool/Program.cs b/tools/ColorTool/ColorTool/Program.cs index d65507d514..f259c73c2f 100644 --- a/tools/ColorTool/ColorTool/Program.cs +++ b/tools/ColorTool/ColorTool/Program.cs @@ -83,6 +83,7 @@ namespace ColorTool static bool quietMode = false; static bool setDefaults = false; static bool setProperties = true; + static bool setUnixStyle = false; static void Usage() { @@ -200,6 +201,47 @@ namespace ColorTool } return success; } + + static int[] VT_INDICIES = { + 0, // DARK_BLACK + 4, // DARK_BLUE + 2, // DARK_GREEN + 6, // DARK_CYAN + 1, // DARK_RED + 5, // DARK_MAGENTA + 3, // DARK_YELLOW + 7, // DARK_WHITE + 8+0, // BRIGHT_BLACK + 8+4, // BRIGHT_BLUE + 8+2, // BRIGHT_GREEN + 8+6, // BRIGHT_CYAN + 8+1, // BRIGHT_RED + 8+5, // BRIGHT_MAGENTA + 8+3, // BRIGHT_YELLOW + 8+7,// BRIGHT_WHITE + }; + + static bool SetPropertiesWithVt(uint[] colorTable) + { + Console.WriteLine("Setting colors using VT Sequences"); + int STD_OUTPUT_HANDLE = -11; + IntPtr hOut = GetStdHandle(STD_OUTPUT_HANDLE); + IntPtr whatever = hOut; + uint dwWritten = 0; + for(int i = 0; i < 16; i++) + { + int vtIndex = VT_INDICIES[i]; + uint rgb = colorTable[i]; + string s = "\x1b]4;" + vtIndex + ";rgb:" + Rvalue(rgb) + "/"+ Gvalue(rgb) + "/"+ Bvalue(rgb) + "\x7"; + string printable = "\\x1b]4;" + vtIndex + ";rgb:" + Rvalue(rgb).ToString("X") + "/"+ Gvalue(rgb).ToString("X") + "/"+ Bvalue(rgb).ToString("X") + "\x7"; + Console.WriteLine(s); + Console.WriteLine(printable); + // WriteConsole(hOut, s, (uint)s.Length, out dwWritten, whatever); + // WriteConsole(hOut, printable, (uint)printable.Length, out dwWritten, whatever); + } + return true; + } + static bool SetDefaults(uint[] colorTable) { RegistryKey consoleKey = Registry.CurrentUser.OpenSubKey("Console", true); @@ -251,6 +293,11 @@ namespace ColorTool case "--version": Version(); return; + case "-x": + case "--xterm": + setUnixStyle = true; + setProperties = true; + break; default: break; } @@ -282,7 +329,15 @@ namespace ColorTool } if (setProperties) { - SetProperties(colorTable); + if (setUnixStyle) + { + SetPropertiesWithVt(colorTable); + } + else + { + SetProperties(colorTable); + + } } } From 48021e1d75f609ebb9771fefc7d130bc596956d7 Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Mon, 23 Oct 2017 10:02:08 -0700 Subject: [PATCH 25/89] fix the xterm version --- tools/ColorTool/ColorTool/ConsoleAPI.cs | 2 +- tools/ColorTool/ColorTool/Program.cs | 132 ++++++++++++++---- .../ColorTool/ColorTool/Resources.Designer.cs | 20 ++- tools/ColorTool/ColorTool/Resources.resx | 7 + tools/ColorTool/colortool.sh | 10 ++ 5 files changed, 142 insertions(+), 29 deletions(-) create mode 100644 tools/ColorTool/colortool.sh diff --git a/tools/ColorTool/ColorTool/ConsoleAPI.cs b/tools/ColorTool/ColorTool/ConsoleAPI.cs index c7003e99de..a9e053a887 100644 --- a/tools/ColorTool/ColorTool/ConsoleAPI.cs +++ b/tools/ColorTool/ColorTool/ConsoleAPI.cs @@ -77,7 +77,7 @@ namespace ColorTool } public static uint Gvalue(uint rgb) { - return rgb & 0x0000ff00 >> 8; + return (rgb & 0x0000ff00) >> 8; } public static uint Bvalue(uint rgb) { diff --git a/tools/ColorTool/ColorTool/Program.cs b/tools/ColorTool/ColorTool/Program.cs index f259c73c2f..4568ff5236 100644 --- a/tools/ColorTool/ColorTool/Program.cs +++ b/tools/ColorTool/ColorTool/Program.cs @@ -80,6 +80,26 @@ namespace ColorTool DARK_WHITE }; + // Use a Console index in to get a VT index out. + static int[] VT_INDICIES = { + 0, // DARK_BLACK + 4, // DARK_BLUE + 2, // DARK_GREEN + 6, // DARK_CYAN + 1, // DARK_RED + 5, // DARK_MAGENTA + 3, // DARK_YELLOW + 7, // DARK_WHITE + 8+0, // BRIGHT_BLACK + 8+4, // BRIGHT_BLUE + 8+2, // BRIGHT_GREEN + 8+6, // BRIGHT_CYAN + 8+1, // BRIGHT_RED + 8+5, // BRIGHT_MAGENTA + 8+3, // BRIGHT_YELLOW + 8+7,// BRIGHT_WHITE + }; + static bool quietMode = false; static bool setDefaults = false; static bool setProperties = true; @@ -99,6 +119,84 @@ namespace ColorTool Console.WriteLine("colortool v" + ver); } + static void PrintTable() + { + ConsoleColor[] colors = (ConsoleColor[])ConsoleColor.GetValues(typeof(ConsoleColor)); + // Save the current background and foreground colors. + ConsoleColor currentBackground = Console.BackgroundColor; + ConsoleColor currentForeground = Console.ForegroundColor; + string test = " gYw "; + string[] FGs = { + "m", + "1m", + "30m", + "1;30m", + "31m", + "1;31m", + "32m", + "1;32m", + "33m", + "1;33m", + "34m", + "1;34m", + "35m", + "1;35m", + "36m", + "1;36m", + "37m", + "1;37m" + }; + string[] BGs = { + "m", + "40m", + "41m", + "42m", + "43m", + "44m", + "45m", + "46m", + "47m" + }; + + Console.Write("\t"); + for (int bg = 0; bg < BGs.Length; bg++) + { + if (bg > 0) Console.Write(" "); + Console.Write(" "); + Console.Write(bg == 0 ? " " : BGs[bg]); + Console.Write(" "); + } + Console.WriteLine(); + + for (int fg = 0; fg < FGs.Length; fg++) + { + Console.ForegroundColor = currentForeground; + Console.BackgroundColor = currentBackground; + + if (fg >= 0) Console.Write(FGs[fg] + "\t"); + + if (fg == 0) Console.ForegroundColor = currentForeground; + else Console.ForegroundColor = colors[outputFgs[fg - 1]]; + + for (int bg = 0; bg < BGs.Length; bg++) + { + if (bg > 0) Console.Write(" "); + if (bg == 0) + Console.BackgroundColor = currentBackground; + else Console.BackgroundColor = colors[saneBgs[bg - 1]]; + Console.Write(test); + Console.BackgroundColor = currentBackground; + } + Console.Write("\n"); + + } + Console.Write("\n"); + + // Reset foreground and background colors + Console.ForegroundColor = currentForeground; + Console.BackgroundColor = currentBackground; + } + static void PrintTable() { ConsoleColor[] colors = (ConsoleColor[])ConsoleColor.GetValues(typeof(ConsoleColor)); @@ -202,42 +300,22 @@ namespace ColorTool return success; } - static int[] VT_INDICIES = { - 0, // DARK_BLACK - 4, // DARK_BLUE - 2, // DARK_GREEN - 6, // DARK_CYAN - 1, // DARK_RED - 5, // DARK_MAGENTA - 3, // DARK_YELLOW - 7, // DARK_WHITE - 8+0, // BRIGHT_BLACK - 8+4, // BRIGHT_BLUE - 8+2, // BRIGHT_GREEN - 8+6, // BRIGHT_CYAN - 8+1, // BRIGHT_RED - 8+5, // BRIGHT_MAGENTA - 8+3, // BRIGHT_YELLOW - 8+7,// BRIGHT_WHITE - }; - static bool SetPropertiesWithVt(uint[] colorTable) { - Console.WriteLine("Setting colors using VT Sequences"); int STD_OUTPUT_HANDLE = -11; IntPtr hOut = GetStdHandle(STD_OUTPUT_HANDLE); IntPtr whatever = hOut; - uint dwWritten = 0; + // uint dwWritten = 0; for(int i = 0; i < 16; i++) { int vtIndex = VT_INDICIES[i]; uint rgb = colorTable[i]; - string s = "\x1b]4;" + vtIndex + ";rgb:" + Rvalue(rgb) + "/"+ Gvalue(rgb) + "/"+ Bvalue(rgb) + "\x7"; - string printable = "\\x1b]4;" + vtIndex + ";rgb:" + Rvalue(rgb).ToString("X") + "/"+ Gvalue(rgb).ToString("X") + "/"+ Bvalue(rgb).ToString("X") + "\x7"; - Console.WriteLine(s); - Console.WriteLine(printable); - // WriteConsole(hOut, s, (uint)s.Length, out dwWritten, whatever); - // WriteConsole(hOut, printable, (uint)printable.Length, out dwWritten, whatever); + string s = "\x1b]4;" + vtIndex + ";rgb:" + Rvalue(rgb).ToString("X") + "/"+ Gvalue(rgb).ToString("X") + "/"+ Bvalue(rgb).ToString("X") + "\x7"; + Console.Write(s); + } + if (!quietMode) + { + PrintTableWithVt(); } return true; } diff --git a/tools/ColorTool/ColorTool/Resources.Designer.cs b/tools/ColorTool/ColorTool/Resources.Designer.cs index e053d6d114..5031721e03 100644 --- a/tools/ColorTool/ColorTool/Resources.Designer.cs +++ b/tools/ColorTool/ColorTool/Resources.Designer.cs @@ -98,6 +98,24 @@ namespace ColorTool { } } + /// + /// Looks up a localized string similar to \x1b]4;{0};rgb:{1}/{2}/{3}\x7. + /// + public static string OSCFormat { + get { + return ResourceManager.GetString("OSCFormat", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to \x1b]4;{0};rgb:{1}/{2}/{3}\x7. + /// + public static string OSCFormat2 { + get { + return ResourceManager.GetString("OSCFormat2", resourceCulture); + } + } + /// /// Looks up a localized string similar to Could not find or load "{0}". /// @@ -114,7 +132,7 @@ namespace ColorTool { ///By default, applies the colors in the specified .itermcolors or .ini file to the current console window. ///This does NOT save the properties automatically. For that, you'll need to open the properties sheet and hit "Ok". ///Included should be a `schemes/` directory with a selection of schemes of both formats for examples. - ///Feel free to add your own prefered scheme to that direc [rest of string was truncated]";. + ///Feel free to add your own preferred scheme to that dire [rest of string was truncated]";. /// public static string Usage { get { diff --git a/tools/ColorTool/ColorTool/Resources.resx b/tools/ColorTool/ColorTool/Resources.resx index 503cdd2f8f..0bc33fdbe4 100644 --- a/tools/ColorTool/ColorTool/Resources.resx +++ b/tools/ColorTool/ColorTool/Resources.resx @@ -151,9 +151,16 @@ Options: -q, --quiet : Don't print the color table after applying -d, --defaults : Apply the scheme to only the defaults in the registry -b, --both : Apply the scheme to both the current console and the defaults. + -x, --xterm : Set the colors using VT sequences. Used for setting the colors in WSL. -v, --version : Display the version number Wrote selected scheme to the defaults. + + \x1b]4;{0};rgb:{1}/{2}/{3}\x7 + + + \x1b]4;{0};rgb:{1}/{2}/{3}\x7 + \ No newline at end of file diff --git a/tools/ColorTool/colortool.sh b/tools/ColorTool/colortool.sh new file mode 100644 index 0000000000..114a18a85e --- /dev/null +++ b/tools/ColorTool/colortool.sh @@ -0,0 +1,10 @@ +#!/bin/sh + +if [ "$1" != "" ]; then + # rm __temp__.txt + # colortool.exe -x $1 > __temp__.txt + # cat __temp__.txt + cmd.exe /c colortool.exe -x $1 +else + colortool.exe --help +fi From 9a5393d49d3bdafdccd7011f1630630fea754521 Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Fri, 19 Jan 2018 13:31:01 -0800 Subject: [PATCH 26/89] Fix printing the table in vt mode --- tools/ColorTool/ColorTool/Program.cs | 46 +++++++++++-------- .../ColorTool/ColorTool/Resources.Designer.cs | 20 +------- tools/ColorTool/ColorTool/Resources.resx | 6 --- 3 files changed, 29 insertions(+), 43 deletions(-) diff --git a/tools/ColorTool/ColorTool/Program.cs b/tools/ColorTool/ColorTool/Program.cs index 4568ff5236..df35d35bb8 100644 --- a/tools/ColorTool/ColorTool/Program.cs +++ b/tools/ColorTool/ColorTool/Program.cs @@ -112,8 +112,6 @@ namespace ColorTool static void Version() { - //System.Reflection.Assembly.GetEntryAssembly(); - //AssemblyName.GetAssemblyName(@"c:\path\to\file.dll").Version; string exePath = System.Reflection.Assembly.GetEntryAssembly().Location; Version ver = AssemblyName.GetAssemblyName(exePath).Version; Console.WriteLine("colortool v" + ver); @@ -197,12 +195,9 @@ namespace ColorTool Console.BackgroundColor = currentBackground; } - static void PrintTable() + static void PrintTableWithVt() { - ConsoleColor[] colors = (ConsoleColor[])ConsoleColor.GetValues(typeof(ConsoleColor)); // Save the current background and foreground colors. - ConsoleColor currentBackground = Console.BackgroundColor; - ConsoleColor currentForeground = Console.ForegroundColor; string test = " gYw "; string[] FGs = { "m", @@ -248,22 +243,39 @@ namespace ColorTool for (int fg = 0; fg < FGs.Length; fg++) { - Console.ForegroundColor = currentForeground; - Console.BackgroundColor = currentBackground; + Console.Write("\x1b[m"); - if (fg >= 0) Console.Write(FGs[fg] + "\t"); + if (fg >= 0) + { + Console.Write(FGs[fg] + "\t"); + } - if (fg == 0) Console.ForegroundColor = currentForeground; - else Console.ForegroundColor = colors[outputFgs[fg - 1]]; + if (fg == 0) + { + Console.Write("\x1b[39m"); + } + else + { + Console.Write("\x1b[" + FGs[fg]); + } for (int bg = 0; bg < BGs.Length; bg++) { - if (bg > 0) Console.Write(" "); + if (bg > 0) + { + Console.Write(" "); + } if (bg == 0) - Console.BackgroundColor = currentBackground; - else Console.BackgroundColor = colors[saneBgs[bg - 1]]; + { + Console.Write("\x1b[49m"); + } + else + { + Console.Write("\x1b[" +BGs[bg]); + } + Console.Write(test); - Console.BackgroundColor = currentBackground; + Console.Write("\x1b[49m"); } Console.Write("\n"); @@ -271,8 +283,7 @@ namespace ColorTool Console.Write("\n"); // Reset foreground and background colors - Console.ForegroundColor = currentForeground; - Console.BackgroundColor = currentBackground; + Console.Write("\x1b[m"); } static bool SetProperties(uint[] colorTable) @@ -305,7 +316,6 @@ namespace ColorTool int STD_OUTPUT_HANDLE = -11; IntPtr hOut = GetStdHandle(STD_OUTPUT_HANDLE); IntPtr whatever = hOut; - // uint dwWritten = 0; for(int i = 0; i < 16; i++) { int vtIndex = VT_INDICIES[i]; diff --git a/tools/ColorTool/ColorTool/Resources.Designer.cs b/tools/ColorTool/ColorTool/Resources.Designer.cs index 5031721e03..a609f9af4a 100644 --- a/tools/ColorTool/ColorTool/Resources.Designer.cs +++ b/tools/ColorTool/ColorTool/Resources.Designer.cs @@ -19,7 +19,7 @@ namespace ColorTool { // class via a tool like ResGen or Visual Studio. // To add or remove a member, edit your .ResX file then rerun ResGen // with the /str option, or rebuild your VS project. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] public class Resources { @@ -98,24 +98,6 @@ namespace ColorTool { } } - /// - /// Looks up a localized string similar to \x1b]4;{0};rgb:{1}/{2}/{3}\x7. - /// - public static string OSCFormat { - get { - return ResourceManager.GetString("OSCFormat", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to \x1b]4;{0};rgb:{1}/{2}/{3}\x7. - /// - public static string OSCFormat2 { - get { - return ResourceManager.GetString("OSCFormat2", resourceCulture); - } - } - /// /// Looks up a localized string similar to Could not find or load "{0}". /// diff --git a/tools/ColorTool/ColorTool/Resources.resx b/tools/ColorTool/ColorTool/Resources.resx index 0bc33fdbe4..ce7e6cc3bf 100644 --- a/tools/ColorTool/ColorTool/Resources.resx +++ b/tools/ColorTool/ColorTool/Resources.resx @@ -157,10 +157,4 @@ Options: Wrote selected scheme to the defaults. - - \x1b]4;{0};rgb:{1}/{2}/{3}\x7 - - - \x1b]4;{0};rgb:{1}/{2}/{3}\x7 - \ No newline at end of file From 85e347fc4a92b38aeb582333c7e9d83d278e85bf Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Fri, 19 Jan 2018 13:32:45 -0800 Subject: [PATCH 27/89] I guess I didn't need this after all --- tools/ColorTool/colortool.sh | 10 ---------- 1 file changed, 10 deletions(-) delete mode 100644 tools/ColorTool/colortool.sh diff --git a/tools/ColorTool/colortool.sh b/tools/ColorTool/colortool.sh deleted file mode 100644 index 114a18a85e..0000000000 --- a/tools/ColorTool/colortool.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/sh - -if [ "$1" != "" ]; then - # rm __temp__.txt - # colortool.exe -x $1 > __temp__.txt - # cat __temp__.txt - cmd.exe /c colortool.exe -x $1 -else - colortool.exe --help -fi From eba68a04b6f8bfd3dcea1feff8c4e9b7be52c5cd Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Fri, 19 Jan 2018 13:51:56 -0800 Subject: [PATCH 28/89] Enable setting the colors w/ VT even on windows --- tools/ColorTool/ColorTool/ConsoleAPI.cs | 16 ++++++++++++++++ tools/ColorTool/ColorTool/Program.cs | 19 +++++++++++++++++-- tools/ColorTool/ColorTool/Resources.resx | 1 + 3 files changed, 34 insertions(+), 2 deletions(-) diff --git a/tools/ColorTool/ColorTool/ConsoleAPI.cs b/tools/ColorTool/ColorTool/ConsoleAPI.cs index a9e053a887..3d781009aa 100644 --- a/tools/ColorTool/ColorTool/ConsoleAPI.cs +++ b/tools/ColorTool/ColorTool/ConsoleAPI.cs @@ -26,6 +26,16 @@ namespace ColorTool public short Bottom; } + [Flags] + public enum ConsoleOutputModes : uint + { + ENABLE_PROCESSED_OUTPUT = 0x0001, + ENABLE_WRAP_AT_EOL_OUTPUT = 0x0002, + ENABLE_VIRTUAL_TERMINAL_PROCESSING = 0x0004, + DISABLE_NEWLINE_AUTO_RETURN = 0x0008, + ENABLE_LVB_GRID_WORLDWIDE = 0x0010, + } + [StructLayout(LayoutKind.Sequential)] public struct CONSOLE_SCREEN_BUFFER_INFO_EX { @@ -65,6 +75,12 @@ namespace ColorTool out uint lpNumberOfCharsWritten, IntPtr lpReserved ); + + [DllImport("kernel32.dll")] + public static extern bool GetConsoleMode(IntPtr hConsoleHandle, out uint lpMode); + + [DllImport("kernel32.dll")] + public static extern bool SetConsoleMode(IntPtr hConsoleHandle, uint dwMode); //////////////////////////////////////////////////////////////////////// public static uint RGB(int r, int g, int b) diff --git a/tools/ColorTool/ColorTool/Program.cs b/tools/ColorTool/ColorTool/Program.cs index df35d35bb8..7a030a554d 100644 --- a/tools/ColorTool/ColorTool/Program.cs +++ b/tools/ColorTool/ColorTool/Program.cs @@ -315,8 +315,17 @@ namespace ColorTool { int STD_OUTPUT_HANDLE = -11; IntPtr hOut = GetStdHandle(STD_OUTPUT_HANDLE); - IntPtr whatever = hOut; - for(int i = 0; i < 16; i++) + uint originalMode; + uint requestedMode; + bool succeeded = GetConsoleMode(hOut, out originalMode); + if (succeeded) + { + requestedMode = originalMode | (uint)ConsoleAPI.ConsoleOutputModes.ENABLE_VIRTUAL_TERMINAL_PROCESSING; + SetConsoleMode(hOut, requestedMode); + + } + + for (int i = 0; i < 16; i++) { int vtIndex = VT_INDICIES[i]; uint rgb = colorTable[i]; @@ -327,6 +336,12 @@ namespace ColorTool { PrintTableWithVt(); } + + if (succeeded) + { + SetConsoleMode(hOut, originalMode); + } + return true; } diff --git a/tools/ColorTool/ColorTool/Resources.resx b/tools/ColorTool/ColorTool/Resources.resx index ce7e6cc3bf..3e806c7437 100644 --- a/tools/ColorTool/ColorTool/Resources.resx +++ b/tools/ColorTool/ColorTool/Resources.resx @@ -152,6 +152,7 @@ Options: -d, --defaults : Apply the scheme to only the defaults in the registry -b, --both : Apply the scheme to both the current console and the defaults. -x, --xterm : Set the colors using VT sequences. Used for setting the colors in WSL. + Only works in Windows versions >= 17048. -v, --version : Display the version number From 22dd8a8e01c0862a80f526d899bdd9d0de5e576c Mon Sep 17 00:00:00 2001 From: Yatao Li Date: Wed, 14 Feb 2018 22:40:28 +0800 Subject: [PATCH 29/89] colortool: add support for fg/bg color slot designation --- tools/ColorTool/ColorTool/ColorScheme.cs | 83 ++++++++++++++++++++ tools/ColorTool/ColorTool/ColorTool.csproj | 1 + tools/ColorTool/ColorTool/ConsoleAPI.cs | 3 +- tools/ColorTool/ColorTool/ISchemeParser.cs | 2 +- tools/ColorTool/ColorTool/IniSchemeParser.cs | 4 +- tools/ColorTool/ColorTool/Program.cs | 33 +++++--- tools/ColorTool/ColorTool/XmlSchemeParser.cs | 49 ++++-------- 7 files changed, 126 insertions(+), 49 deletions(-) create mode 100644 tools/ColorTool/ColorTool/ColorScheme.cs diff --git a/tools/ColorTool/ColorTool/ColorScheme.cs b/tools/ColorTool/ColorTool/ColorScheme.cs new file mode 100644 index 0000000000..fe8b9a782d --- /dev/null +++ b/tools/ColorTool/ColorTool/ColorScheme.cs @@ -0,0 +1,83 @@ +// +// Copyright (C) Microsoft. All rights reserved. +// Licensed under the terms described in the LICENSE file in the root of this project. +// + +using System; +using System.Linq; + +namespace ColorTool +{ + public class ColorScheme + { + public uint[] colorTable = null; + public uint? foreground = null; + public uint? background = null; + + public int CalculateIndex(uint value) => + colorTable.Select((color, idx) => Tuple.Create(color, idx)) + .OrderBy(Difference(value)) + .First().Item2; + + private static Func, double> Difference(uint c1) => + // heuristic 1: nearest neighbor in RGB space + // tup => Distance(RGB(c1), RGB(tup.Item1)); + // heuristic 2: nearest neighbor in RGB space + tup => Distance(HSV(c1), HSV(tup.Item1)); + + private static double Distance(uint[] c1c, uint[] c2c) + => Math.Sqrt(c1c.Zip(c2c, (a, b) => Math.Pow((int)a - (int)b, 2)).Sum()); + + internal static uint[] RGB(uint c) => new[] { c & 0xFF, (c >> 8) & 0xFF, (c >> 16) & 0xFF }; + + internal static uint[] HSV(uint c) + { + var rgb = RGB(c).Select(_ => (int)_).ToArray(); + int max = rgb.Max(); + int min = rgb.Min(); + + int d = max - min; + int h = 0; + int s = (int)(255 * ((max == 0) ? 0 : d / (double)max)); + int v = max; + + if (d != 0) + { + double dh; + if (rgb[0] == max) dh = ((rgb[1] - rgb[2]) / (double)d); + else if (rgb[1] == max) dh = 2.0 + ((rgb[2] - rgb[0]) / (double)d); + else /* if (rgb[2] == max) */ dh = 4.0 + ((rgb[0] - rgb[1]) / (double)d); + dh *= 60; + if (dh < 0) dh += 360.0; + h = (int)(dh * 255.0 / 360.0); + } + + return new[] { (uint)h, (uint)s, (uint)v }; + } + + internal void Dump() + { + Action _dump = (str, c) => + { + var rgb = RGB(c); + var hsv = HSV(c); + Console.WriteLine($"{str} =\tRGB({rgb[0]}, {rgb[1]}, {rgb[2]}),\tHSV({hsv[0]}, {hsv[1]}, {hsv[2]})"); + }; + + for (int i = 0; i < 16; ++i) + { + _dump($"Color[{i}]", colorTable[i]); + } + + if (foreground != null) + { + _dump("FG ", foreground.Value); + } + + if (background != null) + { + _dump("BG ", background.Value); + } + } + } +} diff --git a/tools/ColorTool/ColorTool/ColorTool.csproj b/tools/ColorTool/ColorTool/ColorTool.csproj index 46974cc065..e8e0808b3d 100644 --- a/tools/ColorTool/ColorTool/ColorTool.csproj +++ b/tools/ColorTool/ColorTool/ColorTool.csproj @@ -44,6 +44,7 @@ + diff --git a/tools/ColorTool/ColorTool/ConsoleAPI.cs b/tools/ColorTool/ColorTool/ConsoleAPI.cs index 4e438111f0..ae6aefde3d 100644 --- a/tools/ColorTool/ColorTool/ConsoleAPI.cs +++ b/tools/ColorTool/ColorTool/ConsoleAPI.cs @@ -32,7 +32,7 @@ namespace ColorTool public uint cbSize; public COORD dwSize; public COORD dwCursorPosition; - public short wAttributes; + public ushort wAttributes; public SMALL_RECT srWindow; public COORD dwMaximumWindowSize; @@ -56,6 +56,7 @@ namespace ColorTool [DllImport("kernel32.dll", SetLastError = true)] public static extern bool SetConsoleScreenBufferInfoEx(IntPtr ConsoleOutput, ref CONSOLE_SCREEN_BUFFER_INFO_EX ConsoleScreenBufferInfoEx); + //////////////////////////////////////////////////////////////////////// public static uint RGB(int r, int g, int b) diff --git a/tools/ColorTool/ColorTool/ISchemeParser.cs b/tools/ColorTool/ColorTool/ISchemeParser.cs index df8cfcec2d..d738331d6c 100644 --- a/tools/ColorTool/ColorTool/ISchemeParser.cs +++ b/tools/ColorTool/ColorTool/ISchemeParser.cs @@ -7,6 +7,6 @@ namespace ColorTool { interface ISchemeParser { - uint[] ParseScheme(string schemeName); + ColorScheme ParseScheme(string schemeName); } } diff --git a/tools/ColorTool/ColorTool/IniSchemeParser.cs b/tools/ColorTool/ColorTool/IniSchemeParser.cs index 3b1789f57c..699b331e1c 100644 --- a/tools/ColorTool/ColorTool/IniSchemeParser.cs +++ b/tools/ColorTool/ColorTool/IniSchemeParser.cs @@ -104,7 +104,7 @@ namespace ColorTool return null; } - public uint[] ParseScheme(string schemeName) + public ColorScheme ParseScheme(string schemeName) { bool success = true; @@ -147,7 +147,7 @@ namespace ColorTool } } - return colorTable; + return new ColorScheme { colorTable = colorTable }; } } } diff --git a/tools/ColorTool/ColorTool/Program.cs b/tools/ColorTool/ColorTool/Program.cs index d65507d514..fbbc0e8007 100644 --- a/tools/ColorTool/ColorTool/Program.cs +++ b/tools/ColorTool/ColorTool/Program.cs @@ -176,7 +176,7 @@ namespace ColorTool Console.BackgroundColor = currentBackground; } - static bool SetProperties(uint[] colorTable) + static bool SetProperties(ColorScheme colorScheme) { CONSOLE_SCREEN_BUFFER_INFO_EX csbiex = CONSOLE_SCREEN_BUFFER_INFO_EX.Create(); int STD_OUTPUT_HANDLE = -11; @@ -187,7 +187,13 @@ namespace ColorTool csbiex.srWindow.Bottom++; for (int i = 0; i < 16; i++) { - csbiex.ColorTable[i] = colorTable[i]; + csbiex.ColorTable[i] = colorScheme.colorTable[i]; + } + if(colorScheme.background != null && colorScheme.foreground != null) + { + int fgidx = colorScheme.CalculateIndex(colorScheme.foreground.Value); + int bgidx = colorScheme.CalculateIndex(colorScheme.background.Value); + csbiex.wAttributes = (ushort)(fgidx | (bgidx << 4)); } SetConsoleScreenBufferInfoEx(hOut, ref csbiex); } @@ -200,19 +206,20 @@ namespace ColorTool } return success; } - static bool SetDefaults(uint[] colorTable) + + static bool SetDefaults(ColorScheme colorScheme) { + //TODO RegistryKey consoleKey = Registry.CurrentUser.OpenSubKey("Console", true); - for (int i = 0; i < colorTable.Length; i++) + for (int i = 0; i < colorScheme.colorTable.Length; i++) { string valueName = "ColorTable" + (i < 10 ? "0" : "") + i; - consoleKey.SetValue(valueName, colorTable[i], RegistryValueKind.DWord); + consoleKey.SetValue(valueName, colorScheme.colorTable[i], RegistryValueKind.DWord); } Console.WriteLine(Resources.WroteToDefaults); return true; } - static void Main(string[] args) { if (args.Length < 1) @@ -258,19 +265,19 @@ namespace ColorTool string schemeName = args[args.Length - 1]; - uint[] colorTable = null; + ColorScheme colorScheme = null; ISchemeParser[] parsers = { new XmlSchemeParser(), new IniSchemeParser() }; foreach (var parser in parsers) { - uint[] table = parser.ParseScheme(schemeName); - if (table != null) + var scheme = parser.ParseScheme(schemeName); + if (scheme != null) { - colorTable = table; + colorScheme = scheme; break; } } - if (colorTable == null) + if (colorScheme == null) { Console.WriteLine(string.Format(Resources.SchemeNotFound, schemeName)); return; @@ -278,11 +285,11 @@ namespace ColorTool if (setDefaults) { - SetDefaults(colorTable); + SetDefaults(colorScheme); } if (setProperties) { - SetProperties(colorTable); + SetProperties(colorScheme); } } diff --git a/tools/ColorTool/ColorTool/XmlSchemeParser.cs b/tools/ColorTool/ColorTool/XmlSchemeParser.cs index a28aea54e5..59ee8cc4c6 100644 --- a/tools/ColorTool/ColorTool/XmlSchemeParser.cs +++ b/tools/ColorTool/ColorTool/XmlSchemeParser.cs @@ -4,6 +4,8 @@ // using System; using System.Globalization; +using System.Linq; +using System.Linq.Expressions; using System.Xml; using static ColorTool.ConsoleAPI; @@ -30,6 +32,8 @@ namespace ColorTool "Ansi 11 Color", // BRIGHT_YELLOW "Ansi 15 Color" // BRIGHT_WHITE }; + static string FG_KEY = "Foreground Color"; + static string BG_KEY = "Background Color"; static string RED_KEY = "Red Component"; static string GREEN_KEY = "Green Component"; static string BLUE_KEY = "Blue Component"; @@ -121,7 +125,7 @@ namespace ColorTool } - public uint[] ParseScheme(string schemeName) + public ColorScheme ParseScheme(string schemeName) { XmlDocument xmlDoc = loadXmlScheme(schemeName); // Create an XML document object if (xmlDoc == null) return null; @@ -129,39 +133,20 @@ namespace ColorTool XmlNodeList children = root.ChildNodes; uint[] colorTable = new uint[COLOR_TABLE_SIZE]; + uint? fgColor = null, bgColor = null; int colorsFound = 0; bool success = false; - foreach (XmlNode tableEntry in children) + foreach (var tableEntry in children.OfType().Where(_ => _.Name == "key")) { - if (tableEntry.Name == "key") - { - int index = -1; - for (int i = 0; i < COLOR_TABLE_SIZE; i++) - { - if (PLIST_COLOR_NAMES[i] == tableEntry.InnerText) - { - index = i; - break; - } - } - if (index == -1) - { - continue; - } - uint rgb = 0; ; - XmlNode components = tableEntry.NextSibling; - success = parseRgbFromXml(components, ref rgb); - if (!success) - { - break; - } - else - { - colorTable[index] = rgb; - colorsFound++; - } - } - + uint rgb = 0; + int index = -1; + XmlNode components = tableEntry.NextSibling; + success = parseRgbFromXml(components, ref rgb); + if (!success) { break; } + else if (tableEntry.InnerText == FG_KEY) { fgColor = rgb; } + else if (tableEntry.InnerText == BG_KEY) { bgColor = rgb; } + else if (-1 != (index = Array.IndexOf(PLIST_COLOR_NAMES, tableEntry.InnerText))) + { colorTable[index] = rgb; colorsFound++; } } if (colorsFound < COLOR_TABLE_SIZE) { @@ -172,8 +157,8 @@ namespace ColorTool { return null; } - return colorTable; + return new ColorScheme { colorTable = colorTable, foreground = fgColor, background = bgColor }; } } } From 49b3df3d71b8ba42aebc59782b6babac98fae701 Mon Sep 17 00:00:00 2001 From: Yatao Li Date: Wed, 14 Feb 2018 23:01:37 +0800 Subject: [PATCH 30/89] weighted RGB distance works well --- tools/ColorTool/ColorTool/ColorScheme.cs | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/tools/ColorTool/ColorTool/ColorScheme.cs b/tools/ColorTool/ColorTool/ColorScheme.cs index fe8b9a782d..0e9fae69e9 100644 --- a/tools/ColorTool/ColorTool/ColorScheme.cs +++ b/tools/ColorTool/ColorTool/ColorScheme.cs @@ -23,7 +23,18 @@ namespace ColorTool // heuristic 1: nearest neighbor in RGB space // tup => Distance(RGB(c1), RGB(tup.Item1)); // heuristic 2: nearest neighbor in RGB space - tup => Distance(HSV(c1), HSV(tup.Item1)); + // tup => Distance(HSV(c1), HSV(tup.Item1)); + // heuristic 3: weighted RGB L2 distance + tup => WeightedRGBSimilarity(c1, tup.Item1); + + private static double WeightedRGBSimilarity(uint c1, uint c2) + { + var rgb1 = RGB(c1); + var rgb2 = RGB(c2); + var dist = rgb1.Zip(rgb2, (a, b) => Math.Pow((int)a - (int)b, 2)).ToArray(); + var rbar = (rgb1[0] + rgb1[0]) / 2.0; + return Math.Sqrt(dist[0] * (2 + rbar / 256.0) + dist[1] * 4 + dist[2] * (2 + (255 - rbar) / 256.0)); + } private static double Distance(uint[] c1c, uint[] c2c) => Math.Sqrt(c1c.Zip(c2c, (a, b) => Math.Pow((int)a - (int)b, 2)).Sum()); From ddb74ef5dbab0e8e3c08418596426eb435c7a6a5 Mon Sep 17 00:00:00 2001 From: Michael Niksa Date: Wed, 25 Apr 2018 14:17:38 -0700 Subject: [PATCH 31/89] Fix typo from PR feedback. --- tools/ColorTool/ColorTool/Program.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/ColorTool/ColorTool/Program.cs b/tools/ColorTool/ColorTool/Program.cs index 6399729d8c..e671cb004e 100644 --- a/tools/ColorTool/ColorTool/Program.cs +++ b/tools/ColorTool/ColorTool/Program.cs @@ -240,7 +240,7 @@ namespace ColorTool } else { - Console.WriteLine("Failed to get conosle information."); + Console.WriteLine("Failed to get console information."); } return success; } From 198c75cf26f7177fc195e14c3dcdc4431faf7330 Mon Sep 17 00:00:00 2001 From: Taylor Southwick Date: Wed, 25 Apr 2018 15:24:59 -0700 Subject: [PATCH 32/89] Disable automatic assembly info generation --- tools/ColorTool/ColorTool/ColorTool.csproj | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/ColorTool/ColorTool/ColorTool.csproj b/tools/ColorTool/ColorTool/ColorTool.csproj index 74cfdb4aeb..1fadb76693 100644 --- a/tools/ColorTool/ColorTool/ColorTool.csproj +++ b/tools/ColorTool/ColorTool/ColorTool.csproj @@ -3,6 +3,7 @@ Exe net46 + false From d6e77edc27c7cc63ae9dc205cd39ad99c51be67b Mon Sep 17 00:00:00 2001 From: Michael Niksa Date: Wed, 25 Apr 2018 15:37:40 -0700 Subject: [PATCH 33/89] Add error suppression to make listing work better. --- tools/ColorTool/ColorTool/ISchemeParser.cs | 2 +- tools/ColorTool/ColorTool/IniSchemeParser.cs | 12 +++++++++--- tools/ColorTool/ColorTool/Program.cs | 6 +++--- .../ColorTool/Properties/launchSettings.json | 7 +++++++ tools/ColorTool/ColorTool/XmlSchemeParser.cs | 7 +++++-- 5 files changed, 25 insertions(+), 9 deletions(-) create mode 100644 tools/ColorTool/ColorTool/Properties/launchSettings.json diff --git a/tools/ColorTool/ColorTool/ISchemeParser.cs b/tools/ColorTool/ColorTool/ISchemeParser.cs index 150ca35cca..f47f09f730 100644 --- a/tools/ColorTool/ColorTool/ISchemeParser.cs +++ b/tools/ColorTool/ColorTool/ISchemeParser.cs @@ -9,6 +9,6 @@ namespace ColorTool { string Name { get; } - uint[] ParseScheme(string schemeName); + uint[] ParseScheme(string schemeName, bool reportErrors = true); } } diff --git a/tools/ColorTool/ColorTool/IniSchemeParser.cs b/tools/ColorTool/ColorTool/IniSchemeParser.cs index e20554b0bc..a6a66bbd5d 100644 --- a/tools/ColorTool/ColorTool/IniSchemeParser.cs +++ b/tools/ColorTool/ColorTool/IniSchemeParser.cs @@ -107,7 +107,7 @@ namespace ColorTool return null; } - public uint[] ParseScheme(string schemeName) + public uint[] ParseScheme(string schemeName, bool reportErrors = true) { bool success = true; @@ -127,7 +127,10 @@ namespace ColorTool if (tableStrings[i].Length <= 0) { success = false; - Console.WriteLine(string.Format(Resources.IniParseError, filename, name, tableStrings[i])); + if (reportErrors) + { + Console.WriteLine(string.Format(Resources.IniParseError, filename, name, tableStrings[i])); + } break; } } @@ -144,7 +147,10 @@ namespace ColorTool } catch (Exception /*e*/) { - Console.WriteLine(string.Format(Resources.IniLoadError, filename)); + if (reportErrors) + { + Console.WriteLine(string.Format(Resources.IniLoadError, filename)); + } colorTable = null; } diff --git a/tools/ColorTool/ColorTool/Program.cs b/tools/ColorTool/ColorTool/Program.cs index 4bd7f799ce..22391ee144 100644 --- a/tools/ColorTool/ColorTool/Program.cs +++ b/tools/ColorTool/ColorTool/Program.cs @@ -199,7 +199,7 @@ namespace ColorTool string fgText = " gYw "; foreach (string schemeName in Directory.GetFiles("./schemes/").Select(Path.GetFileName)) { - uint[] colorTable = GetSchemeUints(schemeName); + uint[] colorTable = GetSchemeUints(schemeName, false); if (colorTable != null) { string colors = string.Empty; @@ -389,11 +389,11 @@ namespace ColorTool .Select(t => (ISchemeParser)Activator.CreateInstance(t)); } - private static uint[] GetSchemeUints(string schemeName) + private static uint[] GetSchemeUints(string schemeName, bool reportErrors = true) { foreach (var parser in GetParsers()) { - uint[] table = parser.ParseScheme(schemeName); + uint[] table = parser.ParseScheme(schemeName, reportErrors); if (table != null) { return table; diff --git a/tools/ColorTool/ColorTool/Properties/launchSettings.json b/tools/ColorTool/ColorTool/Properties/launchSettings.json new file mode 100644 index 0000000000..5183ca3e35 --- /dev/null +++ b/tools/ColorTool/ColorTool/Properties/launchSettings.json @@ -0,0 +1,7 @@ +{ + "profiles": { + "ColorTool": { + "commandName": "Project" + } + } +} \ No newline at end of file diff --git a/tools/ColorTool/ColorTool/XmlSchemeParser.cs b/tools/ColorTool/ColorTool/XmlSchemeParser.cs index d1b1424b1b..2aa035af73 100644 --- a/tools/ColorTool/ColorTool/XmlSchemeParser.cs +++ b/tools/ColorTool/ColorTool/XmlSchemeParser.cs @@ -123,7 +123,7 @@ namespace ColorTool } - public uint[] ParseScheme(string schemeName) + public uint[] ParseScheme(string schemeName, bool reportErrors = true) { XmlDocument xmlDoc = loadXmlScheme(schemeName); // Create an XML document object if (xmlDoc == null) return null; @@ -167,7 +167,10 @@ namespace ColorTool } if (colorsFound < COLOR_TABLE_SIZE) { - Console.WriteLine(Resources.InvalidNumberOfColors); + if (reportErrors) + { + Console.WriteLine(Resources.InvalidNumberOfColors); + } success = false; } if (!success) From 78e50fcf260b749adfded714016e3a636287af30 Mon Sep 17 00:00:00 2001 From: Natsumi Hoshino Date: Thu, 26 Apr 2018 23:11:28 +0900 Subject: [PATCH 34/89] Change listing of available schemes to use directory of executable --- tools/ColorTool/ColorTool/Program.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tools/ColorTool/ColorTool/Program.cs b/tools/ColorTool/ColorTool/Program.cs index 44e507c12e..8557471fc5 100644 --- a/tools/ColorTool/ColorTool/Program.cs +++ b/tools/ColorTool/ColorTool/Program.cs @@ -189,7 +189,9 @@ namespace ColorTool static void PrintSchemes() { - if (Directory.Exists("./schemes")) + var schemeDirectory = new FileInfo(new Uri(Assembly.GetEntryAssembly().GetName().CodeBase).AbsolutePath).Directory.FullName + "/schemes"; + + if (Directory.Exists(schemeDirectory)) { IntPtr handle = GetStdHandle(-11); GetConsoleMode(handle, out var mode); @@ -197,7 +199,7 @@ namespace ColorTool int consoleWidth = Console.WindowWidth; string fgText = " gYw "; - foreach (string schemeName in Directory.GetFiles("./schemes/").Select(Path.GetFileName)) + foreach (string schemeName in Directory.GetFiles(schemeDirectory).Select(Path.GetFileName)) { ColorScheme colorScheme = GetScheme(schemeName, false); if (colorScheme != null) From 8d75ff1bec04329334ea6a38f545aaa767ccf144 Mon Sep 17 00:00:00 2001 From: Mike MacCana Date: Wed, 16 May 2018 17:47:47 +0100 Subject: [PATCH 35/89] Adjust 'ANSI 8' color to be more visible against background. Fixes #180 --- tools/ColorTool/schemes/solarized_dark.itermcolors | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/ColorTool/schemes/solarized_dark.itermcolors b/tools/ColorTool/schemes/solarized_dark.itermcolors index 4a727fb700..24c76f5819 100644 --- a/tools/ColorTool/schemes/solarized_dark.itermcolors +++ b/tools/ColorTool/schemes/solarized_dark.itermcolors @@ -161,9 +161,9 @@ Ansi 8 Color Blue Component - 0.15170273184776306 + 0.39215686274509803 Green Component - 0.11783610284328461 + 0.30196078431372547 Red Component 0.0 From b2ed728bf1c8fc5694e6be3f090ef3fae79d3488 Mon Sep 17 00:00:00 2001 From: Mike MacCana Date: Wed, 16 May 2018 17:59:04 +0100 Subject: [PATCH 36/89] Also update the 'one half dark' dark theme to fix #180 --- tools/ColorTool/schemes/OneHalfDark.itermcolors | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/ColorTool/schemes/OneHalfDark.itermcolors b/tools/ColorTool/schemes/OneHalfDark.itermcolors index 50987c8fab..3dc69aca6a 100644 --- a/tools/ColorTool/schemes/OneHalfDark.itermcolors +++ b/tools/ColorTool/schemes/OneHalfDark.itermcolors @@ -221,13 +221,13 @@ Alpha Component 1 Blue Component - 0.203921568627 + 0.4549019607843137 Color Space Calibrated Green Component - 0.172549019608 + 0.38823529411764707 Red Component - 0.156862745098 + 0.35294117647058826 Ansi 9 Color From aed5f9eae9e176561fb0e5f260b9561e97c72bc9 Mon Sep 17 00:00:00 2001 From: Mike MacCana Date: Wed, 16 May 2018 18:12:39 +0100 Subject: [PATCH 37/89] Add a link to colortool releases page For those who just want the zip / don't have a build environment set up. --- tools/ColorTool/README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tools/ColorTool/README.md b/tools/ColorTool/README.md index fba2abbae8..ae04998b65 100644 --- a/tools/ColorTool/README.md +++ b/tools/ColorTool/README.md @@ -37,6 +37,10 @@ Options: I recommend the excellent [iTerm2-Color-Schemes](https://github.com/mbadolato/iTerm2-Color-Schemes) repo, which has TONS of schemes to choose from, and previews. +## Installing + +Just [https://github.com/Microsoft/console/releases](download the latest colortool release) and extract the zip file. + ## Building Either build with Visual Studio, or use the included `build.bat` from the command line to try and auto-detect your msbuild version. From f735286a7da6df5a9ca73de239e489363f3706a6 Mon Sep 17 00:00:00 2001 From: Mike MacCana Date: Wed, 16 May 2018 18:18:56 +0100 Subject: [PATCH 38/89] Add link to a visual editor for .itermcolors files --- tools/ColorTool/README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/ColorTool/README.md b/tools/ColorTool/README.md index fba2abbae8..11ad216e70 100644 --- a/tools/ColorTool/README.md +++ b/tools/ColorTool/README.md @@ -36,6 +36,8 @@ Options: You can also add color schemes to the colortool easily. Take any existing scheme in `.itermcolors` format, and paste it in the `schemes/` directory. I recommend the excellent [iTerm2-Color-Schemes](https://github.com/mbadolato/iTerm2-Color-Schemes) repo, which has TONS of schemes to choose from, and previews. + + You can also easily visually edit `.itermcolors` color schemes using [terminal.sexy](https://terminal.sexy. Use the **Import** and **Export** tabs with `iTerm2` as the format. ## Building From ae5b5fb5b12c8748310e8ee13338e11366bef7b6 Mon Sep 17 00:00:00 2001 From: Mike MacCana Date: Thu, 17 May 2018 11:28:58 +0100 Subject: [PATCH 39/89] Markdown fixes, also add a description --- tools/ColorTool/README.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tools/ColorTool/README.md b/tools/ColorTool/README.md index b2f5589335..ec2bca1c29 100644 --- a/tools/ColorTool/README.md +++ b/tools/ColorTool/README.md @@ -1,4 +1,6 @@ -# ColorTool - colortool.exe +# ColorTool + +ColorTool makes it easy to change the Windows console to your desired scheme. Includes support for iTerm themes! ``` Usage: @@ -41,7 +43,7 @@ Options: ## Installing -Just [https://github.com/Microsoft/console/releases](download the latest colortool release) and extract the zip file. +Just [download the latest colortool release](https://github.com/Microsoft/console/releases) and extract the zip file. ## Building From 8afb12e74767635f59c3cee172e06d3461389f3f Mon Sep 17 00:00:00 2001 From: minhhai2209 Date: Sun, 20 May 2018 14:39:20 +0700 Subject: [PATCH 40/89] Fixed Markdown link --- tools/ColorTool/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/ColorTool/README.md b/tools/ColorTool/README.md index ec2bca1c29..ad5ee7c625 100644 --- a/tools/ColorTool/README.md +++ b/tools/ColorTool/README.md @@ -39,7 +39,7 @@ Options: I recommend the excellent [iTerm2-Color-Schemes](https://github.com/mbadolato/iTerm2-Color-Schemes) repo, which has TONS of schemes to choose from, and previews. - You can also easily visually edit `.itermcolors` color schemes using [terminal.sexy](https://terminal.sexy. Use the **Import** and **Export** tabs with `iTerm2` as the format. + You can also easily visually edit `.itermcolors` color schemes using [terminal.sexy](https://terminal.sexy). Use the **Import** and **Export** tabs with `iTerm2` as the format. ## Installing From aa20e89a847515427cf16b12c6812dc91c4961ac Mon Sep 17 00:00:00 2001 From: Atif Aziz Date: Thu, 31 May 2018 12:57:52 +0200 Subject: [PATCH 41/89] Consolidate schemes path search code --- tools/ColorTool/ColorTool/IniSchemeParser.cs | 35 +--------------- tools/ColorTool/ColorTool/Scheme.cs | 41 ++++++++++++++++++ tools/ColorTool/ColorTool/XmlSchemeParser.cs | 44 ++++---------------- 3 files changed, 51 insertions(+), 69 deletions(-) create mode 100644 tools/ColorTool/ColorTool/Scheme.cs diff --git a/tools/ColorTool/ColorTool/IniSchemeParser.cs b/tools/ColorTool/ColorTool/IniSchemeParser.cs index 0c3e3903b5..d04eea5be2 100644 --- a/tools/ColorTool/ColorTool/IniSchemeParser.cs +++ b/tools/ColorTool/ColorTool/IniSchemeParser.cs @@ -4,6 +4,7 @@ // using System; +using System.Linq; using System.Text; using System.Runtime.InteropServices; using static ColorTool.ConsoleAPI; @@ -70,41 +71,9 @@ namespace ColorTool } } - // TODO: Abstract the locating of a scheme into a function the implementation can call into - // Both parsers duplicate the searching, they should just pass in their extension and - // a callback for initally validating the file static string FindIniScheme(string schemeName) { - string exeDir = System.IO.Directory.GetParent(System.Reflection.Assembly.GetEntryAssembly().Location).FullName; - string filename = schemeName + ".ini"; - string exeSchemes = exeDir + "/schemes/"; - string cwd = "./"; - string cwdSchemes = "./schemes/"; - // Search order, for argument "name", where 'exe' is the dir of the exe. - // 1. ./name - // 2. ./name.ini - // 3. ./schemes/name - // 4. ./schemes/name.ini - // 5. exe/schemes/name - // 6. exe/schemes/name.ini - // 7. name (as an absolute path) - string[] paths = { - cwd + schemeName, - cwd + filename, - cwdSchemes + schemeName, - cwdSchemes + filename, - exeSchemes + schemeName, - exeSchemes + filename, - schemeName, - }; - foreach (string path in paths) - { - if (File.Exists(path)) - { - return path; - } - } - return null; + return Scheme.GetSearchPaths(schemeName, ".ini").FirstOrDefault(File.Exists); } public ColorScheme ParseScheme(string schemeName, bool reportErrors = true) diff --git a/tools/ColorTool/ColorTool/Scheme.cs b/tools/ColorTool/ColorTool/Scheme.cs new file mode 100644 index 0000000000..3d7eb6ce72 --- /dev/null +++ b/tools/ColorTool/ColorTool/Scheme.cs @@ -0,0 +1,41 @@ +// +// Copyright (C) Microsoft. All rights reserved. +// Licensed under the terms described in the LICENSE file in the root of this project. +// + +using System.Collections.Generic; +using System.IO; + +namespace ColorTool +{ + static class Scheme + { + public static IEnumerable GetSearchPaths(string schemeName, string extension) + { + // Search order, for argument "name", where 'exe' is the dir of the exe. + // 1. ./name + // 2. ./name.ext + // 3. ./schemes/name + // 4. ./schemes/name.ext + // 5. exe/schemes/name + // 6. exe/schemes/name.ext + // 7. name (as an absolute path) + + string cwd = "./"; + yield return cwd + schemeName; + + string filename = schemeName + extension; + yield return cwd + filename; + + string cwdSchemes = "./schemes/"; + yield return cwdSchemes + schemeName; + yield return cwdSchemes + filename; + + string exeDir = Directory.GetParent(System.Reflection.Assembly.GetEntryAssembly().Location).FullName; + string exeSchemes = exeDir + "/schemes/"; + yield return exeSchemes + schemeName; + yield return exeSchemes + filename; + yield return schemeName; + } + } +} \ No newline at end of file diff --git a/tools/ColorTool/ColorTool/XmlSchemeParser.cs b/tools/ColorTool/ColorTool/XmlSchemeParser.cs index e54b8b1c3e..ddf965fd06 100644 --- a/tools/ColorTool/ColorTool/XmlSchemeParser.cs +++ b/tools/ColorTool/ColorTool/XmlSchemeParser.cs @@ -4,6 +4,7 @@ // using System; using System.Globalization; +using System.IO; using System.Linq; using System.Linq.Expressions; using System.Xml; @@ -81,49 +82,20 @@ namespace ColorTool static XmlDocument loadXmlScheme(string schemeName) { XmlDocument xmlDoc = new XmlDocument(); // Create an XML document object - string exeDir = System.IO.Directory.GetParent(System.Reflection.Assembly.GetEntryAssembly().Location).FullName; - bool found = false; - string filename = schemeName + ".itermcolors"; - string exeSchemes = exeDir + "/schemes/"; - string cwd = "./"; - string cwdSchemes = "./schemes/"; - // Search order, for argument "name", where 'exe' is the dir of the exe. - // 1. ./name - // 2. ./name.itermcolors - // 3. ./schemes/name - // 4. ./schemes/name.itermcolors - // 5. exe/schemes/name - // 6. exe/schemes/name.itermcolors - // 7. name (as an absolute path) - string[] paths = { - cwd + schemeName, - cwd + filename, - cwdSchemes + schemeName, - cwdSchemes + filename, - exeSchemes + schemeName, - exeSchemes + filename, - schemeName, - }; - foreach (string path in paths) + foreach (string path in Scheme.GetSearchPaths(schemeName, ".itermcolors") + .Where(File.Exists)) { try { xmlDoc.Load(path); - found = true; - break; - } - catch (Exception /*e*/) - { - // We can either fail to find the file, - // or fail to parse the XML here. + return xmlDoc; } + catch (XmlException /*e*/) { /* failed to parse */ } + catch (IOException /*e*/) { /* failed to find */ } + catch (UnauthorizedAccessException /*e*/) { /* unauthorized */ } } - if (!found) - { - return null; - } - return xmlDoc; + return null; } From 11a65ef0c7ba99a7b928d8c52c2dc78ef4b73125 Mon Sep 17 00:00:00 2001 From: Michael Niksa <18221333+miniksa@users.noreply.github.com> Date: Tue, 5 Jun 2018 10:52:57 -0700 Subject: [PATCH 42/89] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 7beff4be75..c7ed5c9f2f 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,8 @@ This repo is monitored by the Windows Console engineering team, and provides a b The Windows Console engineering team greatly appreciate issues containing concise, detailed issues containing repro-steps, and screenshots where appropriate :) +We also appreciate not +1-ing issues with no additional or actionable information. Please use a reaction to show your support of an existing comment on the thread and/or subscribe to notifications using the button in the sidebar in lieu of providing a low-value comment. + ### Code of Conduct This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact opencode@microsoft.com with any additional questions or comments. From 8dacee626aa027b6aa2cd4d5cc14dc894641f83e Mon Sep 17 00:00:00 2001 From: Joel Bennett Date: Sun, 19 Aug 2018 01:14:29 -0400 Subject: [PATCH 43/89] Fix UIntTocolor --- tools/ColorTool/ColorTool/Program.cs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/tools/ColorTool/ColorTool/Program.cs b/tools/ColorTool/ColorTool/Program.cs index 8557471fc5..a90e3bc98d 100644 --- a/tools/ColorTool/ColorTool/Program.cs +++ b/tools/ColorTool/ColorTool/Program.cs @@ -230,11 +230,10 @@ namespace ColorTool private static Color UIntToColor(uint color) { - byte a = (byte)(color >> 24); - byte r = (byte)(color >> 16); + byte r = (byte)(color >> 0); byte g = (byte)(color >> 8); - byte b = (byte)(color >> 0); - return Color.FromArgb(a, r, g, b); + byte b = (byte)(color >> 16); + return Color.FromArgb(r, g, b); } static bool SetProperties(ColorScheme colorScheme) From 1e6232b75182071cf58e8c23d1b352f12de73725 Mon Sep 17 00:00:00 2001 From: Harry Pierson Date: Mon, 10 Sep 2018 09:38:22 -0700 Subject: [PATCH 44/89] Add support for parsing concfg (https://github.com/lukesampson/concfg) presets --- tools/ColorTool/ColorTool/JsonParser.cs | 92 +++++++++++++++++++++++++ 1 file changed, 92 insertions(+) create mode 100644 tools/ColorTool/ColorTool/JsonParser.cs diff --git a/tools/ColorTool/ColorTool/JsonParser.cs b/tools/ColorTool/ColorTool/JsonParser.cs new file mode 100644 index 0000000000..bf09d72754 --- /dev/null +++ b/tools/ColorTool/ColorTool/JsonParser.cs @@ -0,0 +1,92 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Runtime.Serialization.Json; +using System.Text; +using System.Threading.Tasks; +using System.Xml; +using static ColorTool.ConsoleAPI; + +namespace ColorTool +{ + class JsonParser : ISchemeParser + { + static string[] CONCFG_COLOR_NAMES = { + "black", // DARK_BLACK + "dark_blue", // DARK_BLUE + "dark_green", // DARK_GREEN + "dark_cyan", // DARK_CYAN + "dark_red", // DARK_RED + "dark_magenta", // DARK_MAGENTA + "dark_yellow", // DARK_YELLOW + "gray", // DARK_WHITE + "dark_gray", // BRIGHT_BLACK + "blue", // BRIGHT_BLUE + "green", // BRIGHT_GREEN + "cyan", // BRIGHT_CYAN + "red", // BRIGHT_RED + "magenta", // BRIGHT_MAGENTA + "yellow", // BRIGHT_YELLOW + "white" // BRIGHT_WHITE + }; + + public string Name => "concfg Parser"; + + static uint ParseColor(string arg) + { + System.Drawing.Color col = System.Drawing.ColorTranslator.FromHtml(arg); + return RGB(col.R, col.G, col.B); + } + + static XmlDocument loadJsonFile(string schemeName) + { + XmlDocument xmlDoc = new XmlDocument(); + foreach (string path in Scheme.GetSearchPaths(schemeName, ".json") + .Where(File.Exists)) + { + try + { + var data = File.ReadAllBytes(path); + var reader = JsonReaderWriterFactory.CreateJsonReader(data, System.Xml.XmlDictionaryReaderQuotas.Max); + xmlDoc.Load(reader); + return xmlDoc; + } + catch (XmlException /*e*/) { /* failed to parse */ } + catch (IOException /*e*/) { /* failed to find */ } + catch (UnauthorizedAccessException /*e*/) { /* unauthorized */ } + } + + return null; + } + + public ColorScheme ParseScheme(string schemeName, bool reportErrors = true) + { + XmlDocument xmlDoc = loadJsonFile(schemeName); + if (xmlDoc == null) return null; + + try + { + XmlNode root = xmlDoc.DocumentElement; + XmlNodeList children = root.ChildNodes; + uint[] colorTable = new uint[COLOR_TABLE_SIZE]; ; + for (int i = 0; i < COLOR_TABLE_SIZE; i++) + { + string name = CONCFG_COLOR_NAMES[i]; + var node = children.OfType().Where(n => n.Name == name).Single(); + colorTable[i] = ParseColor(node.InnerText); + } + return new ColorScheme { colorTable = colorTable }; + } + catch (Exception /*e*/) + { + if (reportErrors) + { + Console.WriteLine("failes to load json scheme"); + } + + return null; + } + } + } +} From ac843745fa71728f6e385eed2e27805350d90c89 Mon Sep 17 00:00:00 2001 From: Rich Turner Date: Mon, 10 Sep 2018 20:07:17 -0700 Subject: [PATCH 45/89] Add an example application that uses the pseudoconsole APIs (#247) This sample implements a simple "Echo Console" that illustrates the mechanism by which a caller can directly invoke & communicate with Command-Line applications. 1. Creates two pipes - one for output, the second for output 1. Creates a Pseudo Console attached to the other end of the pipes 1. Creates a child process (an instance of `ping.exe` in this case), attached to the Pseudo Console 1. Creates a thread that reads the input pipe, displaying received text on the screen --- samples/ConPTY/EchoCon/EchoCon.sln | 36 ++++ samples/ConPTY/EchoCon/EchoCon/EchoCon.cpp | 189 ++++++++++++++++++ .../ConPTY/EchoCon/EchoCon/EchoCon.vcxproj | 165 +++++++++++++++ .../EchoCon/EchoCon/EchoCon.vcxproj.filters | 33 +++ samples/ConPTY/EchoCon/EchoCon/stdafx.cpp | 8 + samples/ConPTY/EchoCon/EchoCon/stdafx.h | 13 ++ samples/ConPTY/EchoCon/EchoCon/targetver.h | 8 + samples/ConPTY/EchoCon/readme.md | 34 ++++ 8 files changed, 486 insertions(+) create mode 100644 samples/ConPTY/EchoCon/EchoCon.sln create mode 100644 samples/ConPTY/EchoCon/EchoCon/EchoCon.cpp create mode 100644 samples/ConPTY/EchoCon/EchoCon/EchoCon.vcxproj create mode 100644 samples/ConPTY/EchoCon/EchoCon/EchoCon.vcxproj.filters create mode 100644 samples/ConPTY/EchoCon/EchoCon/stdafx.cpp create mode 100644 samples/ConPTY/EchoCon/EchoCon/stdafx.h create mode 100644 samples/ConPTY/EchoCon/EchoCon/targetver.h create mode 100644 samples/ConPTY/EchoCon/readme.md diff --git a/samples/ConPTY/EchoCon/EchoCon.sln b/samples/ConPTY/EchoCon/EchoCon.sln new file mode 100644 index 0000000000..d198128887 --- /dev/null +++ b/samples/ConPTY/EchoCon/EchoCon.sln @@ -0,0 +1,36 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.27703.2026 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "EchoCon", "EchoCon\EchoCon.vcxproj", "{96274800-9574-423E-892A-909FBE2AC8BE}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{556CAA54-33E0-4F99-95C8-0DFD6E8F6C6B}" + ProjectSection(SolutionItems) = preProject + readme.md = readme.md + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {96274800-9574-423E-892A-909FBE2AC8BE}.Debug|x64.ActiveCfg = Debug|x64 + {96274800-9574-423E-892A-909FBE2AC8BE}.Debug|x64.Build.0 = Debug|x64 + {96274800-9574-423E-892A-909FBE2AC8BE}.Debug|x86.ActiveCfg = Debug|Win32 + {96274800-9574-423E-892A-909FBE2AC8BE}.Debug|x86.Build.0 = Debug|Win32 + {96274800-9574-423E-892A-909FBE2AC8BE}.Release|x64.ActiveCfg = Release|x64 + {96274800-9574-423E-892A-909FBE2AC8BE}.Release|x64.Build.0 = Release|x64 + {96274800-9574-423E-892A-909FBE2AC8BE}.Release|x86.ActiveCfg = Release|Win32 + {96274800-9574-423E-892A-909FBE2AC8BE}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {B27C5007-61E2-4080-965D-8C934367BA4F} + EndGlobalSection +EndGlobal diff --git a/samples/ConPTY/EchoCon/EchoCon/EchoCon.cpp b/samples/ConPTY/EchoCon/EchoCon/EchoCon.cpp new file mode 100644 index 0000000000..904ea5b890 --- /dev/null +++ b/samples/ConPTY/EchoCon/EchoCon/EchoCon.cpp @@ -0,0 +1,189 @@ +// EchoCon.cpp : Entry point for the EchoCon Pseudo-Consle sample application. +// Copyright 2018, Microsoft + +#include "stdafx.h" +#include +#include + +// Forward declarations +HRESULT CreatePseudoConsoleAndPipes(HPCON*, HANDLE*, HANDLE*); +HRESULT InitializeStartupInfoAttachedToPseudoConsole(STARTUPINFOEX*, HPCON); +void __cdecl PipeListener(LPVOID); + +int main() +{ + wchar_t szCommand[]{ L"ping localhost" }; + HRESULT hr{ E_UNEXPECTED }; + HANDLE hConsole = { GetStdHandle(STD_OUTPUT_HANDLE) }; + + // Enable Console VT Processing + DWORD consoleMode{}; + GetConsoleMode(hConsole, &consoleMode); + hr = SetConsoleMode(hConsole, consoleMode | ENABLE_VIRTUAL_TERMINAL_PROCESSING) + ? S_OK + : GetLastError(); + if (S_OK == hr) + { + HPCON hPC{ INVALID_HANDLE_VALUE }; + + // Create the Pseudo Console and pipes to it + HANDLE hPipeIn{ INVALID_HANDLE_VALUE }; + HANDLE hPipeOut{ INVALID_HANDLE_VALUE }; + hr = CreatePseudoConsoleAndPipes(&hPC, &hPipeIn, &hPipeOut); + if (S_OK == hr) + { + // Create & start thread to listen to the incoming pipe + // Note: Using CRT-safe _beginthread() rather than CreateThread() + HANDLE hPipeListenerThread{ reinterpret_cast(_beginthread(PipeListener, 0, hPipeIn)) }; + + // Initialize the necessary startup info struct + STARTUPINFOEX startupInfo{}; + if (S_OK == InitializeStartupInfoAttachedToPseudoConsole(&startupInfo, hPC)) + { + // Launch ping to emit some text back via the pipe + PROCESS_INFORMATION piClient{}; + hr = CreateProcess( + NULL, // No module name - use Command Line + szCommand, // Command Line + NULL, // Process handle not inheritable + NULL, // Thread handle not inheritable + FALSE, // Inherit handles + EXTENDED_STARTUPINFO_PRESENT, // Creation flags + NULL, // Use parent's environment block + NULL, // Use parent's starting directory + &startupInfo.StartupInfo, // Pointer to STARTUPINFO + &piClient) // Pointer to PROCESS_INFORMATION + ? S_OK + : GetLastError(); + + if (S_OK == hr) + { + // Wait up to 10s for ping process to complete + WaitForSingleObject(piClient.hThread, 10 * 1000); + + // Allow listening thread to catch-up with final output! + Sleep(500); + } + + // --- CLOSEDOWN --- + + // Now safe to clean-up client app's process-info & thread + CloseHandle(piClient.hThread); + CloseHandle(piClient.hProcess); + + // Cleanup attribute list + DeleteProcThreadAttributeList(startupInfo.lpAttributeList); + free(startupInfo.lpAttributeList); + } + + // Close ConPTY - this will terminate client process if running + ClosePseudoConsole(hPC); + + // Clean-up the pipes + if (INVALID_HANDLE_VALUE != hPipeOut) CloseHandle(hPipeOut); + if (INVALID_HANDLE_VALUE != hPipeIn) CloseHandle(hPipeIn); + } + } + + return S_OK == hr ? EXIT_SUCCESS : EXIT_FAILURE; +} + +HRESULT CreatePseudoConsoleAndPipes(HPCON* phPC, HANDLE* phPipeIn, HANDLE* phPipeOut) +{ + HRESULT hr{ E_UNEXPECTED }; + HANDLE hPipePTYIn{ INVALID_HANDLE_VALUE }; + HANDLE hPipePTYOut{ INVALID_HANDLE_VALUE }; + + // Create the pipes to which the ConPTY will connect + if (CreatePipe(&hPipePTYIn, phPipeOut, NULL, 0) && + CreatePipe(phPipeIn, &hPipePTYOut, NULL, 0)) + { + // Determine required size of Pseudo Console + COORD consoleSize{}; + CONSOLE_SCREEN_BUFFER_INFO csbi{}; + HANDLE hConsole{ GetStdHandle(STD_OUTPUT_HANDLE) }; + if (GetConsoleScreenBufferInfo(hConsole, &csbi)) + { + consoleSize.X = csbi.srWindow.Right - csbi.srWindow.Left + 1; + consoleSize.Y = csbi.srWindow.Bottom - csbi.srWindow.Top + 1; + } + + // Create the Pseudo Console of the required size, attached to the PTY-end of the pipes + hr = CreatePseudoConsole(consoleSize, hPipePTYIn, hPipePTYOut, 0, phPC); + + // Note: We can close the handles to the PTY-end of the pipes here + // because the handles are dup'ed into the ConHost and will be released + // when the ConPTY is destroyed. + if (INVALID_HANDLE_VALUE != hPipePTYOut) CloseHandle(hPipePTYOut); + if (INVALID_HANDLE_VALUE != hPipePTYIn) CloseHandle(hPipePTYIn); + } + + return hr; +} + +// Initializes the specified startup info struct with the required properties and +// updates its thread attribute list with the specified ConPTY handle +HRESULT InitializeStartupInfoAttachedToPseudoConsole(STARTUPINFOEX* pStartupInfo, HPCON hPC) +{ + HRESULT hr{ E_UNEXPECTED }; + + if (pStartupInfo) + { + size_t attrListSize{}; + + pStartupInfo->StartupInfo.cb = sizeof(STARTUPINFOEX); + + // Get the size of the thread attribute list. + InitializeProcThreadAttributeList(NULL, 1, 0, &attrListSize); + + // Allocate a thread attribute list of the correct size + pStartupInfo->lpAttributeList = + reinterpret_cast(malloc(attrListSize)); + + // Initialize thread attribute list + if (pStartupInfo->lpAttributeList + && InitializeProcThreadAttributeList(pStartupInfo->lpAttributeList, 1, 0, &attrListSize)) + { + // Set Pseudo Console attribute + hr = UpdateProcThreadAttribute( + pStartupInfo->lpAttributeList, + 0, + PROC_THREAD_ATTRIBUTE_PSEUDOCONSOLE, + hPC, + sizeof(HPCON), + NULL, + NULL) + ? S_OK + : HRESULT_FROM_WIN32(GetLastError()); + } + else + { + hr = HRESULT_FROM_WIN32(GetLastError()); + } + } + return hr; +} + +void __cdecl PipeListener(LPVOID pipe) +{ + HANDLE hPipe{ pipe }; + HANDLE hConsole{ GetStdHandle(STD_OUTPUT_HANDLE) }; + + const DWORD BUFF_SIZE{ 512 }; + char szBuffer[BUFF_SIZE]{}; + + DWORD dwBytesWritten{}; + DWORD dwBytesRead{}; + BOOL fRead{ FALSE }; + do + { + // Read from the pipe + fRead = ReadFile(hPipe, szBuffer, BUFF_SIZE, &dwBytesRead, NULL); + + // Write received text to the Console + // Note: Write to the Console using WriteFile(hConsole...), not printf()/puts() to + // prevent partially-read VT sequences from corrupting output + WriteFile(hConsole, szBuffer, dwBytesRead, &dwBytesWritten, NULL); + + } while (fRead && dwBytesRead >= 0); +} diff --git a/samples/ConPTY/EchoCon/EchoCon/EchoCon.vcxproj b/samples/ConPTY/EchoCon/EchoCon/EchoCon.vcxproj new file mode 100644 index 0000000000..42fc73fea5 --- /dev/null +++ b/samples/ConPTY/EchoCon/EchoCon/EchoCon.vcxproj @@ -0,0 +1,165 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 15.0 + {96274800-9574-423E-892A-909FBE2AC8BE} + Win32Proj + EchoCon + 10.0.17738.0 + + + + Application + true + v141 + Unicode + + + Application + false + v141 + true + Unicode + + + Application + true + v141 + Unicode + + + Application + false + v141 + true + Unicode + + + + + + + + + + + + + + + + + + + + + true + + + true + + + false + + + false + + + + Use + Level3 + Disabled + true + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + + + + + Use + Level3 + Disabled + true + _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + + + + + Use + Level3 + MaxSpeed + true + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + Use + Level3 + MaxSpeed + true + true + true + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + + + + + + Create + Create + Create + Create + + + + + + \ No newline at end of file diff --git a/samples/ConPTY/EchoCon/EchoCon/EchoCon.vcxproj.filters b/samples/ConPTY/EchoCon/EchoCon/EchoCon.vcxproj.filters new file mode 100644 index 0000000000..69e0ecfed1 --- /dev/null +++ b/samples/ConPTY/EchoCon/EchoCon/EchoCon.vcxproj.filters @@ -0,0 +1,33 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;ipp;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Header Files + + + Header Files + + + + + Source Files + + + Source Files + + + \ No newline at end of file diff --git a/samples/ConPTY/EchoCon/EchoCon/stdafx.cpp b/samples/ConPTY/EchoCon/EchoCon/stdafx.cpp new file mode 100644 index 0000000000..dec485bab3 --- /dev/null +++ b/samples/ConPTY/EchoCon/EchoCon/stdafx.cpp @@ -0,0 +1,8 @@ +// stdafx.cpp : source file that includes just the standard includes +// EchoCon.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "stdafx.h" + +// TODO: reference any additional headers you need in STDAFX.H +// and not in this file \ No newline at end of file diff --git a/samples/ConPTY/EchoCon/EchoCon/stdafx.h b/samples/ConPTY/EchoCon/EchoCon/stdafx.h new file mode 100644 index 0000000000..1fa6ee20bf --- /dev/null +++ b/samples/ConPTY/EchoCon/EchoCon/stdafx.h @@ -0,0 +1,13 @@ +// stdafx.h : include file for standard system include files, +// or project specific include files that are used frequently, but +// are changed infrequently +// + +#pragma once + +#include "targetver.h" + +#include +#include + +// TODO: reference additional headers your program requires here diff --git a/samples/ConPTY/EchoCon/EchoCon/targetver.h b/samples/ConPTY/EchoCon/EchoCon/targetver.h new file mode 100644 index 0000000000..87c0086de7 --- /dev/null +++ b/samples/ConPTY/EchoCon/EchoCon/targetver.h @@ -0,0 +1,8 @@ +#pragma once + +// Including SDKDDKVer.h defines the highest available Windows platform. + +// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and +// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. + +#include diff --git a/samples/ConPTY/EchoCon/readme.md b/samples/ConPTY/EchoCon/readme.md new file mode 100644 index 0000000000..7d1f3572b1 --- /dev/null +++ b/samples/ConPTY/EchoCon/readme.md @@ -0,0 +1,34 @@ +# "EchoCon" ConPTY Sample App +This is a very simple sample application that illustrates how to use the new Win32 Pseudo Console +(ConPTY) by: + +1. Creating an input and an output pipe +1. Calling `CreatePseudoConsole()` to create a ConPTY instance attached to the other end of the pipes +1. Spawning an instance of `ping.exe` connected to the ConPTY +1. Running a thread that listens for output from ping.exe, writing received text to the Console + +# Pre-Requirements +To build and run this sample, you must install: +* Windows 10 Insider build 17733 or later +* [Latest Windows 10 Insider SDK](https://www.microsoft.com/en-us/software-download/windowsinsiderpreviewSDK) + +# Running the sample +Once successfully built, running EchoCon should clear the screen and display the results of the +echo command: + +``` +Pinging Rincewind [::1] with 32 bytes of data: +Reply from ::1: time<1ms +Reply from ::1: time<1ms +Reply from ::1: time<1ms +Reply from ::1: time<1ms + +Ping statistics for ::1: + Packets: Sent = 4, Received = 4, Lost = 0 (0% loss), +Approximate round trip times in milli-seconds: + Minimum = 0ms, Maximum = 0ms, Average = 0ms +``` + +# Resources +For more information on the new Pseudo Console infrastructure and API, please review +[this blog post](https://blogs.msdn.microsoft.com/commandline/2018/08/02/windows-command-line-introducing-the-windows-pseudo-console-conpty/) From 0884a1bb1da8af789977c18631c0715f00441929 Mon Sep 17 00:00:00 2001 From: Will Fuqua Date: Thu, 20 Sep 2018 22:10:12 +0700 Subject: [PATCH 46/89] add project infrastructure (sln, csproj, readme, etc) --- samples/ConPTY/MiniTerm/MiniTerm.sln | 25 ++++++++ samples/ConPTY/MiniTerm/MiniTerm/App.config | 6 ++ .../ConPTY/MiniTerm/MiniTerm/MiniTerm.csproj | 59 +++++++++++++++++++ .../MiniTerm/Properties/AssemblyInfo.cs | 36 +++++++++++ samples/ConPTY/MiniTerm/README.md | 19 ++++++ 5 files changed, 145 insertions(+) create mode 100644 samples/ConPTY/MiniTerm/MiniTerm.sln create mode 100644 samples/ConPTY/MiniTerm/MiniTerm/App.config create mode 100644 samples/ConPTY/MiniTerm/MiniTerm/MiniTerm.csproj create mode 100644 samples/ConPTY/MiniTerm/MiniTerm/Properties/AssemblyInfo.cs create mode 100644 samples/ConPTY/MiniTerm/README.md diff --git a/samples/ConPTY/MiniTerm/MiniTerm.sln b/samples/ConPTY/MiniTerm/MiniTerm.sln new file mode 100644 index 0000000000..898f6e28b7 --- /dev/null +++ b/samples/ConPTY/MiniTerm/MiniTerm.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.27703.2035 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MiniTerm", "MiniTerm\MiniTerm.csproj", "{121D4818-BD57-433B-8AD5-C4E1ACE7E7C0}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {121D4818-BD57-433B-8AD5-C4E1ACE7E7C0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {121D4818-BD57-433B-8AD5-C4E1ACE7E7C0}.Debug|Any CPU.Build.0 = Debug|Any CPU + {121D4818-BD57-433B-8AD5-C4E1ACE7E7C0}.Release|Any CPU.ActiveCfg = Release|Any CPU + {121D4818-BD57-433B-8AD5-C4E1ACE7E7C0}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {EFB13BDE-C952-4311-9FE7-35EFDAC8F021} + EndGlobalSection +EndGlobal diff --git a/samples/ConPTY/MiniTerm/MiniTerm/App.config b/samples/ConPTY/MiniTerm/MiniTerm/App.config new file mode 100644 index 0000000000..56efbc7b5f --- /dev/null +++ b/samples/ConPTY/MiniTerm/MiniTerm/App.config @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/samples/ConPTY/MiniTerm/MiniTerm/MiniTerm.csproj b/samples/ConPTY/MiniTerm/MiniTerm/MiniTerm.csproj new file mode 100644 index 0000000000..88b6940cee --- /dev/null +++ b/samples/ConPTY/MiniTerm/MiniTerm/MiniTerm.csproj @@ -0,0 +1,59 @@ + + + + + Debug + AnyCPU + {121D4818-BD57-433B-8AD5-C4E1ACE7E7C0} + Exe + MiniTerm + MiniTerm + v4.7.2 + 512 + true + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/samples/ConPTY/MiniTerm/MiniTerm/Properties/AssemblyInfo.cs b/samples/ConPTY/MiniTerm/MiniTerm/Properties/AssemblyInfo.cs new file mode 100644 index 0000000000..b38d4e859a --- /dev/null +++ b/samples/ConPTY/MiniTerm/MiniTerm/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("MiniPty")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("MiniPty")] +[assembly: AssemblyCopyright("Copyright © 2018")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("121d4818-bd57-433b-8ad5-c4e1ace7e7c0")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/samples/ConPTY/MiniTerm/README.md b/samples/ConPTY/MiniTerm/README.md new file mode 100644 index 0000000000..780202feb9 --- /dev/null +++ b/samples/ConPTY/MiniTerm/README.md @@ -0,0 +1,19 @@ +# MiniTerm + +Experimental terminal using the new PTY APIs from Microsoft. Written in C#, and heavily based on the native code examples. + +## Status + +Demonstrates the basic API calls required, but not intended for "real-world" usage. + +## Resources + +- [Introductory blog post from Microsoft](https://blogs.msdn.microsoft.com/commandline/2018/08/02/windows-command-line-introducing-the-windows-pseudo-console-conpty/) +- [MSDN Documentation](https://docs.microsoft.com/en-us/windows/console/creating-a-pseudoconsole-session) + +## System Requirements + +See the Introductory blog post from Microsoft for the full setup instructions. This project has been tested with: + +- OS: Windows 10 Pro Build 17744 +- SDK: Windows_InsiderPreview_SDK_en-us_17749 From e09359138ee3c8abe4854224db26771c484c38cf Mon Sep 17 00:00:00 2001 From: Will Fuqua Date: Thu, 20 Sep 2018 22:11:55 +0700 Subject: [PATCH 47/89] add pinvoke signatures --- .../MiniTerm/MiniTerm/Native/ConsoleApi.cs | 38 ++++++++ .../MiniTerm/MiniTerm/Native/ProcessApi.cs | 86 +++++++++++++++++++ .../MiniTerm/Native/PseudoConsoleApi.cs | 36 ++++++++ 3 files changed, 160 insertions(+) create mode 100644 samples/ConPTY/MiniTerm/MiniTerm/Native/ConsoleApi.cs create mode 100644 samples/ConPTY/MiniTerm/MiniTerm/Native/ProcessApi.cs create mode 100644 samples/ConPTY/MiniTerm/MiniTerm/Native/PseudoConsoleApi.cs diff --git a/samples/ConPTY/MiniTerm/MiniTerm/Native/ConsoleApi.cs b/samples/ConPTY/MiniTerm/MiniTerm/Native/ConsoleApi.cs new file mode 100644 index 0000000000..1e82176b56 --- /dev/null +++ b/samples/ConPTY/MiniTerm/MiniTerm/Native/ConsoleApi.cs @@ -0,0 +1,38 @@ +using Microsoft.Win32.SafeHandles; +using System.Runtime.InteropServices; + +namespace MiniTerm.Native +{ + /// + /// PInvoke signatures for win32 console api + /// + static class ConsoleApi + { + internal const int STD_OUTPUT_HANDLE = -11; + internal const uint ENABLE_VIRTUAL_TERMINAL_PROCESSING = 0x0004; + internal const uint DISABLE_NEWLINE_AUTO_RETURN = 0x0008; + + [DllImport("kernel32.dll", SetLastError = true)] + internal static extern SafeFileHandle GetStdHandle(int nStdHandle); + + [DllImport("kernel32.dll", SetLastError = true)] + internal static extern bool SetConsoleMode(SafeFileHandle hConsoleHandle, uint mode); + + [DllImport("kernel32.dll", SetLastError = true)] + internal static extern bool GetConsoleMode(SafeFileHandle handle, out uint mode); + + internal delegate bool ConsoleEventDelegate(CtrlTypes ctrlType); + + internal enum CtrlTypes : uint + { + CTRL_C_EVENT = 0, + CTRL_BREAK_EVENT, + CTRL_CLOSE_EVENT, + CTRL_LOGOFF_EVENT = 5, + CTRL_SHUTDOWN_EVENT + } + + [DllImport("kernel32.dll", SetLastError = true)] + internal static extern bool SetConsoleCtrlHandler(ConsoleEventDelegate callback, bool add); + } +} diff --git a/samples/ConPTY/MiniTerm/MiniTerm/Native/ProcessApi.cs b/samples/ConPTY/MiniTerm/MiniTerm/Native/ProcessApi.cs new file mode 100644 index 0000000000..0bf1f6c9cb --- /dev/null +++ b/samples/ConPTY/MiniTerm/MiniTerm/Native/ProcessApi.cs @@ -0,0 +1,86 @@ +using System; +using System.Runtime.InteropServices; + +namespace MiniTerm.Native +{ + /// + /// PInvoke signatures for win32 process api + /// + static class ProcessApi + { + internal const uint EXTENDED_STARTUPINFO_PRESENT = 0x00080000; + + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] + internal struct STARTUPINFOEX + { + public STARTUPINFO StartupInfo; + public IntPtr lpAttributeList; + } + + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] + internal struct STARTUPINFO + { + public Int32 cb; + public string lpReserved; + public string lpDesktop; + public string lpTitle; + public Int32 dwX; + public Int32 dwY; + public Int32 dwXSize; + public Int32 dwYSize; + public Int32 dwXCountChars; + public Int32 dwYCountChars; + public Int32 dwFillAttribute; + public Int32 dwFlags; + public Int16 wShowWindow; + public Int16 cbReserved2; + public IntPtr lpReserved2; + public IntPtr hStdInput; + public IntPtr hStdOutput; + public IntPtr hStdError; + } + + [StructLayout(LayoutKind.Sequential)] + internal struct PROCESS_INFORMATION + { + public IntPtr hProcess; + public IntPtr hThread; + public int dwProcessId; + public int dwThreadId; + } + + [StructLayout(LayoutKind.Sequential)] + internal struct SECURITY_ATTRIBUTES + { + public int nLength; + public IntPtr lpSecurityDescriptor; + public int bInheritHandle; + } + + [DllImport("kernel32.dll", SetLastError = true)] + [return: MarshalAs(UnmanagedType.Bool)] + internal static extern bool InitializeProcThreadAttributeList( + IntPtr lpAttributeList, int dwAttributeCount, int dwFlags, ref IntPtr lpSize); + + [DllImport("kernel32.dll", SetLastError = true)] + [return: MarshalAs(UnmanagedType.Bool)] + internal static extern bool UpdateProcThreadAttribute( + IntPtr lpAttributeList, uint dwFlags, IntPtr attribute, IntPtr lpValue, + IntPtr cbSize, IntPtr lpPreviousValue, IntPtr lpReturnSize); + + [DllImport("kernel32.dll")] + [return: MarshalAs(UnmanagedType.Bool)] + internal static extern bool CreateProcess( + string lpApplicationName, string lpCommandLine, ref SECURITY_ATTRIBUTES lpProcessAttributes, + ref SECURITY_ATTRIBUTES lpThreadAttributes, bool bInheritHandles, uint dwCreationFlags, + IntPtr lpEnvironment, string lpCurrentDirectory, [In] ref STARTUPINFOEX lpStartupInfo, + out PROCESS_INFORMATION lpProcessInformation); + + [DllImport("kernel32.dll", SetLastError = true)] + [return: MarshalAs(UnmanagedType.Bool)] + internal static extern bool DeleteProcThreadAttributeList(IntPtr lpAttributeList); + + [DllImport("kernel32.dll", SetLastError = true)] + internal static extern bool CloseHandle(IntPtr hObject); + } +} diff --git a/samples/ConPTY/MiniTerm/MiniTerm/Native/PseudoConsoleApi.cs b/samples/ConPTY/MiniTerm/MiniTerm/Native/PseudoConsoleApi.cs new file mode 100644 index 0000000000..71e26ee79d --- /dev/null +++ b/samples/ConPTY/MiniTerm/MiniTerm/Native/PseudoConsoleApi.cs @@ -0,0 +1,36 @@ +using Microsoft.Win32.SafeHandles; +using System; +using System.Runtime.InteropServices; + +namespace MiniTerm.Native +{ + /// + /// PInvoke signatures for win32 pseudo console api + /// + static class PseudoConsoleApi + { + internal const uint PROC_THREAD_ATTRIBUTE_PSEUDOCONSOLE = 0x00020016; + + [StructLayout(LayoutKind.Sequential)] + internal struct COORD + { + public short X; + public short Y; + } + + [DllImport("kernel32.dll", SetLastError = true)] + internal static extern int CreatePseudoConsole(COORD size, SafeFileHandle hInput, SafeFileHandle hOutput, uint dwFlags, out IntPtr phPC); + + [DllImport("kernel32.dll", SetLastError = true)] + internal static extern int CreatePseudoConsole(COORD size, IntPtr hInput, IntPtr hOutput, uint dwFlags, out IntPtr phPC); + + [DllImport("kernel32.dll", SetLastError = true)] + internal static extern int ResizePseudoConsole(IntPtr hPC, COORD size); + + [DllImport("kernel32.dll", SetLastError = true)] + internal static extern int ClosePseudoConsole(IntPtr hPC); + + [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] + internal static extern bool CreatePipe(out SafeFileHandle hReadPipe, out SafeFileHandle hWritePipe, IntPtr lpPipeAttributes, int nSize); + } +} From 637c57473e923e5185c79c0b7d72beacf894be62 Mon Sep 17 00:00:00 2001 From: Will Fuqua Date: Thu, 20 Sep 2018 22:13:37 +0700 Subject: [PATCH 48/89] add c# files - Move from rather ad-hoc, error-prone resource management to IDisposable, which should give us a bit more enforcement. - Optimistically remove "buggy" from readme because the known bugs are now fixed! The main source of bugs was the incorrect InitializeProcThreadAttributeList usage. - Handle ctrl-c by forwarding it to the PseudoConsole - Handle terminal close when the window close button is used - Use .NET's CopyTo in the CopyPipeToOutput, it's much simpler code and seems more robust than the ReadFile/WriteFile approach - Minor refactor to split native APIs to multiple files --- samples/ConPTY/MiniTerm/MiniTerm/Process.cs | 133 ++++++++++++++++ samples/ConPTY/MiniTerm/MiniTerm/Program.cs | 35 ++++ .../ConPTY/MiniTerm/MiniTerm/PseudoConsole.cs | 39 +++++ .../MiniTerm/MiniTerm/PseudoConsolePipe.cs | 33 ++++ samples/ConPTY/MiniTerm/MiniTerm/Terminal.cs | 150 ++++++++++++++++++ 5 files changed, 390 insertions(+) create mode 100644 samples/ConPTY/MiniTerm/MiniTerm/Process.cs create mode 100644 samples/ConPTY/MiniTerm/MiniTerm/Program.cs create mode 100644 samples/ConPTY/MiniTerm/MiniTerm/PseudoConsole.cs create mode 100644 samples/ConPTY/MiniTerm/MiniTerm/PseudoConsolePipe.cs create mode 100644 samples/ConPTY/MiniTerm/MiniTerm/Terminal.cs diff --git a/samples/ConPTY/MiniTerm/MiniTerm/Process.cs b/samples/ConPTY/MiniTerm/MiniTerm/Process.cs new file mode 100644 index 0000000000..be79b5fb3e --- /dev/null +++ b/samples/ConPTY/MiniTerm/MiniTerm/Process.cs @@ -0,0 +1,133 @@ +using System; +using System.Runtime.InteropServices; +using static MiniTerm.Native.ProcessApi; + +namespace MiniTerm +{ + /// + /// Support for starting and configuring processes. + /// + /// + /// Possible to replace with managed code? The key is being able to provide the PROC_THREAD_ATTRIBUTE_PSEUDOCONSOLE attribute + /// + static class Process + { + /// + /// Start and configure a process. The return value should be considered opaque, and eventually disposed. + /// + internal static ProcessResources Start(IntPtr hPC, string command, IntPtr attributes) + { + var startupInfo = ConfigureProcessThread(hPC, attributes); + var processInfo = RunProcess(ref startupInfo, "cmd.exe"); + return new ProcessResources(startupInfo, processInfo); + } + + private static STARTUPINFOEX ConfigureProcessThread(IntPtr hPC, IntPtr attributes) + { + var lpSize = IntPtr.Zero; + var success = InitializeProcThreadAttributeList( + lpAttributeList: IntPtr.Zero, + dwAttributeCount: 1, + dwFlags: 0, + lpSize: ref lpSize + ); + if (success || lpSize == IntPtr.Zero) // we're not expecting `success` here, we just want to get the calculated lpSize + { + throw new InvalidOperationException("Could not calculate the number of bytes for the attribute list. " + Marshal.GetLastWin32Error()); + } + + var startupInfo = new STARTUPINFOEX(); + startupInfo.StartupInfo.cb = Marshal.SizeOf(); + startupInfo.lpAttributeList = Marshal.AllocHGlobal(lpSize); + + success = InitializeProcThreadAttributeList( + lpAttributeList: startupInfo.lpAttributeList, + dwAttributeCount: 1, + dwFlags: 0, + lpSize: ref lpSize + ); + if (!success) + { + throw new InvalidOperationException("Could not set up attribute list. " + Marshal.GetLastWin32Error()); + } + + success = UpdateProcThreadAttribute( + lpAttributeList: startupInfo.lpAttributeList, + dwFlags: 0, + attribute: attributes, + lpValue: hPC, + cbSize: (IntPtr)IntPtr.Size, + lpPreviousValue: IntPtr.Zero, + lpReturnSize: IntPtr.Zero + ); + if (!success) + { + throw new InvalidOperationException("Could not set pseudoconsole thread attribute. " + Marshal.GetLastWin32Error()); + } + + return startupInfo; + } + + private static PROCESS_INFORMATION RunProcess(ref STARTUPINFOEX sInfoEx, string commandLine) + { + int securityAttributeSize = Marshal.SizeOf(); + var pSec = new SECURITY_ATTRIBUTES { nLength = securityAttributeSize }; + var tSec = new SECURITY_ATTRIBUTES { nLength = securityAttributeSize }; + var success = CreateProcess( + lpApplicationName: null, + lpCommandLine: commandLine, + lpProcessAttributes: ref pSec, + lpThreadAttributes: ref tSec, + bInheritHandles: false, + dwCreationFlags: EXTENDED_STARTUPINFO_PRESENT, + lpEnvironment: IntPtr.Zero, + lpCurrentDirectory: null, + lpStartupInfo: ref sInfoEx, + lpProcessInformation: out PROCESS_INFORMATION pInfo + ); + if (!success) + { + throw new InvalidOperationException("Could not create process. " + Marshal.GetLastWin32Error()); + } + + return pInfo; + } + + private static void CleanUp(STARTUPINFOEX startupInfo, PROCESS_INFORMATION processInfo) + { + // Free the attribute list + if (startupInfo.lpAttributeList != IntPtr.Zero) + { + DeleteProcThreadAttributeList(startupInfo.lpAttributeList); + Marshal.FreeHGlobal(startupInfo.lpAttributeList); + } + + // Close process and thread handles + if (processInfo.hProcess != IntPtr.Zero) + { + CloseHandle(processInfo.hProcess); + } + if (processInfo.hThread != IntPtr.Zero) + { + CloseHandle(processInfo.hThread); + } + } + + internal sealed class ProcessResources : IDisposable + { + public ProcessResources(STARTUPINFOEX startupInfo, PROCESS_INFORMATION processInfo) + { + StartupInfo = startupInfo; + ProcessInfo = processInfo; + } + + STARTUPINFOEX StartupInfo { get; } + PROCESS_INFORMATION ProcessInfo { get; } + + public void Dispose() + { + CleanUp(StartupInfo, ProcessInfo); + } + } + } +} diff --git a/samples/ConPTY/MiniTerm/MiniTerm/Program.cs b/samples/ConPTY/MiniTerm/MiniTerm/Program.cs new file mode 100644 index 0000000000..6af24169f3 --- /dev/null +++ b/samples/ConPTY/MiniTerm/MiniTerm/Program.cs @@ -0,0 +1,35 @@ +using System; + +namespace MiniTerm +{ + /// + /// C# version of: + /// https://blogs.msdn.microsoft.com/commandline/2018/08/02/windows-command-line-introducing-the-windows-pseudo-console-conpty/ + /// https://docs.microsoft.com/en-us/windows/console/creating-a-pseudoconsole-session + /// + /// System Requirements: + /// As of September 2018, requires Windows 10 with the "Windows Insider Program" installed for Redstone 5. + /// Also requires the Windows Insider Preview SDK: https://www.microsoft.com/en-us/software-download/windowsinsiderpreviewSDK + /// + /// + /// Basic design is: + /// Terminal UI starts the PseudoConsole, and controls it using a pair of PseudoConsolePipes + /// Terminal UI will run the Process (cmd.exe) and associate it with the PseudoConsole. + /// + static class Program + { + static void Main(string[] args) + { + try + { + var terminal = new Terminal(); + terminal.Run("cmd.exe"); + } + catch (InvalidOperationException e) + { + Console.Error.WriteLine(e.Message); + throw; + } + } + } +} diff --git a/samples/ConPTY/MiniTerm/MiniTerm/PseudoConsole.cs b/samples/ConPTY/MiniTerm/MiniTerm/PseudoConsole.cs new file mode 100644 index 0000000000..b0072033d4 --- /dev/null +++ b/samples/ConPTY/MiniTerm/MiniTerm/PseudoConsole.cs @@ -0,0 +1,39 @@ +using Microsoft.Win32.SafeHandles; +using System; +using static MiniTerm.Native.PseudoConsoleApi; + +namespace MiniTerm +{ + /// + /// Utility functions around the new Pseudo Console APIs + /// + internal sealed class PseudoConsole : IDisposable + { + public static readonly IntPtr PseudoConsoleThreadAttribute = (IntPtr)PROC_THREAD_ATTRIBUTE_PSEUDOCONSOLE; + + public IntPtr Handle { get; } + + private PseudoConsole(IntPtr handle) + { + this.Handle = handle; + } + + internal static PseudoConsole Create(SafeFileHandle inputReadSide, SafeFileHandle outputWriteSide, int width, int height) + { + var createResult = CreatePseudoConsole( + new COORD { X = (short)width, Y = (short)height }, + inputReadSide, outputWriteSide, + 0, out IntPtr hPC); + if(createResult != 0) + { + throw new InvalidOperationException("Could not create psuedo console. Error Code " + createResult); + } + return new PseudoConsole(hPC); + } + + public void Dispose() + { + ClosePseudoConsole(Handle); + } + } +} diff --git a/samples/ConPTY/MiniTerm/MiniTerm/PseudoConsolePipe.cs b/samples/ConPTY/MiniTerm/MiniTerm/PseudoConsolePipe.cs new file mode 100644 index 0000000000..d2e36d6f0c --- /dev/null +++ b/samples/ConPTY/MiniTerm/MiniTerm/PseudoConsolePipe.cs @@ -0,0 +1,33 @@ +using Microsoft.Win32.SafeHandles; +using System; +using static MiniTerm.Native.PseudoConsoleApi; + +namespace MiniTerm +{ + /// + /// A pipe used to talk to the pseudoconsole, as described in: + /// https://docs.microsoft.com/en-us/windows/console/creating-a-pseudoconsole-session + /// + /// + /// We'll have two instances of this class, one for input and one for output. + /// + internal sealed class PseudoConsolePipe : IDisposable + { + public SafeFileHandle ReadSide; + public SafeFileHandle WriteSide; + + public PseudoConsolePipe() + { + if (!CreatePipe(out ReadSide, out WriteSide, IntPtr.Zero, 0)) + { + throw new InvalidOperationException("failed to create pipe"); + } + } + + public void Dispose() + { + ReadSide.Dispose(); + WriteSide.Dispose(); + } + } +} diff --git a/samples/ConPTY/MiniTerm/MiniTerm/Terminal.cs b/samples/ConPTY/MiniTerm/MiniTerm/Terminal.cs new file mode 100644 index 0000000000..546355c542 --- /dev/null +++ b/samples/ConPTY/MiniTerm/MiniTerm/Terminal.cs @@ -0,0 +1,150 @@ +using Microsoft.Win32.SafeHandles; +using System; +using System.IO; +using System.Text; +using System.Threading.Tasks; +using static MiniTerm.Native.ConsoleApi; + +namespace MiniTerm +{ + /// + /// The UI of the terminal. It's just a normal console window, but we're managing the input/output. + /// In a "real" project this could be some other UI. + /// + internal sealed class Terminal + { + private const string ExitCommand = "exit\r"; + private const string CtrlC_Command = "\x3"; + + public Terminal() + { + EnableVirtualTerminalSequenceProcessing(); + } + + /// + /// Newer versions of the windows console support interpreting virtual terminal sequences, we just have to opt-in + /// + private static void EnableVirtualTerminalSequenceProcessing() + { + var iStdOut = GetStdHandle(STD_OUTPUT_HANDLE); + if (!GetConsoleMode(iStdOut, out uint outConsoleMode)) + { + throw new InvalidOperationException("Could not get console mode"); + } + + outConsoleMode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING | DISABLE_NEWLINE_AUTO_RETURN; + if (!SetConsoleMode(iStdOut, outConsoleMode)) + { + throw new InvalidOperationException("Could not enable virtual terminal processing"); + } + } + + /// + /// Start the psuedoconsole and run the process as shown in + /// https://docs.microsoft.com/en-us/windows/console/creating-a-pseudoconsole-session#creating-the-pseudoconsole + /// + /// the command to run, e.g. cmd.exe + public void Run(string command) + { + using (var inputPipe = new PseudoConsolePipe()) + using (var outputPipe = new PseudoConsolePipe()) + using (var pseudoConsole = PseudoConsole.Create(inputPipe.ReadSide, outputPipe.WriteSide, Console.WindowWidth, Console.WindowHeight)) + using (var process = Process.Start(pseudoConsole.Handle, command, PseudoConsole.PseudoConsoleThreadAttribute)) + { + // set up a background task to copy all pseudoconsole output to stdout + Task.Run(() => CopyPipeToOutput(outputPipe.ReadSide)); + + // free resources in case the console is ungracefully closed (e.g. by the 'x' in the window titlebar) + OnClose(() => DisposeResources(process, pseudoConsole, outputPipe, inputPipe)); + + // prompt for stdin input and send the result to the pipe. + // blocks until the user types "exit" + CopyInputToPipe(inputPipe.WriteSide); + } + } + + /// + /// Reads terminal input and copies it to the PseudoConsole + /// + /// the "write" side of the pseudo console input pipe + private static void CopyInputToPipe(SafeFileHandle inputWriteSide) + { + using (var writer = new StreamWriter(new FileStream(inputWriteSide, FileAccess.Write))) + { + ForwardCtrlC(writer); + writer.AutoFlush = true; + writer.WriteLine(@"cd \"); + + StringBuilder buffer = new StringBuilder(); + while (true) + { + // send input character-by-character to the pipe + char key = Console.ReadKey(intercept: true).KeyChar; + writer.Write(key); + + // stop the input loop if 'exit' was sent + // TODO: if we have nested cmd.exe process, this will kill all of them which is wrong. + // could we somehow detect when the top-level cmd.exe process has ended and remove this logic? + buffer.Append(key); + if (key == '\r') + { + if (buffer.ToString() == ExitCommand) + { + break; + } + buffer.Clear(); + } + } + } + } + + /// + /// Don't let ctrl-c kill the terminal, it should be sent to the process in the terminal. + /// + private static void ForwardCtrlC(StreamWriter writer) + { + Console.CancelKeyPress += (sender, e) => + { + e.Cancel = true; + writer.Write(CtrlC_Command); + }; + } + + /// + /// Reads PseudoConsole output and copies it to the terminal's standard out. + /// + /// the "read" side of the pseudo console output pipe + private static void CopyPipeToOutput(SafeFileHandle outputReadSide) + { + using (var terminalOutput = Console.OpenStandardOutput()) + using (var pseudoConsoleOutput = new FileStream(outputReadSide, FileAccess.Read)) + { + pseudoConsoleOutput.CopyTo(terminalOutput); + } + } + + /// + /// Set a callback for when the terminal is closed (e.g. via the "X" window decoration button). + /// Intended for resource cleanup logic. + /// + private static void OnClose(Action handler) + { + SetConsoleCtrlHandler(eventType => + { + if(eventType == CtrlTypes.CTRL_CLOSE_EVENT) + { + handler(); + } + return false; + }, true); + } + + private void DisposeResources(params IDisposable[] disposables) + { + foreach (var disposable in disposables) + { + disposable.Dispose(); + } + } + } +} From bf32b8d48f16b238aa5cb2044efc4b612f1ade2d Mon Sep 17 00:00:00 2001 From: Will Fuqua Date: Fri, 21 Sep 2018 07:29:09 +0700 Subject: [PATCH 49/89] implement dispose pattern - Full Dispose Pattern for ProcessResources since it has unmanaged resources - Basic Dispose Pattern for PseudoConsolePipe since it has managed resources - Fix naming of iStdOut to hStdOut - Change parameter order of Process.Start to make more sense --- .../MiniTerm/Native/PseudoConsoleApi.cs | 3 - samples/ConPTY/MiniTerm/MiniTerm/Process.cs | 73 +++++++++++++------ .../MiniTerm/MiniTerm/PseudoConsolePipe.cs | 17 ++++- samples/ConPTY/MiniTerm/MiniTerm/Terminal.cs | 10 +-- 4 files changed, 71 insertions(+), 32 deletions(-) diff --git a/samples/ConPTY/MiniTerm/MiniTerm/Native/PseudoConsoleApi.cs b/samples/ConPTY/MiniTerm/MiniTerm/Native/PseudoConsoleApi.cs index 71e26ee79d..8ad317550c 100644 --- a/samples/ConPTY/MiniTerm/MiniTerm/Native/PseudoConsoleApi.cs +++ b/samples/ConPTY/MiniTerm/MiniTerm/Native/PseudoConsoleApi.cs @@ -21,9 +21,6 @@ namespace MiniTerm.Native [DllImport("kernel32.dll", SetLastError = true)] internal static extern int CreatePseudoConsole(COORD size, SafeFileHandle hInput, SafeFileHandle hOutput, uint dwFlags, out IntPtr phPC); - [DllImport("kernel32.dll", SetLastError = true)] - internal static extern int CreatePseudoConsole(COORD size, IntPtr hInput, IntPtr hOutput, uint dwFlags, out IntPtr phPC); - [DllImport("kernel32.dll", SetLastError = true)] internal static extern int ResizePseudoConsole(IntPtr hPC, COORD size); diff --git a/samples/ConPTY/MiniTerm/MiniTerm/Process.cs b/samples/ConPTY/MiniTerm/MiniTerm/Process.cs index be79b5fb3e..3756077e2a 100644 --- a/samples/ConPTY/MiniTerm/MiniTerm/Process.cs +++ b/samples/ConPTY/MiniTerm/MiniTerm/Process.cs @@ -1,6 +1,7 @@ using System; using System.Runtime.InteropServices; using static MiniTerm.Native.ProcessApi; +using static MiniTerm.Native.PseudoConsoleApi; namespace MiniTerm { @@ -15,7 +16,7 @@ namespace MiniTerm /// /// Start and configure a process. The return value should be considered opaque, and eventually disposed. /// - internal static ProcessResources Start(IntPtr hPC, string command, IntPtr attributes) + internal static ProcessResources Start(string command, IntPtr attributes, IntPtr hPC) { var startupInfo = ConfigureProcessThread(hPC, attributes); var processInfo = RunProcess(ref startupInfo, "cmd.exe"); @@ -93,26 +94,6 @@ namespace MiniTerm return pInfo; } - private static void CleanUp(STARTUPINFOEX startupInfo, PROCESS_INFORMATION processInfo) - { - // Free the attribute list - if (startupInfo.lpAttributeList != IntPtr.Zero) - { - DeleteProcThreadAttributeList(startupInfo.lpAttributeList); - Marshal.FreeHGlobal(startupInfo.lpAttributeList); - } - - // Close process and thread handles - if (processInfo.hProcess != IntPtr.Zero) - { - CloseHandle(processInfo.hProcess); - } - if (processInfo.hThread != IntPtr.Zero) - { - CloseHandle(processInfo.hThread); - } - } - internal sealed class ProcessResources : IDisposable { public ProcessResources(STARTUPINFOEX startupInfo, PROCESS_INFORMATION processInfo) @@ -124,10 +105,58 @@ namespace MiniTerm STARTUPINFOEX StartupInfo { get; } PROCESS_INFORMATION ProcessInfo { get; } + #region IDisposable Support + + private bool disposedValue = false; // To detect redundant calls + + void Dispose(bool disposing) + { + if (!disposedValue) + { + if (disposing) + { + // dispose managed state (managed objects). + } + + // dispose unmanaged state + + // Free the attribute list + if (StartupInfo.lpAttributeList != IntPtr.Zero) + { + DeleteProcThreadAttributeList(StartupInfo.lpAttributeList); + Marshal.FreeHGlobal(StartupInfo.lpAttributeList); + } + + // Close process and thread handles + if (ProcessInfo.hProcess != IntPtr.Zero) + { + CloseHandle(ProcessInfo.hProcess); + } + if (ProcessInfo.hThread != IntPtr.Zero) + { + CloseHandle(ProcessInfo.hThread); + } + + disposedValue = true; + } + } + + ~ProcessResources() + { + // Do not change this code. Put cleanup code in Dispose(bool disposing) above. + Dispose(false); + } + + // This code added to correctly implement the disposable pattern. public void Dispose() { - CleanUp(StartupInfo, ProcessInfo); + // Do not change this code. Put cleanup code in Dispose(bool disposing) above. + Dispose(true); + // use the following line if the finalizer is overridden above. + GC.SuppressFinalize(this); } + + #endregion } } } diff --git a/samples/ConPTY/MiniTerm/MiniTerm/PseudoConsolePipe.cs b/samples/ConPTY/MiniTerm/MiniTerm/PseudoConsolePipe.cs index d2e36d6f0c..604afb2d17 100644 --- a/samples/ConPTY/MiniTerm/MiniTerm/PseudoConsolePipe.cs +++ b/samples/ConPTY/MiniTerm/MiniTerm/PseudoConsolePipe.cs @@ -24,10 +24,23 @@ namespace MiniTerm } } + #region IDisposable + + void Dispose(bool disposing) + { + if (disposing) + { + ReadSide?.Dispose(); + WriteSide?.Dispose(); + } + } + public void Dispose() { - ReadSide.Dispose(); - WriteSide.Dispose(); + Dispose(true); + GC.SuppressFinalize(this); } + + #endregion } } diff --git a/samples/ConPTY/MiniTerm/MiniTerm/Terminal.cs b/samples/ConPTY/MiniTerm/MiniTerm/Terminal.cs index 546355c542..8de735628b 100644 --- a/samples/ConPTY/MiniTerm/MiniTerm/Terminal.cs +++ b/samples/ConPTY/MiniTerm/MiniTerm/Terminal.cs @@ -26,14 +26,14 @@ namespace MiniTerm /// private static void EnableVirtualTerminalSequenceProcessing() { - var iStdOut = GetStdHandle(STD_OUTPUT_HANDLE); - if (!GetConsoleMode(iStdOut, out uint outConsoleMode)) + var hStdOut = GetStdHandle(STD_OUTPUT_HANDLE); + if (!GetConsoleMode(hStdOut, out uint outConsoleMode)) { throw new InvalidOperationException("Could not get console mode"); } outConsoleMode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING | DISABLE_NEWLINE_AUTO_RETURN; - if (!SetConsoleMode(iStdOut, outConsoleMode)) + if (!SetConsoleMode(hStdOut, outConsoleMode)) { throw new InvalidOperationException("Could not enable virtual terminal processing"); } @@ -48,8 +48,8 @@ namespace MiniTerm { using (var inputPipe = new PseudoConsolePipe()) using (var outputPipe = new PseudoConsolePipe()) - using (var pseudoConsole = PseudoConsole.Create(inputPipe.ReadSide, outputPipe.WriteSide, Console.WindowWidth, Console.WindowHeight)) - using (var process = Process.Start(pseudoConsole.Handle, command, PseudoConsole.PseudoConsoleThreadAttribute)) + using (var pseudoConsole = PseudoConsole.Create(inputPipe.ReadSide, outputPipe.WriteSide, (short)Console.WindowWidth, (short)Console.WindowHeight)) + using (var process = Process.Start(command, PseudoConsole.PseudoConsoleThreadAttribute, pseudoConsole.Handle)) { // set up a background task to copy all pseudoconsole output to stdout Task.Run(() => CopyPipeToOutput(outputPipe.ReadSide)); From 3a1ee614764ab31732df1823aeb719b3c4d2eae5 Mon Sep 17 00:00:00 2001 From: Will Fuqua Date: Fri, 21 Sep 2018 21:50:18 +0700 Subject: [PATCH 50/89] fix exit behavior old behavior was whenever the user types "exit" to stop the entire terminal, which is not correct (e.g. does not work correctly for nested cmd.exe sessions). Now we wait for the top-level process to exit, which I think is more correct. Also contains a minor rename, Process -> ProcessFactory, ProcessResources -> Process. --- samples/ConPTY/MiniTerm/MiniTerm/Process.cs | 136 +++++++++--------- .../MiniTerm/MiniTerm/PseudoConsolePipe.cs | 4 +- samples/ConPTY/MiniTerm/MiniTerm/Terminal.cs | 35 ++--- 3 files changed, 86 insertions(+), 89 deletions(-) diff --git a/samples/ConPTY/MiniTerm/MiniTerm/Process.cs b/samples/ConPTY/MiniTerm/MiniTerm/Process.cs index 3756077e2a..40a703f638 100644 --- a/samples/ConPTY/MiniTerm/MiniTerm/Process.cs +++ b/samples/ConPTY/MiniTerm/MiniTerm/Process.cs @@ -1,7 +1,6 @@ using System; using System.Runtime.InteropServices; using static MiniTerm.Native.ProcessApi; -using static MiniTerm.Native.PseudoConsoleApi; namespace MiniTerm { @@ -11,16 +10,16 @@ namespace MiniTerm /// /// Possible to replace with managed code? The key is being able to provide the PROC_THREAD_ATTRIBUTE_PSEUDOCONSOLE attribute /// - static class Process + static class ProcessFactory { /// - /// Start and configure a process. The return value should be considered opaque, and eventually disposed. + /// Start and configure a process. The return value represents the process and should be disposed. /// - internal static ProcessResources Start(string command, IntPtr attributes, IntPtr hPC) + internal static Process Start(string command, IntPtr attributes, IntPtr hPC) { var startupInfo = ConfigureProcessThread(hPC, attributes); var processInfo = RunProcess(ref startupInfo, "cmd.exe"); - return new ProcessResources(startupInfo, processInfo); + return new Process(startupInfo, processInfo); } private static STARTUPINFOEX ConfigureProcessThread(IntPtr hPC, IntPtr attributes) @@ -93,70 +92,73 @@ namespace MiniTerm return pInfo; } + } - internal sealed class ProcessResources : IDisposable + /// + /// Represents an instance of a process + /// + internal sealed class Process : IDisposable + { + public Process(STARTUPINFOEX startupInfo, PROCESS_INFORMATION processInfo) { - public ProcessResources(STARTUPINFOEX startupInfo, PROCESS_INFORMATION processInfo) - { - StartupInfo = startupInfo; - ProcessInfo = processInfo; - } - - STARTUPINFOEX StartupInfo { get; } - PROCESS_INFORMATION ProcessInfo { get; } - - #region IDisposable Support - - private bool disposedValue = false; // To detect redundant calls - - void Dispose(bool disposing) - { - if (!disposedValue) - { - if (disposing) - { - // dispose managed state (managed objects). - } - - // dispose unmanaged state - - // Free the attribute list - if (StartupInfo.lpAttributeList != IntPtr.Zero) - { - DeleteProcThreadAttributeList(StartupInfo.lpAttributeList); - Marshal.FreeHGlobal(StartupInfo.lpAttributeList); - } - - // Close process and thread handles - if (ProcessInfo.hProcess != IntPtr.Zero) - { - CloseHandle(ProcessInfo.hProcess); - } - if (ProcessInfo.hThread != IntPtr.Zero) - { - CloseHandle(ProcessInfo.hThread); - } - - disposedValue = true; - } - } - - ~ProcessResources() - { - // Do not change this code. Put cleanup code in Dispose(bool disposing) above. - Dispose(false); - } - - // This code added to correctly implement the disposable pattern. - public void Dispose() - { - // Do not change this code. Put cleanup code in Dispose(bool disposing) above. - Dispose(true); - // use the following line if the finalizer is overridden above. - GC.SuppressFinalize(this); - } - - #endregion + StartupInfo = startupInfo; + ProcessInfo = processInfo; } + + public STARTUPINFOEX StartupInfo { get; } + public PROCESS_INFORMATION ProcessInfo { get; } + + #region IDisposable Support + + private bool disposedValue = false; // To detect redundant calls + + void Dispose(bool disposing) + { + if (!disposedValue) + { + if (disposing) + { + // dispose managed state (managed objects). + } + + // dispose unmanaged state + + // Free the attribute list + if (StartupInfo.lpAttributeList != IntPtr.Zero) + { + DeleteProcThreadAttributeList(StartupInfo.lpAttributeList); + Marshal.FreeHGlobal(StartupInfo.lpAttributeList); + } + + // Close process and thread handles + if (ProcessInfo.hProcess != IntPtr.Zero) + { + CloseHandle(ProcessInfo.hProcess); + } + if (ProcessInfo.hThread != IntPtr.Zero) + { + CloseHandle(ProcessInfo.hThread); + } + + disposedValue = true; + } + } + + ~Process() + { + // Do not change this code. Put cleanup code in Dispose(bool disposing) above. + Dispose(false); + } + + // This code added to correctly implement the disposable pattern. + public void Dispose() + { + // Do not change this code. Put cleanup code in Dispose(bool disposing) above. + Dispose(true); + // use the following line if the finalizer is overridden above. + GC.SuppressFinalize(this); + } + + #endregion } } diff --git a/samples/ConPTY/MiniTerm/MiniTerm/PseudoConsolePipe.cs b/samples/ConPTY/MiniTerm/MiniTerm/PseudoConsolePipe.cs index 604afb2d17..c5a8898a4b 100644 --- a/samples/ConPTY/MiniTerm/MiniTerm/PseudoConsolePipe.cs +++ b/samples/ConPTY/MiniTerm/MiniTerm/PseudoConsolePipe.cs @@ -13,8 +13,8 @@ namespace MiniTerm /// internal sealed class PseudoConsolePipe : IDisposable { - public SafeFileHandle ReadSide; - public SafeFileHandle WriteSide; + public readonly SafeFileHandle ReadSide; + public readonly SafeFileHandle WriteSide; public PseudoConsolePipe() { diff --git a/samples/ConPTY/MiniTerm/MiniTerm/Terminal.cs b/samples/ConPTY/MiniTerm/MiniTerm/Terminal.cs index 8de735628b..2077fb4c8a 100644 --- a/samples/ConPTY/MiniTerm/MiniTerm/Terminal.cs +++ b/samples/ConPTY/MiniTerm/MiniTerm/Terminal.cs @@ -2,6 +2,7 @@ using System; using System.IO; using System.Text; +using System.Threading; using System.Threading.Tasks; using static MiniTerm.Native.ConsoleApi; @@ -49,17 +50,16 @@ namespace MiniTerm using (var inputPipe = new PseudoConsolePipe()) using (var outputPipe = new PseudoConsolePipe()) using (var pseudoConsole = PseudoConsole.Create(inputPipe.ReadSide, outputPipe.WriteSide, (short)Console.WindowWidth, (short)Console.WindowHeight)) - using (var process = Process.Start(command, PseudoConsole.PseudoConsoleThreadAttribute, pseudoConsole.Handle)) + using (var process = ProcessFactory.Start(command, PseudoConsole.PseudoConsoleThreadAttribute, pseudoConsole.Handle)) { - // set up a background task to copy all pseudoconsole output to stdout + // copy all pseudoconsole output to stdout Task.Run(() => CopyPipeToOutput(outputPipe.ReadSide)); - + // prompt for stdin input and send the result to the pseudoconsole + Task.Run(() => CopyInputToPipe(inputPipe.WriteSide)); // free resources in case the console is ungracefully closed (e.g. by the 'x' in the window titlebar) OnClose(() => DisposeResources(process, pseudoConsole, outputPipe, inputPipe)); - // prompt for stdin input and send the result to the pipe. - // blocks until the user types "exit" - CopyInputToPipe(inputPipe.WriteSide); + WaitForExit(process).WaitOne(Timeout.Infinite); } } @@ -75,25 +75,11 @@ namespace MiniTerm writer.AutoFlush = true; writer.WriteLine(@"cd \"); - StringBuilder buffer = new StringBuilder(); while (true) { // send input character-by-character to the pipe char key = Console.ReadKey(intercept: true).KeyChar; writer.Write(key); - - // stop the input loop if 'exit' was sent - // TODO: if we have nested cmd.exe process, this will kill all of them which is wrong. - // could we somehow detect when the top-level cmd.exe process has ended and remove this logic? - buffer.Append(key); - if (key == '\r') - { - if (buffer.ToString() == ExitCommand) - { - break; - } - buffer.Clear(); - } } } } @@ -123,6 +109,15 @@ namespace MiniTerm } } + /// + /// Get an AutoResetEvent that signals when the process exits + /// + private static AutoResetEvent WaitForExit(ProcessFactory.Process process) => + new AutoResetEvent(false) + { + SafeWaitHandle = new SafeWaitHandle(process.ProcessInfo.hProcess, false) + }; + /// /// Set a callback for when the terminal is closed (e.g. via the "X" window decoration button). /// Intended for resource cleanup logic. From 08b436f1a5a59533b3852e93b68f1777c28c7b18 Mon Sep 17 00:00:00 2001 From: Will Fuqua Date: Fri, 21 Sep 2018 21:54:01 +0700 Subject: [PATCH 51/89] move Process and ProcessFactory classes into separate files --- .../ConPTY/MiniTerm/MiniTerm/MiniTerm.csproj | 3 +- .../MiniTerm/MiniTerm/Processes/Process.cs | 74 +++++++++++++++++++ .../ProcessFactory.cs} | 70 +----------------- samples/ConPTY/MiniTerm/MiniTerm/Terminal.cs | 4 +- 4 files changed, 80 insertions(+), 71 deletions(-) create mode 100644 samples/ConPTY/MiniTerm/MiniTerm/Processes/Process.cs rename samples/ConPTY/MiniTerm/MiniTerm/{Process.cs => Processes/ProcessFactory.cs} (65%) diff --git a/samples/ConPTY/MiniTerm/MiniTerm/MiniTerm.csproj b/samples/ConPTY/MiniTerm/MiniTerm/MiniTerm.csproj index 88b6940cee..e901ac9b42 100644 --- a/samples/ConPTY/MiniTerm/MiniTerm/MiniTerm.csproj +++ b/samples/ConPTY/MiniTerm/MiniTerm/MiniTerm.csproj @@ -45,7 +45,8 @@ - + + diff --git a/samples/ConPTY/MiniTerm/MiniTerm/Processes/Process.cs b/samples/ConPTY/MiniTerm/MiniTerm/Processes/Process.cs new file mode 100644 index 0000000000..a1b5228fed --- /dev/null +++ b/samples/ConPTY/MiniTerm/MiniTerm/Processes/Process.cs @@ -0,0 +1,74 @@ +using System; +using System.Runtime.InteropServices; +using static MiniTerm.Native.ProcessApi; + +namespace MiniTerm +{ + /// + /// Represents an instance of a process. + /// + internal sealed class Process : IDisposable + { + public Process(STARTUPINFOEX startupInfo, PROCESS_INFORMATION processInfo) + { + StartupInfo = startupInfo; + ProcessInfo = processInfo; + } + + public STARTUPINFOEX StartupInfo { get; } + public PROCESS_INFORMATION ProcessInfo { get; } + + #region IDisposable Support + + private bool disposedValue = false; // To detect redundant calls + + void Dispose(bool disposing) + { + if (!disposedValue) + { + if (disposing) + { + // dispose managed state (managed objects). + } + + // dispose unmanaged state + + // Free the attribute list + if (StartupInfo.lpAttributeList != IntPtr.Zero) + { + DeleteProcThreadAttributeList(StartupInfo.lpAttributeList); + Marshal.FreeHGlobal(StartupInfo.lpAttributeList); + } + + // Close process and thread handles + if (ProcessInfo.hProcess != IntPtr.Zero) + { + CloseHandle(ProcessInfo.hProcess); + } + if (ProcessInfo.hThread != IntPtr.Zero) + { + CloseHandle(ProcessInfo.hThread); + } + + disposedValue = true; + } + } + + ~Process() + { + // Do not change this code. Put cleanup code in Dispose(bool disposing) above. + Dispose(false); + } + + // This code added to correctly implement the disposable pattern. + public void Dispose() + { + // Do not change this code. Put cleanup code in Dispose(bool disposing) above. + Dispose(true); + // use the following line if the finalizer is overridden above. + GC.SuppressFinalize(this); + } + + #endregion + } +} diff --git a/samples/ConPTY/MiniTerm/MiniTerm/Process.cs b/samples/ConPTY/MiniTerm/MiniTerm/Processes/ProcessFactory.cs similarity index 65% rename from samples/ConPTY/MiniTerm/MiniTerm/Process.cs rename to samples/ConPTY/MiniTerm/MiniTerm/Processes/ProcessFactory.cs index 40a703f638..f54805ba34 100644 --- a/samples/ConPTY/MiniTerm/MiniTerm/Process.cs +++ b/samples/ConPTY/MiniTerm/MiniTerm/Processes/ProcessFactory.cs @@ -24,6 +24,8 @@ namespace MiniTerm private static STARTUPINFOEX ConfigureProcessThread(IntPtr hPC, IntPtr attributes) { + // this method implements the behavior described in https://docs.microsoft.com/en-us/windows/console/creating-a-pseudoconsole-session#preparing-for-creation-of-the-child-process + var lpSize = IntPtr.Zero; var success = InitializeProcThreadAttributeList( lpAttributeList: IntPtr.Zero, @@ -93,72 +95,4 @@ namespace MiniTerm return pInfo; } } - - /// - /// Represents an instance of a process - /// - internal sealed class Process : IDisposable - { - public Process(STARTUPINFOEX startupInfo, PROCESS_INFORMATION processInfo) - { - StartupInfo = startupInfo; - ProcessInfo = processInfo; - } - - public STARTUPINFOEX StartupInfo { get; } - public PROCESS_INFORMATION ProcessInfo { get; } - - #region IDisposable Support - - private bool disposedValue = false; // To detect redundant calls - - void Dispose(bool disposing) - { - if (!disposedValue) - { - if (disposing) - { - // dispose managed state (managed objects). - } - - // dispose unmanaged state - - // Free the attribute list - if (StartupInfo.lpAttributeList != IntPtr.Zero) - { - DeleteProcThreadAttributeList(StartupInfo.lpAttributeList); - Marshal.FreeHGlobal(StartupInfo.lpAttributeList); - } - - // Close process and thread handles - if (ProcessInfo.hProcess != IntPtr.Zero) - { - CloseHandle(ProcessInfo.hProcess); - } - if (ProcessInfo.hThread != IntPtr.Zero) - { - CloseHandle(ProcessInfo.hThread); - } - - disposedValue = true; - } - } - - ~Process() - { - // Do not change this code. Put cleanup code in Dispose(bool disposing) above. - Dispose(false); - } - - // This code added to correctly implement the disposable pattern. - public void Dispose() - { - // Do not change this code. Put cleanup code in Dispose(bool disposing) above. - Dispose(true); - // use the following line if the finalizer is overridden above. - GC.SuppressFinalize(this); - } - - #endregion - } } diff --git a/samples/ConPTY/MiniTerm/MiniTerm/Terminal.cs b/samples/ConPTY/MiniTerm/MiniTerm/Terminal.cs index 2077fb4c8a..df4bb21734 100644 --- a/samples/ConPTY/MiniTerm/MiniTerm/Terminal.cs +++ b/samples/ConPTY/MiniTerm/MiniTerm/Terminal.cs @@ -112,10 +112,10 @@ namespace MiniTerm /// /// Get an AutoResetEvent that signals when the process exits /// - private static AutoResetEvent WaitForExit(ProcessFactory.Process process) => + private static AutoResetEvent WaitForExit(Process process) => new AutoResetEvent(false) { - SafeWaitHandle = new SafeWaitHandle(process.ProcessInfo.hProcess, false) + SafeWaitHandle = new SafeWaitHandle(process.ProcessInfo.hProcess, ownsHandle: false) }; /// From 7371ed764db658f90a8a3e58b7a7456430222098 Mon Sep 17 00:00:00 2001 From: Michael Niksa Date: Tue, 2 Oct 2018 09:46:15 -0700 Subject: [PATCH 52/89] Set to LF line endings. --- tools/ColorTool/ColorTool/IniSchemeParser.cs | 24 ++-- tools/ColorTool/ColorTool/JsonParser.cs | 142 +++++++++---------- tools/ColorTool/ColorTool/XmlSchemeParser.cs | 6 +- 3 files changed, 86 insertions(+), 86 deletions(-) diff --git a/tools/ColorTool/ColorTool/IniSchemeParser.cs b/tools/ColorTool/ColorTool/IniSchemeParser.cs index d04eea5be2..dc4b8d26b0 100644 --- a/tools/ColorTool/ColorTool/IniSchemeParser.cs +++ b/tools/ColorTool/ColorTool/IniSchemeParser.cs @@ -96,9 +96,9 @@ namespace ColorTool if (tableStrings[i].Length <= 0) { success = false; - if (reportErrors) - { - Console.WriteLine(string.Format(Resources.IniParseError, filename, name, tableStrings[i])); + if (reportErrors) + { + Console.WriteLine(string.Format(Resources.IniParseError, filename, name, tableStrings[i])); } break; } @@ -116,22 +116,22 @@ namespace ColorTool } catch (Exception /*e*/) { - if (reportErrors) - { - Console.WriteLine(string.Format(Resources.IniLoadError, filename)); + if (reportErrors) + { + Console.WriteLine(string.Format(Resources.IniLoadError, filename)); } colorTable = null; } } - if (colorTable != null) - { - return new ColorScheme { colorTable = colorTable }; + if (colorTable != null) + { + return new ColorScheme { colorTable = colorTable }; } - else - { - return null; + else + { + return null; } } } diff --git a/tools/ColorTool/ColorTool/JsonParser.cs b/tools/ColorTool/ColorTool/JsonParser.cs index bf09d72754..2bf0f00f3e 100644 --- a/tools/ColorTool/ColorTool/JsonParser.cs +++ b/tools/ColorTool/ColorTool/JsonParser.cs @@ -1,17 +1,17 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Runtime.Serialization.Json; -using System.Text; -using System.Threading.Tasks; -using System.Xml; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Runtime.Serialization.Json; +using System.Text; +using System.Threading.Tasks; +using System.Xml; using static ColorTool.ConsoleAPI; - -namespace ColorTool -{ - class JsonParser : ISchemeParser - { + +namespace ColorTool +{ + class JsonParser : ISchemeParser + { static string[] CONCFG_COLOR_NAMES = { "black", // DARK_BLACK "dark_blue", // DARK_BLUE @@ -29,64 +29,64 @@ namespace ColorTool "magenta", // BRIGHT_MAGENTA "yellow", // BRIGHT_YELLOW "white" // BRIGHT_WHITE - }; - - public string Name => "concfg Parser"; - - static uint ParseColor(string arg) - { - System.Drawing.Color col = System.Drawing.ColorTranslator.FromHtml(arg); - return RGB(col.R, col.G, col.B); - } - - static XmlDocument loadJsonFile(string schemeName) - { - XmlDocument xmlDoc = new XmlDocument(); - foreach (string path in Scheme.GetSearchPaths(schemeName, ".json") - .Where(File.Exists)) - { - try - { - var data = File.ReadAllBytes(path); - var reader = JsonReaderWriterFactory.CreateJsonReader(data, System.Xml.XmlDictionaryReaderQuotas.Max); - xmlDoc.Load(reader); - return xmlDoc; - } + }; + + public string Name => "concfg Parser"; + + static uint ParseColor(string arg) + { + System.Drawing.Color col = System.Drawing.ColorTranslator.FromHtml(arg); + return RGB(col.R, col.G, col.B); + } + + static XmlDocument loadJsonFile(string schemeName) + { + XmlDocument xmlDoc = new XmlDocument(); + foreach (string path in Scheme.GetSearchPaths(schemeName, ".json") + .Where(File.Exists)) + { + try + { + var data = File.ReadAllBytes(path); + var reader = JsonReaderWriterFactory.CreateJsonReader(data, System.Xml.XmlDictionaryReaderQuotas.Max); + xmlDoc.Load(reader); + return xmlDoc; + } catch (XmlException /*e*/) { /* failed to parse */ } catch (IOException /*e*/) { /* failed to find */ } catch (UnauthorizedAccessException /*e*/) { /* unauthorized */ } - } - - return null; - } - - public ColorScheme ParseScheme(string schemeName, bool reportErrors = true) - { - XmlDocument xmlDoc = loadJsonFile(schemeName); - if (xmlDoc == null) return null; - - try - { - XmlNode root = xmlDoc.DocumentElement; - XmlNodeList children = root.ChildNodes; - uint[] colorTable = new uint[COLOR_TABLE_SIZE]; ; - for (int i = 0; i < COLOR_TABLE_SIZE; i++) - { - string name = CONCFG_COLOR_NAMES[i]; - var node = children.OfType().Where(n => n.Name == name).Single(); - colorTable[i] = ParseColor(node.InnerText); - } - return new ColorScheme { colorTable = colorTable }; - } - catch (Exception /*e*/) - { - if (reportErrors) - { - Console.WriteLine("failes to load json scheme"); - } - - return null; - } - } - } -} + } + + return null; + } + + public ColorScheme ParseScheme(string schemeName, bool reportErrors = true) + { + XmlDocument xmlDoc = loadJsonFile(schemeName); + if (xmlDoc == null) return null; + + try + { + XmlNode root = xmlDoc.DocumentElement; + XmlNodeList children = root.ChildNodes; + uint[] colorTable = new uint[COLOR_TABLE_SIZE]; ; + for (int i = 0; i < COLOR_TABLE_SIZE; i++) + { + string name = CONCFG_COLOR_NAMES[i]; + var node = children.OfType().Where(n => n.Name == name).Single(); + colorTable[i] = ParseColor(node.InnerText); + } + return new ColorScheme { colorTable = colorTable }; + } + catch (Exception /*e*/) + { + if (reportErrors) + { + Console.WriteLine("failes to load json scheme"); + } + + return null; + } + } + } +} diff --git a/tools/ColorTool/ColorTool/XmlSchemeParser.cs b/tools/ColorTool/ColorTool/XmlSchemeParser.cs index ddf965fd06..bf47988251 100644 --- a/tools/ColorTool/ColorTool/XmlSchemeParser.cs +++ b/tools/ColorTool/ColorTool/XmlSchemeParser.cs @@ -124,9 +124,9 @@ namespace ColorTool } if (colorsFound < COLOR_TABLE_SIZE) { - if (reportErrors) - { - Console.WriteLine(Resources.InvalidNumberOfColors); + if (reportErrors) + { + Console.WriteLine(Resources.InvalidNumberOfColors); } success = false; } From 15c2e57b96da4f4c14457be8b700d0aba04adef1 Mon Sep 17 00:00:00 2001 From: Michael Niksa Date: Tue, 2 Oct 2018 10:03:26 -0700 Subject: [PATCH 53/89] Use helper and move constant for STD_OUTPUT_HANDLE. Use string interpolation for colors. Use Color object and UIntToColor helper for creating our pattern. Add SetLastError annotations to native functions. --- tools/ColorTool/ColorTool/ConsoleAPI.cs | 6 ++++-- tools/ColorTool/ColorTool/Program.cs | 21 +++++++++++---------- 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/tools/ColorTool/ColorTool/ConsoleAPI.cs b/tools/ColorTool/ColorTool/ConsoleAPI.cs index a4fd414f15..468278148c 100644 --- a/tools/ColorTool/ColorTool/ConsoleAPI.cs +++ b/tools/ColorTool/ColorTool/ConsoleAPI.cs @@ -58,6 +58,8 @@ namespace ColorTool } } + public static int STD_OUTPUT_HANDLE = -11; + [DllImport("kernel32.dll", SetLastError = true)] public static extern IntPtr GetStdHandle(int nStdHandle); @@ -76,10 +78,10 @@ namespace ColorTool IntPtr lpReserved ); - [DllImport("kernel32.dll")] + [DllImport("kernel32.dll", SetLastError = true)] public static extern bool GetConsoleMode(IntPtr hConsoleHandle, out uint lpMode); - [DllImport("kernel32.dll")] + [DllImport("kernel32.dll", SetLastError = true)] public static extern bool SetConsoleMode(IntPtr hConsoleHandle, uint dwMode); //////////////////////////////////////////////////////////////////////// diff --git a/tools/ColorTool/ColorTool/Program.cs b/tools/ColorTool/ColorTool/Program.cs index 7ec1d13ac1..893b292d59 100644 --- a/tools/ColorTool/ColorTool/Program.cs +++ b/tools/ColorTool/ColorTool/Program.cs @@ -297,13 +297,18 @@ namespace ColorTool Console.Write("\x1b[m"); } + private static IntPtr GetStdOutputHandle() + { + return GetStdHandle(STD_OUTPUT_HANDLE); + } + static void PrintSchemes() { var schemeDirectory = new FileInfo(new Uri(Assembly.GetEntryAssembly().GetName().CodeBase).AbsolutePath).Directory.FullName + "/schemes"; if (Directory.Exists(schemeDirectory)) { - IntPtr handle = GetStdHandle(-11); + IntPtr handle = GetStdOutputHandle(); GetConsoleMode(handle, out var mode); SetConsoleMode(handle, mode | 0x4); @@ -349,8 +354,7 @@ namespace ColorTool static bool SetProperties(ColorScheme colorScheme) { CONSOLE_SCREEN_BUFFER_INFO_EX csbiex = CONSOLE_SCREEN_BUFFER_INFO_EX.Create(); - int STD_OUTPUT_HANDLE = -11; - IntPtr hOut = GetStdHandle(STD_OUTPUT_HANDLE); + IntPtr hOut = GetStdOutputHandle(); bool success = GetConsoleScreenBufferInfoEx(hOut, ref csbiex); if (success) { @@ -379,8 +383,7 @@ namespace ColorTool static bool SetPropertiesWithVt(ColorScheme colorScheme) { - int STD_OUTPUT_HANDLE = -11; - IntPtr hOut = GetStdHandle(STD_OUTPUT_HANDLE); + IntPtr hOut = GetStdOutputHandle(); uint originalMode; uint requestedMode; bool succeeded = GetConsoleMode(hOut, out originalMode); @@ -394,8 +397,8 @@ namespace ColorTool for (int i = 0; i < colorScheme.colorTable.Length; i++) { int vtIndex = VT_INDICIES[i]; - uint rgb = colorScheme.colorTable[i]; - string s = "\x1b]4;" + vtIndex + ";rgb:" + Rvalue(rgb).ToString("X") + "/"+ Gvalue(rgb).ToString("X") + "/"+ Bvalue(rgb).ToString("X") + "\x7"; + Color color = UIntToColor(colorScheme.colorTable[i]); + string s = $"\x1b]4;{vtIndex};rgb:{color.R:X}/{color.G:X}/{color.B:X}\x7"; Console.Write(s); } if (!quietMode) @@ -426,8 +429,7 @@ namespace ColorTool static bool ExportCurrentAsIni(string outputPath) { CONSOLE_SCREEN_BUFFER_INFO_EX csbiex = CONSOLE_SCREEN_BUFFER_INFO_EX.Create(); - int STD_OUTPUT_HANDLE = -11; - IntPtr hOut = GetStdHandle(STD_OUTPUT_HANDLE); + IntPtr hOut = GetStdOutputHandle(); bool success = GetConsoleScreenBufferInfoEx(hOut, ref csbiex); if (success) { @@ -540,7 +542,6 @@ namespace ColorTool else { SetProperties(colorScheme); - } } } From 4272e9c8e97d0c899c07bcf16739089c338523d3 Mon Sep 17 00:00:00 2001 From: Michael Niksa Date: Tue, 2 Oct 2018 10:16:36 -0700 Subject: [PATCH 54/89] These masks were unused after I used the color helper. Removing. --- tools/ColorTool/ColorTool/ConsoleAPI.cs | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/tools/ColorTool/ColorTool/ConsoleAPI.cs b/tools/ColorTool/ColorTool/ConsoleAPI.cs index 468278148c..3219d34e01 100644 --- a/tools/ColorTool/ColorTool/ConsoleAPI.cs +++ b/tools/ColorTool/ColorTool/ConsoleAPI.cs @@ -89,19 +89,7 @@ namespace ColorTool { return (uint)r + (((uint)g) << 8) + (((uint)b) << 16); } - public static uint Rvalue(uint rgb) - { - return rgb & 0x000000ff; - } - public static uint Gvalue(uint rgb) - { - return (rgb & 0x0000ff00) >> 8; - } - public static uint Bvalue(uint rgb) - { - return (rgb & 0x00ff0000) >> 16; - } - + public const int COLOR_TABLE_SIZE = 16; } } From e25ca320223df57d70e6a30597e9cae84c1f5f4a Mon Sep 17 00:00:00 2001 From: Michael Niksa Date: Tue, 2 Oct 2018 10:43:03 -0700 Subject: [PATCH 55/89] Wrap file system export write in try/catch. --- tools/ColorTool/ColorTool/Program.cs | 36 +++++++++++++++++----------- 1 file changed, 22 insertions(+), 14 deletions(-) diff --git a/tools/ColorTool/ColorTool/Program.cs b/tools/ColorTool/ColorTool/Program.cs index 893b292d59..7301c05cbc 100644 --- a/tools/ColorTool/ColorTool/Program.cs +++ b/tools/ColorTool/ColorTool/Program.cs @@ -297,9 +297,9 @@ namespace ColorTool Console.Write("\x1b[m"); } - private static IntPtr GetStdOutputHandle() - { - return GetStdHandle(STD_OUTPUT_HANDLE); + private static IntPtr GetStdOutputHandle() + { + return GetStdHandle(STD_OUTPUT_HANDLE); } static void PrintSchemes() @@ -433,21 +433,29 @@ namespace ColorTool bool success = GetConsoleScreenBufferInfoEx(hOut, ref csbiex); if (success) { - using (System.IO.StreamWriter file = new System.IO.StreamWriter(outputPath)) + try { - file.WriteLine("[table]"); - for (int i = 0; i < 16; i++) + // StreamWriter can fail for a variety of file system reasons so catch exceptions and print message. + using (System.IO.StreamWriter file = new System.IO.StreamWriter(outputPath)) { - string line = IniSchemeParser.COLOR_NAMES[i]; - line += " = "; - uint color = csbiex.ColorTable[i]; - uint r = color & (0x000000ff); - uint g = (color & (0x0000ff00)) >> 8; - uint b = (color & (0x00ff0000)) >> 16; - line += r + "," + g + "," + b; - file.WriteLine(line); + file.WriteLine("[table]"); + for (int i = 0; i < 16; i++) + { + string line = IniSchemeParser.COLOR_NAMES[i]; + line += " = "; + uint color = csbiex.ColorTable[i]; + uint r = color & (0x000000ff); + uint g = (color & (0x0000ff00)) >> 8; + uint b = (color & (0x00ff0000)) >> 16; + line += r + "," + g + "," + b; + file.WriteLine(line); + } } } + catch (Exception ex) + { + Console.WriteLine(ex.Message); + } } else { From 2791753780fee45b23528a56badff090d2ae40e6 Mon Sep 17 00:00:00 2001 From: Michael Niksa Date: Tue, 2 Oct 2018 11:18:00 -0700 Subject: [PATCH 56/89] Adjust version lookup to use file version info stamp which is automatically incremented/generated by engineering system. --- tools/ColorTool/ColorTool/Program.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/ColorTool/ColorTool/Program.cs b/tools/ColorTool/ColorTool/Program.cs index 7301c05cbc..7470dbe704 100644 --- a/tools/ColorTool/ColorTool/Program.cs +++ b/tools/ColorTool/ColorTool/Program.cs @@ -123,9 +123,9 @@ namespace ColorTool static void Version() { - string exePath = System.Reflection.Assembly.GetEntryAssembly().Location; - Version ver = AssemblyName.GetAssemblyName(exePath).Version; - Console.WriteLine("colortool v" + ver); + var assembly = System.Reflection.Assembly.GetExecutingAssembly(); + var info = System.Diagnostics.FileVersionInfo.GetVersionInfo(assembly.Location); + Console.WriteLine($"colortool v{info.FileVersion}"); } static void PrintTable() From 9971abf4e4d53e08d32034daef178a8559ba8607 Mon Sep 17 00:00:00 2001 From: Will Fuqua Date: Sat, 6 Oct 2018 17:49:48 +0700 Subject: [PATCH 57/89] add the new ConPTY samples to the readme Now that both the ConPTY samples (https://github.com/Microsoft/console/pull/247 and https://github.com/Microsoft/console/pull/260) are merged, mention them on the main repository README. --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index c7ed5c9f2f..fe9a518991 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,9 @@ In addition, the team reserve the right to actively manage issues, closing dupli ## Tools & Samples You'll also find assorted Console tools, samples, including the following: -* [ColorTool](https://github.com/Microsoft/Console/tree/master/tools/ColorTool). +* [ColorTool](https://github.com/Microsoft/Console/tree/master/tools/ColorTool) - A tool for changing the color scheme of the Windows console. +* [EchoCon](https://github.com/Microsoft/console/tree/master/samples/ConPTY/EchoCon) - A C++ sample application that illustrates how to use the new Win32 Pseudo Console (ConPTY). +* [MiniTerm](https://github.com/Microsoft/console/tree/master/samples/ConPTY/MiniTerm) - A C# sample terminal that illustrates how to use ConPTY. ### Tool Build Status From 66bc1f547eeb156f582b42cba4be418f066e379f Mon Sep 17 00:00:00 2001 From: Jake Langford Date: Wed, 10 Oct 2018 21:25:36 +0100 Subject: [PATCH 58/89] Added location flag to colortool and updated help. Also used path combine for schemes directory --- tools/ColorTool/ColorTool/Program.cs | 12 +++++- tools/ColorTool/ColorTool/Resources.resx | 47 ++++++++++++------------ 2 files changed, 35 insertions(+), 24 deletions(-) diff --git a/tools/ColorTool/ColorTool/Program.cs b/tools/ColorTool/ColorTool/Program.cs index 7470dbe704..86ba2c1b48 100644 --- a/tools/ColorTool/ColorTool/Program.cs +++ b/tools/ColorTool/ColorTool/Program.cs @@ -304,7 +304,7 @@ namespace ColorTool static void PrintSchemes() { - var schemeDirectory = new FileInfo(new Uri(Assembly.GetEntryAssembly().GetName().CodeBase).AbsolutePath).Directory.FullName + "/schemes"; + var schemeDirectory = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "schemes\\"); if (Directory.Exists(schemeDirectory)) { @@ -343,6 +343,12 @@ namespace ColorTool } } + static void PrintSchemesDirectory() + { + string schemeDirectory = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "schemes\\"); + Console.WriteLine(schemeDirectory); + } + private static Color UIntToColor(uint color) { byte r = (byte)(color >> 0); @@ -502,6 +508,10 @@ namespace ColorTool case "--version": Version(); return; + case "-l": + case "--location": + PrintSchemesDirectory(); + return; case "-x": case "--xterm": setUnixStyle = true; diff --git a/tools/ColorTool/ColorTool/Resources.resx b/tools/ColorTool/ColorTool/Resources.resx index 139b64d9cd..4b8219e715 100644 --- a/tools/ColorTool/ColorTool/Resources.resx +++ b/tools/ColorTool/ColorTool/Resources.resx @@ -138,29 +138,30 @@ Could not find or load "{0}" - Usage: - colortool.exe [options] <schemename> -ColorTool is a utility for helping to set the color palette of the Windows Console. -By default, applies the colors in the specified .itermcolors or .ini file to the current console window. -This does NOT save the properties automatically. For that, you'll need to open the properties sheet and hit "Ok". -Included should be a `schemes/` directory with a selection of schemes of both formats for examples. -Feel free to add your own preferred scheme to that directory. -Arguments: - <schemename>: The name of a color scheme. ct will try to first load it as an .itermcolors color scheme. - If that fails, it will look for it as an .ini file color scheme. -Options: - -?, --help : Display this help message - -c, --current : Print the color table for the currently applied scheme - -q, --quiet : Don't print the color table after applying - -d, --defaults : Apply the scheme to only the defaults in the registry - -b, --both : Apply the scheme to both the current console and the defaults. - -x, --xterm : Set the colors using VT sequences. Used for setting the colors in WSL. - Only works in Windows versions >= 17048. - -s, --schemes : Displays all available schemes - -v, --version : Display the version number - -o, --output <filename> : output the current color table to an file (in .ini format) - -Available importers: + Usage: + colortool.exe [options] <schemename> +ColorTool is a utility for helping to set the color palette of the Windows Console. +By default, applies the colors in the specified .itermcolors or .ini file to the current console window. +This does NOT save the properties automatically. For that, you'll need to open the properties sheet and hit "Ok". +Included should be a `schemes/` directory with a selection of schemes of both formats for examples. +Feel free to add your own preferred scheme to that directory. +Arguments: + <schemename>: The name of a color scheme. ct will try to first load it as an .itermcolors color scheme. + If that fails, it will look for it as an .ini file color scheme. +Options: + -?, --help : Display this help message + -c, --current : Print the color table for the currently applied scheme + -q, --quiet : Don't print the color table after applying + -d, --defaults : Apply the scheme to only the defaults in the registry + -b, --both : Apply the scheme to both the current console and the defaults. + -x, --xterm : Set the colors using VT sequences. Used for setting the colors in WSL. + Only works in Windows versions >= 17048. + -s, --schemes : Displays all available schemes + -l, --location : Displays the full path to the schemes directory + -v, --version : Display the version number + -o, --output <filename> : output the current color table to an file (in .ini format) + +Available importers: {0} From 10b05fbe2307b04f5f29f9395534cae6ae8ee80c Mon Sep 17 00:00:00 2001 From: "AzureAD\\JakeLangford" Date: Fri, 12 Oct 2018 09:11:48 +0100 Subject: [PATCH 59/89] fixed trailing slash at the end of path --- tools/ColorTool/ColorTool/Program.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/ColorTool/ColorTool/Program.cs b/tools/ColorTool/ColorTool/Program.cs index 86ba2c1b48..c056137333 100644 --- a/tools/ColorTool/ColorTool/Program.cs +++ b/tools/ColorTool/ColorTool/Program.cs @@ -304,7 +304,7 @@ namespace ColorTool static void PrintSchemes() { - var schemeDirectory = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "schemes\\"); + var schemeDirectory = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "schemes"); if (Directory.Exists(schemeDirectory)) { From df1843c87d045157dc106a67bb30c2029533308e Mon Sep 17 00:00:00 2001 From: Michael Niksa Date: Thu, 29 Nov 2018 10:32:04 -0800 Subject: [PATCH 60/89] Add signing configuration information to repository. --- tools/ColorTool/signing/CopySignFiles.cmd | 37 +++++++++++++++++++++++ tools/ColorTool/signing/SignConfig.xml | 6 ++++ 2 files changed, 43 insertions(+) create mode 100644 tools/ColorTool/signing/CopySignFiles.cmd create mode 100644 tools/ColorTool/signing/SignConfig.xml diff --git a/tools/ColorTool/signing/CopySignFiles.cmd b/tools/ColorTool/signing/CopySignFiles.cmd new file mode 100644 index 0000000000..51fda9ec8f --- /dev/null +++ b/tools/ColorTool/signing/CopySignFiles.cmd @@ -0,0 +1,37 @@ +REM @echo off +REM This script copies the files to have different paths to be signed and copies them back + +if "%2" == "" goto :usage +if "%1" == "sign" goto :sign +if "%1" == "afterSign" goto :afterSign + +goto :usage + +:sign +pushd "%2" +mkdir tosign +call :checkedCopy ..\b\Release\anycpu\ColorTool.exe tosign\ColorTool.exe + +popd +goto :end + +:afterSign +pushd "%2" +call :checkedCopy signed\ColorTool.exe ..\b\Release\anycpu\ColorTool.exe + +popd +goto :end + +:checkedCopy +copy %1 %2 +if %errorlevel% NEQ 0 ( + popd + exit 1 +) +exit /b + +:usage +echo "Usage: CopySignFiles " +echo "Will copy the binary release from \Release to be sent to signed" + +:end \ No newline at end of file diff --git a/tools/ColorTool/signing/SignConfig.xml b/tools/ColorTool/signing/SignConfig.xml new file mode 100644 index 0000000000..81b36c3b4b --- /dev/null +++ b/tools/ColorTool/signing/SignConfig.xml @@ -0,0 +1,6 @@ + + + + + + From 058b3f5d19c9c67fc54b91a88549369af842ccf5 Mon Sep 17 00:00:00 2001 From: Michael Niksa Date: Thu, 29 Nov 2018 12:38:36 -0800 Subject: [PATCH 61/89] Austin should be in the list. --- tools/ColorTool/signing/SignConfig.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/ColorTool/signing/SignConfig.xml b/tools/ColorTool/signing/SignConfig.xml index 81b36c3b4b..43b707e06a 100644 --- a/tools/ColorTool/signing/SignConfig.xml +++ b/tools/ColorTool/signing/SignConfig.xml @@ -1,6 +1,6 @@ - + From 4a30b1868b9852e07b42e0e3c6dd99df31c942a0 Mon Sep 17 00:00:00 2001 From: Harry Pierson Date: Wed, 27 Feb 2019 08:32:45 -0800 Subject: [PATCH 62/89] change ISchemeParser ParseScheme reportErrors param default to false --- tools/ColorTool/ColorTool/ISchemeParser.cs | 2 +- tools/ColorTool/ColorTool/IniSchemeParser.cs | 2 +- tools/ColorTool/ColorTool/JsonParser.cs | 2 +- tools/ColorTool/ColorTool/XmlSchemeParser.cs | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tools/ColorTool/ColorTool/ISchemeParser.cs b/tools/ColorTool/ColorTool/ISchemeParser.cs index 6e794ecd94..0153150943 100644 --- a/tools/ColorTool/ColorTool/ISchemeParser.cs +++ b/tools/ColorTool/ColorTool/ISchemeParser.cs @@ -9,6 +9,6 @@ namespace ColorTool { string Name { get; } - ColorScheme ParseScheme(string schemeName, bool reportErrors = true); + ColorScheme ParseScheme(string schemeName, bool reportErrors = false); } } diff --git a/tools/ColorTool/ColorTool/IniSchemeParser.cs b/tools/ColorTool/ColorTool/IniSchemeParser.cs index dc4b8d26b0..985299dded 100644 --- a/tools/ColorTool/ColorTool/IniSchemeParser.cs +++ b/tools/ColorTool/ColorTool/IniSchemeParser.cs @@ -76,7 +76,7 @@ namespace ColorTool return Scheme.GetSearchPaths(schemeName, ".ini").FirstOrDefault(File.Exists); } - public ColorScheme ParseScheme(string schemeName, bool reportErrors = true) + public ColorScheme ParseScheme(string schemeName, bool reportErrors = false) { bool success = true; diff --git a/tools/ColorTool/ColorTool/JsonParser.cs b/tools/ColorTool/ColorTool/JsonParser.cs index 2bf0f00f3e..ae3dd2b4e4 100644 --- a/tools/ColorTool/ColorTool/JsonParser.cs +++ b/tools/ColorTool/ColorTool/JsonParser.cs @@ -60,7 +60,7 @@ namespace ColorTool return null; } - public ColorScheme ParseScheme(string schemeName, bool reportErrors = true) + public ColorScheme ParseScheme(string schemeName, bool reportErrors = false) { XmlDocument xmlDoc = loadJsonFile(schemeName); if (xmlDoc == null) return null; diff --git a/tools/ColorTool/ColorTool/XmlSchemeParser.cs b/tools/ColorTool/ColorTool/XmlSchemeParser.cs index bf47988251..86463f76d3 100644 --- a/tools/ColorTool/ColorTool/XmlSchemeParser.cs +++ b/tools/ColorTool/ColorTool/XmlSchemeParser.cs @@ -99,7 +99,7 @@ namespace ColorTool } - public ColorScheme ParseScheme(string schemeName, bool reportErrors = true) + public ColorScheme ParseScheme(string schemeName, bool reportErrors = false) { XmlDocument xmlDoc = loadXmlScheme(schemeName); // Create an XML document object if (xmlDoc == null) return null; From ae5be18556c8403d2a0200d51ee2c93ae0cb74aa Mon Sep 17 00:00:00 2001 From: Harry Pierson Date: Wed, 27 Feb 2019 08:33:06 -0800 Subject: [PATCH 63/89] add --errors cmd line arg to enable scheme parsing error reporting --- tools/ColorTool/ColorTool/Program.cs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/tools/ColorTool/ColorTool/Program.cs b/tools/ColorTool/ColorTool/Program.cs index 7470dbe704..cb044f4f98 100644 --- a/tools/ColorTool/ColorTool/Program.cs +++ b/tools/ColorTool/ColorTool/Program.cs @@ -106,6 +106,7 @@ namespace ColorTool }; static bool quietMode = false; + static bool reportErrors = false; static bool setDefaults = false; static bool setProperties = true; static bool setUnixStyle = false; @@ -480,6 +481,10 @@ namespace ColorTool case "--current": PrintTable(); return; + case "-e": + case "--errors": + reportErrors = true; + break; case "-q": case "--quiet": quietMode = true; @@ -529,7 +534,7 @@ namespace ColorTool string schemeName = args[args.Length - 1]; - ColorScheme colorScheme = GetScheme(schemeName); + ColorScheme colorScheme = GetScheme(schemeName, reportErrors); if (colorScheme == null) { @@ -561,7 +566,7 @@ namespace ColorTool .Select(t => (ISchemeParser)Activator.CreateInstance(t)); } - private static ColorScheme GetScheme(string schemeName, bool reportErrors = true) + private static ColorScheme GetScheme(string schemeName, bool reportErrors = false) { foreach (var parser in GetParsers()) { From f3e53f1dac511f42982c793cddea5b937144f8e6 Mon Sep 17 00:00:00 2001 From: Harry Pierson Date: Wed, 27 Feb 2019 09:50:08 -0800 Subject: [PATCH 64/89] updated resources file --- tools/ColorTool/ColorTool/Resources.resx | 52 ++++++++++++------------ 1 file changed, 27 insertions(+), 25 deletions(-) diff --git a/tools/ColorTool/ColorTool/Resources.resx b/tools/ColorTool/ColorTool/Resources.resx index 139b64d9cd..47d73b71cb 100644 --- a/tools/ColorTool/ColorTool/Resources.resx +++ b/tools/ColorTool/ColorTool/Resources.resx @@ -121,8 +121,8 @@ Error loading ini file "{0}" - Error loading ini file "{0}" - for key "{1}" + Error loading ini file "{0}" + for key "{1}" the value "{2}" is invalid @@ -138,29 +138,31 @@ Could not find or load "{0}" - Usage: - colortool.exe [options] <schemename> -ColorTool is a utility for helping to set the color palette of the Windows Console. -By default, applies the colors in the specified .itermcolors or .ini file to the current console window. -This does NOT save the properties automatically. For that, you'll need to open the properties sheet and hit "Ok". -Included should be a `schemes/` directory with a selection of schemes of both formats for examples. -Feel free to add your own preferred scheme to that directory. -Arguments: - <schemename>: The name of a color scheme. ct will try to first load it as an .itermcolors color scheme. - If that fails, it will look for it as an .ini file color scheme. -Options: - -?, --help : Display this help message - -c, --current : Print the color table for the currently applied scheme - -q, --quiet : Don't print the color table after applying - -d, --defaults : Apply the scheme to only the defaults in the registry - -b, --both : Apply the scheme to both the current console and the defaults. - -x, --xterm : Set the colors using VT sequences. Used for setting the colors in WSL. - Only works in Windows versions >= 17048. - -s, --schemes : Displays all available schemes - -v, --version : Display the version number - -o, --output <filename> : output the current color table to an file (in .ini format) - -Available importers: + Usage: + colortool.exe [options] <schemename> +ColorTool is a utility for helping to set the color palette of the Windows Console. +By default, applies the colors in the specified .itermcolors, .json or .ini file to the current console window. +This does NOT save the properties automatically. For that, you'll need to open the properties sheet and hit "Ok". +Included should be a `schemes/` directory with a selection of schemes of both formats for examples. +Feel free to add your own preferred scheme to that directory. +Arguments: + <schemename>: The name of a color scheme. ct will try to first load it as an .ini file color scheme + If that fails, it will look for it as a .json file color scheme + If that fails, it will look for it as an .itermcolors file color scheme. +Options: + -?, --help : Display this help message + -c, --current : Print the color table for the currently applied scheme + -q, --quiet : Don't print the color table after applying + -e, --errors : Report scheme parsing errors on the console + -d, --defaults : Apply the scheme to only the defaults in the registry + -b, --both : Apply the scheme to both the current console and the defaults. + -x, --xterm : Set the colors using VT sequences. Used for setting the colors in WSL. + Only works in Windows versions >= 17048. + -s, --schemes : Displays all available schemes + -v, --version : Display the version number + -o, --output <filename> : output the current color table to an file (in .ini format) + +Available importers: {0} From 14f9cfc38933986e4e82af3a05500f137097e265 Mon Sep 17 00:00:00 2001 From: Jake Langford Date: Thu, 28 Mar 2019 17:20:08 +0000 Subject: [PATCH 65/89] Removed trailing slashes on schemes directory --- tools/ColorTool/ColorTool/Program.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/ColorTool/ColorTool/Program.cs b/tools/ColorTool/ColorTool/Program.cs index c056137333..1a20c3a09a 100644 --- a/tools/ColorTool/ColorTool/Program.cs +++ b/tools/ColorTool/ColorTool/Program.cs @@ -345,7 +345,7 @@ namespace ColorTool static void PrintSchemesDirectory() { - string schemeDirectory = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "schemes\\"); + string schemeDirectory = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "schemes"); Console.WriteLine(schemeDirectory); } From cafe71c50b01350668c681b55f5917037920f06c Mon Sep 17 00:00:00 2001 From: Patrick Kranz Date: Fri, 29 Mar 2019 16:44:41 +0100 Subject: [PATCH 66/89] added popup color to scheme --- tools/ColorTool/ColorTool/ColorScheme.cs | 3 +++ tools/ColorTool/ColorTool/Program.cs | 8 +++++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/tools/ColorTool/ColorTool/ColorScheme.cs b/tools/ColorTool/ColorTool/ColorScheme.cs index 0e9fae69e9..e62d08f757 100644 --- a/tools/ColorTool/ColorTool/ColorScheme.cs +++ b/tools/ColorTool/ColorTool/ColorScheme.cs @@ -14,6 +14,9 @@ namespace ColorTool public uint? foreground = null; public uint? background = null; + public uint? popupForeground = null; + public uint? popupBackground = null; + public int CalculateIndex(uint value) => colorTable.Select((color, idx) => Tuple.Create(color, idx)) .OrderBy(Difference(value)) diff --git a/tools/ColorTool/ColorTool/Program.cs b/tools/ColorTool/ColorTool/Program.cs index adb4ec1271..ef7b2e539e 100644 --- a/tools/ColorTool/ColorTool/Program.cs +++ b/tools/ColorTool/ColorTool/Program.cs @@ -370,12 +370,18 @@ namespace ColorTool { csbiex.ColorTable[i] = colorScheme.colorTable[i]; } - if(colorScheme.background != null && colorScheme.foreground != null) + if (colorScheme.background != null && colorScheme.foreground != null) { int fgidx = colorScheme.CalculateIndex(colorScheme.foreground.Value); int bgidx = colorScheme.CalculateIndex(colorScheme.background.Value); csbiex.wAttributes = (ushort)(fgidx | (bgidx << 4)); } + if (colorScheme.popupBackground != null && colorScheme.popupForeground != null) + { + int fgidx = colorScheme.CalculateIndex(colorScheme.popupForeground.Value); + int bgidx = colorScheme.CalculateIndex(colorScheme.popupBackground.Value); + csbiex.wPopupAttributes = (ushort)(fgidx | (bgidx << 4)); + } SetConsoleScreenBufferInfoEx(hOut, ref csbiex); } if (success) From 16b1b059a438e688aec15ba494c0924727add2b8 Mon Sep 17 00:00:00 2001 From: Patrick Kranz Date: Fri, 29 Mar 2019 17:08:57 +0100 Subject: [PATCH 67/89] added abblity to parse popup and screen color from ini file --- tools/ColorTool/ColorTool/IniSchemeParser.cs | 44 +++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) diff --git a/tools/ColorTool/ColorTool/IniSchemeParser.cs b/tools/ColorTool/ColorTool/IniSchemeParser.cs index 985299dded..0cd69cd025 100644 --- a/tools/ColorTool/ColorTool/IniSchemeParser.cs +++ b/tools/ColorTool/ColorTool/IniSchemeParser.cs @@ -9,6 +9,7 @@ using System.Text; using System.Runtime.InteropServices; using static ColorTool.ConsoleAPI; using System.IO; +using System.Collections.Generic; namespace ColorTool { @@ -85,6 +86,10 @@ namespace ColorTool string[] tableStrings = new string[COLOR_TABLE_SIZE]; uint[] colorTable = null; + uint? forgroundColor = null; + uint? backgroundColor = null; + uint? popupForgroundColor = null; + uint? popupBackgroundColor = null; for (int i = 0; i < COLOR_TABLE_SIZE; i++) { @@ -113,6 +118,22 @@ namespace ColorTool { colorTable[i] = ParseColor(tableStrings[i]); } + + if (ReadAttributes("popup", out var forground, out var background)) + { + var forgroundIndex = (COLOR_NAMES as IList).IndexOf(forground); + var backgroundIndex = (COLOR_NAMES as IList).IndexOf(background); + popupForgroundColor = colorTable[forgroundIndex]; + popupBackgroundColor = colorTable[backgroundIndex]; + } + + if (ReadAttributes("screen", out forground, out background)) + { + var forgroundIndex = (COLOR_NAMES as IList).IndexOf(forground); + var backgroundIndex = (COLOR_NAMES as IList).IndexOf(background); + forgroundColor = colorTable[forgroundIndex]; + backgroundColor = colorTable[backgroundIndex]; + } } catch (Exception /*e*/) { @@ -127,12 +148,33 @@ namespace ColorTool if (colorTable != null) { - return new ColorScheme { colorTable = colorTable }; + return new ColorScheme { colorTable = colorTable, background = backgroundColor, foreground = forgroundColor, popupBackground = popupBackgroundColor, popupForeground = popupForgroundColor }; } else { return null; } + + bool ReadAttributes(string section, out string forground, out string background) + { + forground = null; + background = null; + + StringBuilder buffer = new StringBuilder(512); + GetPrivateProfileString(section, "FOREGROUND", null, buffer, 512, filename); + forground = buffer.ToString(); + if (!COLOR_NAMES.Contains(forground)) + return false; + + + buffer = new StringBuilder(512); + GetPrivateProfileString(section, "BACKGROUND", null, buffer, 512, filename); + background = buffer.ToString(); + if (!COLOR_NAMES.Contains(background)) + return false; + + return true; + } } } } From 99f71a0cc5018a8b3ad5ba068eb22e3645a79561 Mon Sep 17 00:00:00 2001 From: Patrick Kranz Date: Fri, 29 Mar 2019 17:18:26 +0100 Subject: [PATCH 68/89] Export now writes screen and popup indexes in ini --- tools/ColorTool/ColorTool/Program.cs | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/tools/ColorTool/ColorTool/Program.cs b/tools/ColorTool/ColorTool/Program.cs index ef7b2e539e..fee46254b1 100644 --- a/tools/ColorTool/ColorTool/Program.cs +++ b/tools/ColorTool/ColorTool/Program.cs @@ -206,7 +206,7 @@ namespace ColorTool Console.ForegroundColor = currentForeground; Console.BackgroundColor = currentBackground; } - + static void PrintTableWithVt() { // Save the current background and foreground colors. @@ -242,7 +242,7 @@ namespace ColorTool "46m", "47m" }; - + Console.Write("\t"); for (int bg = 0; bg < BGs.Length; bg++) { @@ -283,7 +283,7 @@ namespace ColorTool } else { - Console.Write("\x1b[" +BGs[bg]); + Console.Write("\x1b[" + BGs[bg]); } Console.Write(test); @@ -463,6 +463,20 @@ namespace ColorTool line += r + "," + g + "," + b; file.WriteLine(line); } + + file.WriteLine(); + file.WriteLine("[screen]"); + var forgroundIndex = csbiex.wAttributes & 0xF; + var backgroundIndex = csbiex.wAttributes >> 4; + file.WriteLine($"FOREGROUND = {IniSchemeParser.COLOR_NAMES[forgroundIndex]}"); + file.WriteLine($"BACKGROUND = {IniSchemeParser.COLOR_NAMES[backgroundIndex]}"); + + file.WriteLine(); + file.WriteLine("[popup]"); + forgroundIndex = csbiex.wPopupAttributes & 0xF; + backgroundIndex = csbiex.wPopupAttributes >> 4; + file.WriteLine($"FOREGROUND = {IniSchemeParser.COLOR_NAMES[forgroundIndex]}"); + file.WriteLine($"BACKGROUND = {IniSchemeParser.COLOR_NAMES[backgroundIndex]}"); } } catch (Exception ex) @@ -530,7 +544,7 @@ namespace ColorTool break; case "-o": case "--output": - if (i+1 < args.Length) + if (i + 1 < args.Length) { ExportCurrentAsIni(args[i + 1]); } @@ -581,7 +595,7 @@ namespace ColorTool .Where(t => !t.IsAbstract && typeof(ISchemeParser).IsAssignableFrom(t)) .Select(t => (ISchemeParser)Activator.CreateInstance(t)); } - + private static ColorScheme GetScheme(string schemeName, bool reportErrors = false) { foreach (var parser in GetParsers()) @@ -593,6 +607,6 @@ namespace ColorTool } } return null; - } + } } } From ee8589110a02b922864d50fbf1861d11eb6d53b3 Mon Sep 17 00:00:00 2001 From: Avdi Grimm Date: Fri, 29 Mar 2019 15:04:58 -0500 Subject: [PATCH 69/89] Document loading colortool schemes from current dir --- tools/ColorTool/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/ColorTool/README.md b/tools/ColorTool/README.md index ad5ee7c625..ab55b240c9 100644 --- a/tools/ColorTool/README.md +++ b/tools/ColorTool/README.md @@ -35,7 +35,7 @@ Options: ## Adding Schemes - You can also add color schemes to the colortool easily. Take any existing scheme in `.itermcolors` format, and paste it in the `schemes/` directory. + You can also add color schemes to the colortool easily. Take any existing scheme in `.itermcolors` format, and paste it in the `schemes/` directory. Or just cd into a directory containing `*.itermcolors` files before running the colortool. I recommend the excellent [iTerm2-Color-Schemes](https://github.com/mbadolato/iTerm2-Color-Schemes) repo, which has TONS of schemes to choose from, and previews. From e6500864bcb63c8c5becd43a2791d3a749d44833 Mon Sep 17 00:00:00 2001 From: Patrick Kranz Date: Fri, 29 Mar 2019 21:52:04 +0100 Subject: [PATCH 70/89] added Support for parsing screen color in json --- tools/ColorTool/ColorTool/JsonParser.cs | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/tools/ColorTool/ColorTool/JsonParser.cs b/tools/ColorTool/ColorTool/JsonParser.cs index ae3dd2b4e4..8bb6f06abb 100644 --- a/tools/ColorTool/ColorTool/JsonParser.cs +++ b/tools/ColorTool/ColorTool/JsonParser.cs @@ -76,7 +76,27 @@ namespace ColorTool var node = children.OfType().Where(n => n.Name == name).Single(); colorTable[i] = ParseColor(node.InnerText); } - return new ColorScheme { colorTable = colorTable }; + + uint? screenForeground = null; + uint? screenBackground = null; + + var screenNode = children.OfType().Where(n => n.Name == "screen_colors").SingleOrDefault(); + if (screenNode != null) + { + var parts = screenNode.InnerText.Split(','); + if (parts.Length == 2) + { + var foregroundIndex = (CONCFG_COLOR_NAMES as IList).IndexOf(parts[0]); + var backgroundIndex = (CONCFG_COLOR_NAMES as IList).IndexOf(parts[1]); + if (foregroundIndex != -1 && backgroundIndex != -1) + { + screenForeground = colorTable[foregroundIndex]; + screenBackground = colorTable[backgroundIndex]; + } + } + } + + return new ColorScheme { colorTable = colorTable, background = screenBackground, foreground = screenForeground }; } catch (Exception /*e*/) { From b38f6ffbd134331b95e73a111e00d6a378d2a61a Mon Sep 17 00:00:00 2001 From: Patrick Kranz Date: Fri, 29 Mar 2019 21:53:50 +0100 Subject: [PATCH 71/89] Added check if screen or popup colors were not found. --- tools/ColorTool/ColorTool/IniSchemeParser.cs | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/tools/ColorTool/ColorTool/IniSchemeParser.cs b/tools/ColorTool/ColorTool/IniSchemeParser.cs index 0cd69cd025..a85c2c6f4c 100644 --- a/tools/ColorTool/ColorTool/IniSchemeParser.cs +++ b/tools/ColorTool/ColorTool/IniSchemeParser.cs @@ -123,16 +123,22 @@ namespace ColorTool { var forgroundIndex = (COLOR_NAMES as IList).IndexOf(forground); var backgroundIndex = (COLOR_NAMES as IList).IndexOf(background); - popupForgroundColor = colorTable[forgroundIndex]; - popupBackgroundColor = colorTable[backgroundIndex]; + if (forgroundIndex != -1 && backgroundIndex != -1) + { + popupForgroundColor = colorTable[forgroundIndex]; + popupBackgroundColor = colorTable[backgroundIndex]; + } } if (ReadAttributes("screen", out forground, out background)) { var forgroundIndex = (COLOR_NAMES as IList).IndexOf(forground); var backgroundIndex = (COLOR_NAMES as IList).IndexOf(background); - forgroundColor = colorTable[forgroundIndex]; - backgroundColor = colorTable[backgroundIndex]; + if (forgroundIndex != -1 && backgroundIndex != -1) + { + forgroundColor = colorTable[forgroundIndex]; + backgroundColor = colorTable[backgroundIndex]; + } } } catch (Exception /*e*/) From 9bf9a6f62cbae873fef0204c42f81a82d05510f2 Mon Sep 17 00:00:00 2001 From: Patrick Kranz Date: Fri, 29 Mar 2019 22:01:47 +0100 Subject: [PATCH 72/89] add popup color support to json format --- tools/ColorTool/ColorTool/JsonParser.cs | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/tools/ColorTool/ColorTool/JsonParser.cs b/tools/ColorTool/ColorTool/JsonParser.cs index 8bb6f06abb..c19973de4e 100644 --- a/tools/ColorTool/ColorTool/JsonParser.cs +++ b/tools/ColorTool/ColorTool/JsonParser.cs @@ -77,6 +77,26 @@ namespace ColorTool colorTable[i] = ParseColor(node.InnerText); } + + uint? popupForeground = null; + uint? popupBackground = null; + + var popupNode = children.OfType().Where(n => n.Name == "popup_colors").SingleOrDefault(); + if (popupNode != null) + { + var parts = popupNode.InnerText.Split(','); + if (parts.Length == 2) + { + var foregroundIndex = (CONCFG_COLOR_NAMES as IList).IndexOf(parts[0]); + var backgroundIndex = (CONCFG_COLOR_NAMES as IList).IndexOf(parts[1]); + if (foregroundIndex != -1 && backgroundIndex != -1) + { + popupForeground = colorTable[foregroundIndex]; + popupBackground = colorTable[backgroundIndex]; + } + } + } + uint? screenForeground = null; uint? screenBackground = null; @@ -96,7 +116,7 @@ namespace ColorTool } } - return new ColorScheme { colorTable = colorTable, background = screenBackground, foreground = screenForeground }; + return new ColorScheme { colorTable = colorTable, background = screenBackground, foreground = screenForeground, popupBackground = popupBackground, popupForeground = popupForeground }; } catch (Exception /*e*/) { From 3484e07089dd8b90e92c296a62f668abbfbe56d6 Mon Sep 17 00:00:00 2001 From: Patrick Kranz Date: Tue, 2 Apr 2019 18:48:16 +0200 Subject: [PATCH 73/89] Fix spelling of foreground (was forground) --- tools/ColorTool/ColorTool/IniSchemeParser.cs | 30 ++++++++++---------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/tools/ColorTool/ColorTool/IniSchemeParser.cs b/tools/ColorTool/ColorTool/IniSchemeParser.cs index a85c2c6f4c..42627ec994 100644 --- a/tools/ColorTool/ColorTool/IniSchemeParser.cs +++ b/tools/ColorTool/ColorTool/IniSchemeParser.cs @@ -86,9 +86,9 @@ namespace ColorTool string[] tableStrings = new string[COLOR_TABLE_SIZE]; uint[] colorTable = null; - uint? forgroundColor = null; + uint? foregroundColor = null; uint? backgroundColor = null; - uint? popupForgroundColor = null; + uint? popupForegroundColor = null; uint? popupBackgroundColor = null; for (int i = 0; i < COLOR_TABLE_SIZE; i++) @@ -119,24 +119,24 @@ namespace ColorTool colorTable[i] = ParseColor(tableStrings[i]); } - if (ReadAttributes("popup", out var forground, out var background)) + if (ReadAttributes("popup", out var foreground, out var background)) { - var forgroundIndex = (COLOR_NAMES as IList).IndexOf(forground); + var foregroundIndex = (COLOR_NAMES as IList).IndexOf(foreground); var backgroundIndex = (COLOR_NAMES as IList).IndexOf(background); - if (forgroundIndex != -1 && backgroundIndex != -1) + if (foregroundIndex != -1 && backgroundIndex != -1) { - popupForgroundColor = colorTable[forgroundIndex]; + popupForegroundColor = colorTable[foregroundIndex]; popupBackgroundColor = colorTable[backgroundIndex]; } } - if (ReadAttributes("screen", out forground, out background)) + if (ReadAttributes("screen", out foreground, out background)) { - var forgroundIndex = (COLOR_NAMES as IList).IndexOf(forground); + var foregroundIndex = (COLOR_NAMES as IList).IndexOf(foreground); var backgroundIndex = (COLOR_NAMES as IList).IndexOf(background); - if (forgroundIndex != -1 && backgroundIndex != -1) + if (foregroundIndex != -1 && backgroundIndex != -1) { - forgroundColor = colorTable[forgroundIndex]; + foregroundColor = colorTable[foregroundIndex]; backgroundColor = colorTable[backgroundIndex]; } } @@ -154,22 +154,22 @@ namespace ColorTool if (colorTable != null) { - return new ColorScheme { colorTable = colorTable, background = backgroundColor, foreground = forgroundColor, popupBackground = popupBackgroundColor, popupForeground = popupForgroundColor }; + return new ColorScheme { colorTable = colorTable, background = backgroundColor, foreground = foregroundColor, popupBackground = popupBackgroundColor, popupForeground = popupForegroundColor }; } else { return null; } - bool ReadAttributes(string section, out string forground, out string background) + bool ReadAttributes(string section, out string foreground, out string background) { - forground = null; + foreground = null; background = null; StringBuilder buffer = new StringBuilder(512); GetPrivateProfileString(section, "FOREGROUND", null, buffer, 512, filename); - forground = buffer.ToString(); - if (!COLOR_NAMES.Contains(forground)) + foreground = buffer.ToString(); + if (!COLOR_NAMES.Contains(foreground)) return false; From a247624e907f83f5b756104d22631a9b677fc881 Mon Sep 17 00:00:00 2001 From: Patrick Kranz Date: Tue, 2 Apr 2019 18:54:00 +0200 Subject: [PATCH 74/89] encapsule console attributes in struct --- tools/ColorTool/ColorTool/ColorScheme.cs | 13 +++++-------- tools/ColorTool/ColorTool/ConsoleAttributes.cs | 17 +++++++++++++++++ tools/ColorTool/ColorTool/IniSchemeParser.cs | 2 +- tools/ColorTool/ColorTool/JsonParser.cs | 2 +- tools/ColorTool/ColorTool/Program.cs | 12 ++++++------ tools/ColorTool/ColorTool/XmlSchemeParser.cs | 2 +- 6 files changed, 31 insertions(+), 17 deletions(-) create mode 100644 tools/ColorTool/ColorTool/ConsoleAttributes.cs diff --git a/tools/ColorTool/ColorTool/ColorScheme.cs b/tools/ColorTool/ColorTool/ColorScheme.cs index e62d08f757..f930f31e54 100644 --- a/tools/ColorTool/ColorTool/ColorScheme.cs +++ b/tools/ColorTool/ColorTool/ColorScheme.cs @@ -11,11 +11,8 @@ namespace ColorTool public class ColorScheme { public uint[] colorTable = null; - public uint? foreground = null; - public uint? background = null; + public ConsoleAttributes consoleAttributes; - public uint? popupForeground = null; - public uint? popupBackground = null; public int CalculateIndex(uint value) => colorTable.Select((color, idx) => Tuple.Create(color, idx)) @@ -83,14 +80,14 @@ namespace ColorTool _dump($"Color[{i}]", colorTable[i]); } - if (foreground != null) + if (consoleAttributes.foreground != null) { - _dump("FG ", foreground.Value); + _dump("FG ", consoleAttributes.foreground.Value); } - if (background != null) + if (consoleAttributes.background != null) { - _dump("BG ", background.Value); + _dump("BG ", consoleAttributes.background.Value); } } } diff --git a/tools/ColorTool/ColorTool/ConsoleAttributes.cs b/tools/ColorTool/ColorTool/ConsoleAttributes.cs new file mode 100644 index 0000000000..ac2d9bceb3 --- /dev/null +++ b/tools/ColorTool/ColorTool/ConsoleAttributes.cs @@ -0,0 +1,17 @@ +// +// Copyright (C) Microsoft. All rights reserved. +// Licensed under the terms described in the LICENSE file in the root of this project. +// + +namespace ColorTool +{ + public struct ConsoleAttributes + { + public uint? foreground; + public uint? background; + + public uint? popupForeground; + public uint? popupBackground; + + } +} diff --git a/tools/ColorTool/ColorTool/IniSchemeParser.cs b/tools/ColorTool/ColorTool/IniSchemeParser.cs index 42627ec994..f03c3971fe 100644 --- a/tools/ColorTool/ColorTool/IniSchemeParser.cs +++ b/tools/ColorTool/ColorTool/IniSchemeParser.cs @@ -154,7 +154,7 @@ namespace ColorTool if (colorTable != null) { - return new ColorScheme { colorTable = colorTable, background = backgroundColor, foreground = foregroundColor, popupBackground = popupBackgroundColor, popupForeground = popupForegroundColor }; + return new ColorScheme { colorTable = colorTable, consoleAttributes = new ConsoleAttributes { background = backgroundColor, foreground = foregroundColor, popupBackground = popupBackgroundColor, popupForeground = popupForegroundColor } }; } else { diff --git a/tools/ColorTool/ColorTool/JsonParser.cs b/tools/ColorTool/ColorTool/JsonParser.cs index c19973de4e..e8ff31527b 100644 --- a/tools/ColorTool/ColorTool/JsonParser.cs +++ b/tools/ColorTool/ColorTool/JsonParser.cs @@ -116,7 +116,7 @@ namespace ColorTool } } - return new ColorScheme { colorTable = colorTable, background = screenBackground, foreground = screenForeground, popupBackground = popupBackground, popupForeground = popupForeground }; + return new ColorScheme { colorTable = colorTable, consoleAttributes = new ConsoleAttributes { background = screenBackground, foreground = screenForeground, popupBackground = popupBackground, popupForeground = popupForeground } }; } catch (Exception /*e*/) { diff --git a/tools/ColorTool/ColorTool/Program.cs b/tools/ColorTool/ColorTool/Program.cs index fee46254b1..3496d606de 100644 --- a/tools/ColorTool/ColorTool/Program.cs +++ b/tools/ColorTool/ColorTool/Program.cs @@ -370,16 +370,16 @@ namespace ColorTool { csbiex.ColorTable[i] = colorScheme.colorTable[i]; } - if (colorScheme.background != null && colorScheme.foreground != null) + if (colorScheme.consoleAttributes.background != null && colorScheme.consoleAttributes.foreground != null) { - int fgidx = colorScheme.CalculateIndex(colorScheme.foreground.Value); - int bgidx = colorScheme.CalculateIndex(colorScheme.background.Value); + int fgidx = colorScheme.CalculateIndex(colorScheme.consoleAttributes.foreground.Value); + int bgidx = colorScheme.CalculateIndex(colorScheme.consoleAttributes.background.Value); csbiex.wAttributes = (ushort)(fgidx | (bgidx << 4)); } - if (colorScheme.popupBackground != null && colorScheme.popupForeground != null) + if (colorScheme.consoleAttributes.popupBackground != null && colorScheme.consoleAttributes.popupForeground != null) { - int fgidx = colorScheme.CalculateIndex(colorScheme.popupForeground.Value); - int bgidx = colorScheme.CalculateIndex(colorScheme.popupBackground.Value); + int fgidx = colorScheme.CalculateIndex(colorScheme.consoleAttributes.popupForeground.Value); + int bgidx = colorScheme.CalculateIndex(colorScheme.consoleAttributes.popupBackground.Value); csbiex.wPopupAttributes = (ushort)(fgidx | (bgidx << 4)); } SetConsoleScreenBufferInfoEx(hOut, ref csbiex); diff --git a/tools/ColorTool/ColorTool/XmlSchemeParser.cs b/tools/ColorTool/ColorTool/XmlSchemeParser.cs index 86463f76d3..1784a0b7f0 100644 --- a/tools/ColorTool/ColorTool/XmlSchemeParser.cs +++ b/tools/ColorTool/ColorTool/XmlSchemeParser.cs @@ -135,7 +135,7 @@ namespace ColorTool return null; } - return new ColorScheme { colorTable = colorTable, foreground = fgColor, background = bgColor }; + return new ColorScheme { colorTable = colorTable, consoleAttributes = new ConsoleAttributes { foreground = fgColor, background = bgColor } }; } } } From 2661fbe0b9dc3b35ee5431aef1f7d9d4e0171f59 Mon Sep 17 00:00:00 2001 From: Patrick Kranz Date: Tue, 2 Apr 2019 18:56:14 +0200 Subject: [PATCH 75/89] put console attributes in own variable --- tools/ColorTool/ColorTool/IniSchemeParser.cs | 3 ++- tools/ColorTool/ColorTool/JsonParser.cs | 3 ++- tools/ColorTool/ColorTool/XmlSchemeParser.cs | 3 ++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/tools/ColorTool/ColorTool/IniSchemeParser.cs b/tools/ColorTool/ColorTool/IniSchemeParser.cs index f03c3971fe..be332d6002 100644 --- a/tools/ColorTool/ColorTool/IniSchemeParser.cs +++ b/tools/ColorTool/ColorTool/IniSchemeParser.cs @@ -154,7 +154,8 @@ namespace ColorTool if (colorTable != null) { - return new ColorScheme { colorTable = colorTable, consoleAttributes = new ConsoleAttributes { background = backgroundColor, foreground = foregroundColor, popupBackground = popupBackgroundColor, popupForeground = popupForegroundColor } }; + var consoleAttributes = new ConsoleAttributes { background = backgroundColor, foreground = foregroundColor, popupBackground = popupBackgroundColor, popupForeground = popupForegroundColor }; + return new ColorScheme { colorTable = colorTable, consoleAttributes = consoleAttributes }; } else { diff --git a/tools/ColorTool/ColorTool/JsonParser.cs b/tools/ColorTool/ColorTool/JsonParser.cs index e8ff31527b..dde2145df6 100644 --- a/tools/ColorTool/ColorTool/JsonParser.cs +++ b/tools/ColorTool/ColorTool/JsonParser.cs @@ -116,7 +116,8 @@ namespace ColorTool } } - return new ColorScheme { colorTable = colorTable, consoleAttributes = new ConsoleAttributes { background = screenBackground, foreground = screenForeground, popupBackground = popupBackground, popupForeground = popupForeground } }; + var consoleAttributes = new ConsoleAttributes { background = screenBackground, foreground = screenForeground, popupBackground = popupBackground, popupForeground = popupForeground }; + return new ColorScheme { colorTable = colorTable, consoleAttributes = consoleAttributes }; } catch (Exception /*e*/) { diff --git a/tools/ColorTool/ColorTool/XmlSchemeParser.cs b/tools/ColorTool/ColorTool/XmlSchemeParser.cs index 1784a0b7f0..615a399bb3 100644 --- a/tools/ColorTool/ColorTool/XmlSchemeParser.cs +++ b/tools/ColorTool/ColorTool/XmlSchemeParser.cs @@ -135,7 +135,8 @@ namespace ColorTool return null; } - return new ColorScheme { colorTable = colorTable, consoleAttributes = new ConsoleAttributes { foreground = fgColor, background = bgColor } }; + var consoleAttributes = new ConsoleAttributes { foreground = fgColor, background = bgColor }; + return new ColorScheme { colorTable = colorTable, consoleAttributes = consoleAttributes }; } } } From cade139e0c3eaae2b6486704b61b765f32a0c11b Mon Sep 17 00:00:00 2001 From: oising Date: Sun, 21 Apr 2019 13:31:36 -0400 Subject: [PATCH 76/89] initial commit for tools/readconsoleinputstream PR --- .../ConcurrentCircularQueue.cs | 62 ++++++ tools/ReadConsoleInputStream/NativeMethods.cs | 22 ++ tools/ReadConsoleInputStream/Program.cs | 151 ++++++++++++++ .../ReadConsoleInputStream.cs | 194 ++++++++++++++++++ .../ReadConsoleInputStreamDemo.csproj | 16 ++ 5 files changed, 445 insertions(+) create mode 100644 tools/ReadConsoleInputStream/ConcurrentCircularQueue.cs create mode 100644 tools/ReadConsoleInputStream/NativeMethods.cs create mode 100644 tools/ReadConsoleInputStream/Program.cs create mode 100644 tools/ReadConsoleInputStream/ReadConsoleInputStream.cs create mode 100644 tools/ReadConsoleInputStream/ReadConsoleInputStreamDemo.csproj diff --git a/tools/ReadConsoleInputStream/ConcurrentCircularQueue.cs b/tools/ReadConsoleInputStream/ConcurrentCircularQueue.cs new file mode 100644 index 0000000000..db14019f37 --- /dev/null +++ b/tools/ReadConsoleInputStream/ConcurrentCircularQueue.cs @@ -0,0 +1,62 @@ +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; + +namespace Nivot.Terminal +{ + /// + /// Implements a circular buffer. + /// + /// + public class ConcurrentCircularQueue : ConcurrentQueue + { + public ConcurrentCircularQueue(int capacity) + { + Capacity = GetAlignedCapacity(capacity); + } + + /// + /// + /// + /// + /// + public ConcurrentCircularQueue(IEnumerable collection, int capacity) : base(collection) + { + Capacity = GetAlignedCapacity(capacity); + } + + private int GetAlignedCapacity(int n) + { + if (n < 2) + { + throw new ArgumentException("Capacity must be at least 2"); + } + + var f = Math.Log(n, 2); + var p = Math.Ceiling(f); + + return (int) Math.Pow(2, p); + } + + public new void Enqueue(T item) + { + if (Count >= Capacity) + { + lock (this) + { + while (Count >= Capacity) + { + TryDequeue(out _); + } + } + } + + base.Enqueue(item); + } + + public int Capacity + { + get; private set; + } + } +} diff --git a/tools/ReadConsoleInputStream/NativeMethods.cs b/tools/ReadConsoleInputStream/NativeMethods.cs new file mode 100644 index 0000000000..f08640f02e --- /dev/null +++ b/tools/ReadConsoleInputStream/NativeMethods.cs @@ -0,0 +1,22 @@ +using System; +using System.Runtime.InteropServices; + +namespace Nivot.Terminal +{ + internal static class NativeMethods + { + private static int MakeHRFromErrorCode(int errorCode) + { + // Don't convert it if it is already an HRESULT + if ((0xFFFF0000 & errorCode) != 0) + return errorCode; + + return unchecked(((int)0x80070000) | errorCode); + } + + internal static Exception GetExceptionForWin32Error(int errorCode) + { + return Marshal.GetExceptionForHR(MakeHRFromErrorCode(errorCode)); + } + } +} \ No newline at end of file diff --git a/tools/ReadConsoleInputStream/Program.cs b/tools/ReadConsoleInputStream/Program.cs new file mode 100644 index 0000000000..d4f97f3eef --- /dev/null +++ b/tools/ReadConsoleInputStream/Program.cs @@ -0,0 +1,151 @@ +/* + * This is a demo that shows how we can have a stream-oriented view of characters from the console + * while also listening to console events like mouse, menu, focus, buffer/viewport(1) resize events. + * + * This has always been tricky to do because ReadConsoleW/A doesn't allow retrieving events. + * Only ReadConsoleInputW/A returns events, but isn't stream-oriented. Using both doesn't work because + * ReadConsoleW/A flushes the input queue, meaning calls to ReadConsoleInputW/A will wait forever. + * + * I do this by deriving a new Stream class which wraps ReadConsoleInputW and accepts a provider/consumer + * implementation of BlockingCollection. This allows asynchronous monitoring of + * console events while simultaneously streaming the character input. I also use Mark Gravell's great + * System.IO.Pipelines utility classes (2) and David Hall's excellent P/Invoke wrappers (3) to make this + * demo cleaner to read; both are pulled from NuGet. + * + * (1) in versions of windows 10 prior to 1809, the buffer resize event only fires for enlarging + * the viewport, as this would cause the buffer to be enlarged too. Now it fires even when + * shrinking the viewport, which won't change the buffer size. + * + * (2) https://github.com/mgravell/Pipelines.Sockets.Unofficial + * https://www.nuget.org/packages/Pipelines.Sockets.Unofficial + * + * (3) https://github.com/dahall/Vanara + * https://www.nuget.org/packages/Vanara.Pinvoke.Kernel32 + * + * Oisin Grehan - 2019/4/21 + * + * https://twitter.com/oising + * https://github.com/oising + */ + +using System; +using System.Collections.Concurrent; +using System.IO; +using System.Runtime.InteropServices; +using System.Text; +using System.Threading; +using System.Threading.Tasks; + +using Pipelines.Sockets.Unofficial; +using Vanara.PInvoke; + +namespace Nivot.Terminal +{ + internal class Program + { + private static async Task Main(string[] args) + { + // run for 90 seconds + const int timeout = 90000; + + var source = new CancellationTokenSource(timeout); + var token = source.Token; + var handle = Kernel32.GetStdHandle(Kernel32.StdHandleType.STD_INPUT_HANDLE); + + if (!Kernel32.GetConsoleMode(handle, out Kernel32.CONSOLE_INPUT_MODE mode)) + throw NativeMethods.GetExceptionForWin32Error(Marshal.GetLastWin32Error()); + + // enable VT sequences so cursor movement etc is encapsulated in the stream + mode |= Kernel32.CONSOLE_INPUT_MODE.ENABLE_WINDOW_INPUT; + mode |= Kernel32.CONSOLE_INPUT_MODE.ENABLE_VIRTUAL_TERMINAL_INPUT; + mode &= ~Kernel32.CONSOLE_INPUT_MODE.ENABLE_ECHO_INPUT; + mode &= ~Kernel32.CONSOLE_INPUT_MODE.ENABLE_LINE_INPUT; + + if (!Kernel32.SetConsoleMode(handle, mode)) + throw NativeMethods.GetExceptionForWin32Error(Marshal.GetLastWin32Error()); + + // set utf-8 cp + if (!Kernel32.SetConsoleCP(65001)) + throw NativeMethods.GetExceptionForWin32Error(Marshal.GetLastWin32Error()); + + if (!Kernel32.SetConsoleOutputCP(65001)) + throw NativeMethods.GetExceptionForWin32Error(Marshal.GetLastWin32Error()); + + // base our provider/consumer on a circular buffer to keep memory usage under control + var events = new BlockingCollection( + new ConcurrentCircularQueue(256)); + + // Task that will consume non-key events asynchronously + var consumeEvents = Task.Run(() => + { + Console.WriteLine("consumeEvents started"); + + try + { + while (!events.IsCompleted) + { + // blocking call + var record = events.Take(token); + + Console.WriteLine("record: {0}", + Enum.GetName(typeof(Kernel32.EVENT_TYPE), record.EventType)); + } + } + catch (OperationCanceledException) + { + // timeout + } + + Console.WriteLine("consumeEvents ended"); + }, token); + + // Task that will watch for key events while feeding non-key events into our provider/consumer collection + var readInputAndProduceEvents = Task.Run(async () => + { + //So, this is the key point - we cannot use the following or we lose all non-key events: + // Stream stdin = Console.OpenStandardInput(); + + // get a unicode character stream over console input + Stream stdin = new ReadConsoleInputStream(handle, events); + + // wrap in a System.IO.Pipelines.PipeReader to get clean async and span/memory usage + var reader = StreamConnection.GetReader(stdin); + + while (!token.IsCancellationRequested) + { + // blocking call + var result = await reader.ReadAsync(token); + + if (result.IsCanceled) + break; + + var sequence = result.Buffer; + var segment = sequence.Start; + + while (sequence.TryGet(ref segment, out var mem)) + { + // decode back from unicode (2 bytes per char) + var datum = Encoding.Unicode.GetString(mem.Span); + Console.Write(datum); + } + + reader.AdvanceTo(sequence.End); + } + }, token); + + Console.WriteLine("Running"); + + try + { + await Task.WhenAll(consumeEvents, readInputAndProduceEvents); + } + catch (OperationCanceledException) + { + // timeout + } + + Console.WriteLine("press any key..."); + Console.ReadKey(true); + } + } +} \ No newline at end of file diff --git a/tools/ReadConsoleInputStream/ReadConsoleInputStream.cs b/tools/ReadConsoleInputStream/ReadConsoleInputStream.cs new file mode 100644 index 0000000000..64a99f7377 --- /dev/null +++ b/tools/ReadConsoleInputStream/ReadConsoleInputStream.cs @@ -0,0 +1,194 @@ +using System; +using System.Collections.Concurrent; +using System.Diagnostics; +using System.IO; + +using Vanara.PInvoke; + +namespace Nivot.Terminal +{ + /// + /// Provides a Stream-oriented view over the console's input buffer key events + /// while also collecting out of band events like buffer resize, menu etc in + /// a caller-provided BlockingCollection. + /// + /// The buffer contains unicode chars, not 8 bit CP encoded chars as we rely on ReadConsoleInputW. + public sealed class ReadConsoleInputStream : Stream + { + private const int BufferSize = 256; + private const int BytesPerWChar = 2; + private readonly BlockingCollection _nonKeyEvents; + private IntPtr _handle; + + /// + /// Creates an instance of ReadConsoleInputStream over the standard handle for StdIn. + /// + /// A BlockingCollection provider/consumer collection for collecting non key events. + public ReadConsoleInputStream(BlockingCollection nonKeyEvents) : + this(Kernel32.GetStdHandle(Kernel32.StdHandleType.STD_INPUT_HANDLE), nonKeyEvents) + { + } + + /// + /// Creates an instance of ReadConsoleInputStream over a caller-provided standard handle for stdin. + /// + /// A HFILE handle representing StdIn + /// A BlockingCollection provider/consumer collection for collecting non key events. + internal ReadConsoleInputStream(HFILE handle, + BlockingCollection nonKeyEvents) + { + Debug.Assert(handle.IsInvalid == false, "handle.IsInvalid == false"); + + _handle = handle.DangerousGetHandle(); + _nonKeyEvents = nonKeyEvents; + } + + public override bool CanRead { get; } = true; + + public override bool CanWrite => false; + + public override bool CanSeek => false; + + public override long Length => throw new NotSupportedException("Seek not supported."); + + public override long Position + { + get => throw new NotSupportedException("Seek not supported."); + set => throw new NotSupportedException("Seek not supported."); + } + + protected override void Dispose(bool disposing) + { + _handle = IntPtr.Zero; + + base.Dispose(disposing); + } + + public override int Read(byte[] buffer, int offset, int count) + { + ValidateRead(buffer, offset, count); + + Debug.Assert(offset >= 0, "offset >= 0"); + Debug.Assert(count >= 0, "count >= 0"); + Debug.Assert(buffer != null, "bytes != null"); + + // Don't corrupt memory when multiple threads are erroneously writing + // to this stream simultaneously. + if (buffer.Length - offset < count) + throw new IndexOutOfRangeException("IndexOutOfRange_IORaceCondition"); + + int bytesRead; + int ret; + + if (buffer.Length == 0) + { + bytesRead = 0; + ret = Win32Error.ERROR_SUCCESS; + } + else + { + var charsRead = 0; + bytesRead = 0; + + var records = new Kernel32.INPUT_RECORD[BufferSize]; + + // begin input loop + waitForInput: + + var readSuccess = Kernel32.ReadConsoleInput(_handle, records, 256, out var recordsRead); + Debug.WriteLine("Read {0} input record(s)", recordsRead); + + if (readSuccess && recordsRead > 0) + { + for (var index = 0; index < recordsRead; index++) + { + var record = records[index]; + + if (record.EventType == Kernel32.EVENT_TYPE.KEY_EVENT) + { + // skip key up events - if not, every key will be duped in the stream + if (record.Event.KeyEvent.bKeyDown == false) continue; + + // pack ucs-2/utf-16le/unicode chars into position in our byte[] buffer. + var glyph = (ushort) record.Event.KeyEvent.uChar; + + var lsb = (byte) (glyph & 0xFFu); + var msb = (byte) ((glyph >> 8) & 0xFFu); + + // ensure we accommodate key repeat counts + for (var n = 0; n < record.Event.KeyEvent.wRepeatCount; n++) + { + buffer[offset + charsRead * BytesPerWChar] = lsb; + buffer[offset + charsRead * BytesPerWChar + 1] = msb; + + charsRead++; + } + } + else + { + // ignore focus events (not doing so makes debugging absolutely hilarious) + if (record.EventType != Kernel32.EVENT_TYPE.FOCUS_EVENT) + { + // I assume success adding records - this is not so critical + // if it is critical to you, loop on this with a miniscule delay + _nonKeyEvents.TryAdd(record); + } + } + } + + bytesRead = charsRead * BytesPerWChar; + + // we should continue to block if no chars read (KEY_EVENT) + // even though non-key events were dispatched + if (bytesRead == 0) goto waitForInput; + } + else + { + Debug.Assert(bytesRead == 0, "bytesRead == 0"); + } + + Debug.WriteLine("Read {0} character(s)", charsRead); + ret = Win32Error.ERROR_SUCCESS; + } + + var errCode = ret; + if (Win32Error.ERROR_SUCCESS != errCode) + throw NativeMethods.GetExceptionForWin32Error(errCode); + + return bytesRead; + } + + public override void Write(byte[] buffer, int offset, int count) + { + throw new NotImplementedException("Write operations not implemented."); + } + + public override void Flush() + { + throw new NotSupportedException("Flush/Write not supported."); + } + + public override void SetLength(long value) + { + throw new NotSupportedException("Seek not supported."); + } + + public override long Seek(long offset, SeekOrigin origin) + { + throw new NotSupportedException("Seek not supported."); + } + + private void ValidateRead(byte[] buffer, int offset, int count) + { + if (buffer == null) + throw new ArgumentNullException(nameof(buffer)); + if (offset < 0 || count < 0) + throw new ArgumentOutOfRangeException(offset < 0 ? nameof(offset) : nameof(count), + "offset or count cannot be negative numbers."); + if (buffer.Length - offset < count) + throw new ArgumentException("invalid offset length."); + + if (!CanRead) throw new NotSupportedException("Get read not supported."); + } + } +} \ No newline at end of file diff --git a/tools/ReadConsoleInputStream/ReadConsoleInputStreamDemo.csproj b/tools/ReadConsoleInputStream/ReadConsoleInputStreamDemo.csproj new file mode 100644 index 0000000000..e6b445ee51 --- /dev/null +++ b/tools/ReadConsoleInputStream/ReadConsoleInputStreamDemo.csproj @@ -0,0 +1,16 @@ + + + + Exe + netcoreapp2.2 + latest + true + Nivot.Terminal + + + + + + + + From 7eea98d4ea484479fd6ba4afce7485564851bba8 Mon Sep 17 00:00:00 2001 From: oising Date: Sun, 21 Apr 2019 13:32:04 -0400 Subject: [PATCH 77/89] add sln file --- .../ReadConsoleInputStreamDemo.sln | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 tools/ReadConsoleInputStream/ReadConsoleInputStreamDemo.sln diff --git a/tools/ReadConsoleInputStream/ReadConsoleInputStreamDemo.sln b/tools/ReadConsoleInputStream/ReadConsoleInputStreamDemo.sln new file mode 100644 index 0000000000..cc2566a4c7 --- /dev/null +++ b/tools/ReadConsoleInputStream/ReadConsoleInputStreamDemo.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.28803.156 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ReadConsoleInputStreamDemo", "ReadConsoleInputStreamDemo.csproj", "{62F500DE-4F06-4B46-B7AF-02AF21296F00}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {62F500DE-4F06-4B46-B7AF-02AF21296F00}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {62F500DE-4F06-4B46-B7AF-02AF21296F00}.Debug|Any CPU.Build.0 = Debug|Any CPU + {62F500DE-4F06-4B46-B7AF-02AF21296F00}.Release|Any CPU.ActiveCfg = Release|Any CPU + {62F500DE-4F06-4B46-B7AF-02AF21296F00}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {55A9793B-D717-4A6E-A8FE-ABC6CD3B17BA} + EndGlobalSection +EndGlobal From 7daea0a25c3cf954485abd47803e1c8bf6bdd6ef Mon Sep 17 00:00:00 2001 From: Will Fuqua Date: Tue, 23 Apr 2019 21:10:16 +0700 Subject: [PATCH 78/89] pull logic out of Program.cs There aren't any user-facing changes in this commit, just pulling logic out of Program.cs. All that remains in Program.cs is command line parsing. - The functions that wrote to the registry, the console, and the virtual terminal (--xterm) are now in their own files, implementing the `IConsoleTarget` interface - Move the utility method UIntToColor into ColorScheme, where it can be used as an indexer, e.g. myColorScheme[i] returns a System.Drawing.Color - The "export to INI" functionality is now in a "SchemeWriters" namespace; Parsers are now in a "SchemeParsers" namespace - Printing the color table is now in the ColorTable class. --- tools/ColorTool/ColorTool/ColorScheme.cs | 12 +- tools/ColorTool/ColorTool/ColorTable.cs | 232 ++++++++ tools/ColorTool/ColorTool/ConsoleAPI.cs | 5 +- .../ColorTool/ColorTool/ConsoleAttributes.cs | 3 +- .../ConsoleTargets/CurrentConsoleTarget.cs | 51 ++ .../ConsoleTargets/DefaultConsoleTarget.cs | 28 + .../ConsoleTargets/IConsoleTarget.cs | 15 + .../VirtualTerminalConsoleTarget.cs | 67 +++ tools/ColorTool/ColorTool/Program.cs | 499 +----------------- tools/ColorTool/ColorTool/Scheme.cs | 41 -- tools/ColorTool/ColorTool/SchemeManager.cs | 112 ++++ .../{ => SchemeParsers}/ISchemeParser.cs | 4 +- .../{ => SchemeParsers}/IniSchemeParser.cs | 8 +- .../{ => SchemeParsers}/JsonParser.cs | 13 +- .../{ => SchemeParsers}/XmlSchemeParser.cs | 8 +- .../SchemeWriters/IniSchemeWriter.cs | 66 +++ 16 files changed, 617 insertions(+), 547 deletions(-) create mode 100644 tools/ColorTool/ColorTool/ColorTable.cs create mode 100644 tools/ColorTool/ColorTool/ConsoleTargets/CurrentConsoleTarget.cs create mode 100644 tools/ColorTool/ColorTool/ConsoleTargets/DefaultConsoleTarget.cs create mode 100644 tools/ColorTool/ColorTool/ConsoleTargets/IConsoleTarget.cs create mode 100644 tools/ColorTool/ColorTool/ConsoleTargets/VirtualTerminalConsoleTarget.cs delete mode 100644 tools/ColorTool/ColorTool/Scheme.cs create mode 100644 tools/ColorTool/ColorTool/SchemeManager.cs rename tools/ColorTool/ColorTool/{ => SchemeParsers}/ISchemeParser.cs (74%) rename tools/ColorTool/ColorTool/{ => SchemeParsers}/IniSchemeParser.cs (97%) rename tools/ColorTool/ColorTool/{ => SchemeParsers}/JsonParser.cs (94%) rename tools/ColorTool/ColorTool/{ => SchemeParsers}/XmlSchemeParser.cs (96%) create mode 100644 tools/ColorTool/ColorTool/SchemeWriters/IniSchemeWriter.cs diff --git a/tools/ColorTool/ColorTool/ColorScheme.cs b/tools/ColorTool/ColorTool/ColorScheme.cs index f930f31e54..507558f57d 100644 --- a/tools/ColorTool/ColorTool/ColorScheme.cs +++ b/tools/ColorTool/ColorTool/ColorScheme.cs @@ -1,9 +1,10 @@ // -// Copyright (C) Microsoft. All rights reserved. +// Copyright (C) Microsoft. All rights reserved. // Licensed under the terms described in the LICENSE file in the root of this project. // using System; +using System.Drawing; using System.Linq; namespace ColorTool @@ -13,6 +14,15 @@ namespace ColorTool public uint[] colorTable = null; public ConsoleAttributes consoleAttributes; + public Color this[int index] => UIntToColor(colorTable[index]); + + private static Color UIntToColor(uint color) + { + byte r = (byte)(color >> 0); + byte g = (byte)(color >> 8); + byte b = (byte)(color >> 16); + return Color.FromArgb(r, g, b); + } public int CalculateIndex(uint value) => colorTable.Select((color, idx) => Tuple.Create(color, idx)) diff --git a/tools/ColorTool/ColorTool/ColorTable.cs b/tools/ColorTool/ColorTool/ColorTable.cs new file mode 100644 index 0000000000..7f5e3742cc --- /dev/null +++ b/tools/ColorTool/ColorTool/ColorTable.cs @@ -0,0 +1,232 @@ +// +// Copyright (C) Microsoft. All rights reserved. +// Licensed under the terms described in the LICENSE file in the root of this project. +// + +using System; + +namespace ColorTool +{ + class ColorTable + { + static int DARK_BLACK = 0; + static int DARK_BLUE = 1; + static int DARK_GREEN = 2; + static int DARK_CYAN = 3; + static int DARK_RED = 4; + static int DARK_MAGENTA = 5; + static int DARK_YELLOW = 6; + static int DARK_WHITE = 7; + static int BRIGHT_BLACK = 8; + static int BRIGHT_BLUE = 9; + static int BRIGHT_GREEN = 10; + static int BRIGHT_CYAN = 11; + static int BRIGHT_RED = 12; + static int BRIGHT_MAGENTA = 13; + static int BRIGHT_YELLOW = 14; + static int BRIGHT_WHITE = 15; + + // This is the order of colors when output by the table. + static int[] outputFgs = { + BRIGHT_WHITE , + DARK_BLACK , + BRIGHT_BLACK , + DARK_RED , + BRIGHT_RED , + DARK_GREEN , + BRIGHT_GREEN , + DARK_YELLOW , + BRIGHT_YELLOW , + DARK_BLUE , + BRIGHT_BLUE , + DARK_MAGENTA , + BRIGHT_MAGENTA , + DARK_CYAN , + BRIGHT_CYAN , + DARK_WHITE , + BRIGHT_WHITE + }; + + + static int[] saneBgs = { + DARK_BLACK , + DARK_RED , + DARK_GREEN , + DARK_YELLOW , + DARK_BLUE , + DARK_MAGENTA , + DARK_CYAN , + DARK_WHITE + }; + + + public static void PrintTable() + { + ConsoleColor[] colors = (ConsoleColor[])ConsoleColor.GetValues(typeof(ConsoleColor)); + // Save the current background and foreground colors. + ConsoleColor currentBackground = Console.BackgroundColor; + ConsoleColor currentForeground = Console.ForegroundColor; + string test = " gYw "; + string[] FGs = { + "m", + "1m", + "30m", + "1;30m", + "31m", + "1;31m", + "32m", + "1;32m", + "33m", + "1;33m", + "34m", + "1;34m", + "35m", + "1;35m", + "36m", + "1;36m", + "37m", + "1;37m" + }; + string[] BGs = { + "m", + "40m", + "41m", + "42m", + "43m", + "44m", + "45m", + "46m", + "47m" + }; + + Console.Write("\t"); + for (int bg = 0; bg < BGs.Length; bg++) + { + if (bg > 0) Console.Write(" "); + Console.Write(" "); + Console.Write(bg == 0 ? " " : BGs[bg]); + Console.Write(" "); + } + Console.WriteLine(); + + for (int fg = 0; fg < FGs.Length; fg++) + { + Console.ForegroundColor = currentForeground; + Console.BackgroundColor = currentBackground; + + if (fg >= 0) Console.Write(FGs[fg] + "\t"); + + if (fg == 0) Console.ForegroundColor = currentForeground; + else Console.ForegroundColor = colors[outputFgs[fg - 1]]; + + for (int bg = 0; bg < BGs.Length; bg++) + { + if (bg > 0) Console.Write(" "); + if (bg == 0) + Console.BackgroundColor = currentBackground; + else Console.BackgroundColor = colors[saneBgs[bg - 1]]; + Console.Write(test); + Console.BackgroundColor = currentBackground; + } + Console.Write("\n"); + + } + Console.Write("\n"); + + // Reset foreground and background colors + Console.ForegroundColor = currentForeground; + Console.BackgroundColor = currentBackground; + } + + public static void PrintTableWithVt() + { + // Save the current background and foreground colors. + string test = " gYw "; + string[] FGs = { + "m", + "1m", + "30m", + "1;30m", + "31m", + "1;31m", + "32m", + "1;32m", + "33m", + "1;33m", + "34m", + "1;34m", + "35m", + "1;35m", + "36m", + "1;36m", + "37m", + "1;37m" + }; + string[] BGs = { + "m", + "40m", + "41m", + "42m", + "43m", + "44m", + "45m", + "46m", + "47m" + }; + + Console.Write("\t"); + for (int bg = 0; bg < BGs.Length; bg++) + { + if (bg > 0) Console.Write(" "); + Console.Write(" "); + Console.Write(bg == 0 ? " " : BGs[bg]); + Console.Write(" "); + } + Console.WriteLine(); + + for (int fg = 0; fg < FGs.Length; fg++) + { + Console.Write("\x1b[m"); + + if (fg >= 0) + { + Console.Write(FGs[fg] + "\t"); + } + + if (fg == 0) + { + Console.Write("\x1b[39m"); + } + else + { + Console.Write("\x1b[" + FGs[fg]); + } + + for (int bg = 0; bg < BGs.Length; bg++) + { + if (bg > 0) + { + Console.Write(" "); + } + if (bg == 0) + { + Console.Write("\x1b[49m"); + } + else + { + Console.Write("\x1b[" + BGs[bg]); + } + + Console.Write(test); + Console.Write("\x1b[49m"); + } + Console.Write("\n"); + + } + Console.Write("\n"); + + // Reset foreground and background colors + Console.Write("\x1b[m"); + } + } +} diff --git a/tools/ColorTool/ColorTool/ConsoleAPI.cs b/tools/ColorTool/ColorTool/ConsoleAPI.cs index 3219d34e01..1f1c62309c 100644 --- a/tools/ColorTool/ColorTool/ConsoleAPI.cs +++ b/tools/ColorTool/ColorTool/ConsoleAPI.cs @@ -1,5 +1,5 @@ // -// Copyright (C) Microsoft. All rights reserved. +// Copyright (C) Microsoft. All rights reserved. // Licensed under the terms described in the LICENSE file in the root of this project. // @@ -60,6 +60,9 @@ namespace ColorTool public static int STD_OUTPUT_HANDLE = -11; + + public static IntPtr GetStdOutputHandle() => GetStdHandle(STD_OUTPUT_HANDLE); + [DllImport("kernel32.dll", SetLastError = true)] public static extern IntPtr GetStdHandle(int nStdHandle); diff --git a/tools/ColorTool/ColorTool/ConsoleAttributes.cs b/tools/ColorTool/ColorTool/ConsoleAttributes.cs index ac2d9bceb3..17b5c7387d 100644 --- a/tools/ColorTool/ColorTool/ConsoleAttributes.cs +++ b/tools/ColorTool/ColorTool/ConsoleAttributes.cs @@ -1,5 +1,5 @@ // -// Copyright (C) Microsoft. All rights reserved. +// Copyright (C) Microsoft. All rights reserved. // Licensed under the terms described in the LICENSE file in the root of this project. // @@ -12,6 +12,5 @@ namespace ColorTool public uint? popupForeground; public uint? popupBackground; - } } diff --git a/tools/ColorTool/ColorTool/ConsoleTargets/CurrentConsoleTarget.cs b/tools/ColorTool/ColorTool/ConsoleTargets/CurrentConsoleTarget.cs new file mode 100644 index 0000000000..97a9c95ba0 --- /dev/null +++ b/tools/ColorTool/ColorTool/ConsoleTargets/CurrentConsoleTarget.cs @@ -0,0 +1,51 @@ +// +// Copyright (C) Microsoft. All rights reserved. +// Licensed under the terms described in the LICENSE file in the root of this project. +// + +using System; +using static ColorTool.ConsoleAPI; + +namespace ColorTool.ConsoleTargets +{ + /// + /// A console target that writes to the currently open console. + /// + class CurrentConsoleTarget : IConsoleTarget + { + public void ApplyColorScheme(ColorScheme colorScheme, bool quietMode) + { + CONSOLE_SCREEN_BUFFER_INFO_EX csbiex = CONSOLE_SCREEN_BUFFER_INFO_EX.Create(); + IntPtr hOut = GetStdOutputHandle(); + bool success = GetConsoleScreenBufferInfoEx(hOut, ref csbiex); + if (!success) + { + throw new InvalidOperationException("Could not obtain console screen buffer"); + } + + csbiex.srWindow.Bottom++; + for (int i = 0; i < 16; i++) + { + csbiex.ColorTable[i] = colorScheme.colorTable[i]; + } + if (colorScheme.consoleAttributes.background != null && colorScheme.consoleAttributes.foreground != null) + { + int fgidx = colorScheme.CalculateIndex(colorScheme.consoleAttributes.foreground.Value); + int bgidx = colorScheme.CalculateIndex(colorScheme.consoleAttributes.background.Value); + csbiex.wAttributes = (ushort)(fgidx | (bgidx << 4)); + } + if (colorScheme.consoleAttributes.popupBackground != null && colorScheme.consoleAttributes.popupForeground != null) + { + int fgidx = colorScheme.CalculateIndex(colorScheme.consoleAttributes.popupForeground.Value); + int bgidx = colorScheme.CalculateIndex(colorScheme.consoleAttributes.popupBackground.Value); + csbiex.wPopupAttributes = (ushort)(fgidx | (bgidx << 4)); + } + SetConsoleScreenBufferInfoEx(hOut, ref csbiex); + + if (!quietMode) + { + ColorTable.PrintTable(); + } + } + } +} diff --git a/tools/ColorTool/ColorTool/ConsoleTargets/DefaultConsoleTarget.cs b/tools/ColorTool/ColorTool/ConsoleTargets/DefaultConsoleTarget.cs new file mode 100644 index 0000000000..bb36487016 --- /dev/null +++ b/tools/ColorTool/ColorTool/ConsoleTargets/DefaultConsoleTarget.cs @@ -0,0 +1,28 @@ +// +// Copyright (C) Microsoft. All rights reserved. +// Licensed under the terms described in the LICENSE file in the root of this project. +// + +using Microsoft.Win32; +using System; + +namespace ColorTool.ConsoleTargets +{ + /// + /// A console target that writes to the Windows registry to modify system defaults + /// + class DefaultConsoleTarget : IConsoleTarget + { + public void ApplyColorScheme(ColorScheme colorScheme, bool quietMode) + { + //TODO + RegistryKey consoleKey = Registry.CurrentUser.OpenSubKey("Console", true); + for (int i = 0; i < colorScheme.colorTable.Length; i++) + { + string valueName = "ColorTable" + (i < 10 ? "0" : "") + i; + consoleKey.SetValue(valueName, colorScheme.colorTable[i], RegistryValueKind.DWord); + } + Console.WriteLine(Resources.WroteToDefaults); + } + } +} diff --git a/tools/ColorTool/ColorTool/ConsoleTargets/IConsoleTarget.cs b/tools/ColorTool/ColorTool/ConsoleTargets/IConsoleTarget.cs new file mode 100644 index 0000000000..a1a2b9d2a8 --- /dev/null +++ b/tools/ColorTool/ColorTool/ConsoleTargets/IConsoleTarget.cs @@ -0,0 +1,15 @@ +// +// Copyright (C) Microsoft. All rights reserved. +// Licensed under the terms described in the LICENSE file in the root of this project. +// + +namespace ColorTool.ConsoleTargets +{ + /// + /// A console that can have a color scheme applied to it. + /// + interface IConsoleTarget + { + void ApplyColorScheme(ColorScheme colorScheme, bool quietMode); + } +} diff --git a/tools/ColorTool/ColorTool/ConsoleTargets/VirtualTerminalConsoleTarget.cs b/tools/ColorTool/ColorTool/ConsoleTargets/VirtualTerminalConsoleTarget.cs new file mode 100644 index 0000000000..ea660ab167 --- /dev/null +++ b/tools/ColorTool/ColorTool/ConsoleTargets/VirtualTerminalConsoleTarget.cs @@ -0,0 +1,67 @@ +// +// Copyright (C) Microsoft. All rights reserved. +// Licensed under the terms described in the LICENSE file in the root of this project. +// + +using System; +using System.Drawing; +using static ColorTool.ConsoleAPI; + +namespace ColorTool.ConsoleTargets +{ + /// + /// A console target that writes to the currently open console, using VT sequences. + /// + class VirtualTerminalConsoleTarget : IConsoleTarget + { + // Use a Console index in to get a VT index out. + static readonly int[] VT_INDICIES = { + 0, // DARK_BLACK + 4, // DARK_BLUE + 2, // DARK_GREEN + 6, // DARK_CYAN + 1, // DARK_RED + 5, // DARK_MAGENTA + 3, // DARK_YELLOW + 7, // DARK_WHITE + 8+0, // BRIGHT_BLACK + 8+4, // BRIGHT_BLUE + 8+2, // BRIGHT_GREEN + 8+6, // BRIGHT_CYAN + 8+1, // BRIGHT_RED + 8+5, // BRIGHT_MAGENTA + 8+3, // BRIGHT_YELLOW + 8+7,// BRIGHT_WHITE + }; + + public void ApplyColorScheme(ColorScheme colorScheme, bool quietMode) + { + IntPtr hOut = GetStdOutputHandle(); + uint originalMode; + uint requestedMode; + bool succeeded = GetConsoleMode(hOut, out originalMode); + if (succeeded) + { + requestedMode = originalMode | (uint)ConsoleAPI.ConsoleOutputModes.ENABLE_VIRTUAL_TERMINAL_PROCESSING; + SetConsoleMode(hOut, requestedMode); + } + + for (int i = 0; i < colorScheme.colorTable.Length; i++) + { + int vtIndex = VT_INDICIES[i]; + Color color = colorScheme[i]; + string s = $"\x1b]4;{vtIndex};rgb:{color.R:X}/{color.G:X}/{color.B:X}\x7"; + Console.Write(s); + } + if (!quietMode) + { + ColorTable.PrintTableWithVt(); + } + + if (succeeded) + { + SetConsoleMode(hOut, originalMode); + } + } + } +} diff --git a/tools/ColorTool/ColorTool/Program.cs b/tools/ColorTool/ColorTool/Program.cs index 3496d606de..36fe40fe3c 100644 --- a/tools/ColorTool/ColorTool/Program.cs +++ b/tools/ColorTool/ColorTool/Program.cs @@ -1,110 +1,17 @@ // -// Copyright (C) Microsoft. All rights reserved. +// Copyright (C) Microsoft. All rights reserved. // Licensed under the terms described in the LICENSE file in the root of this project. // -using Microsoft.Win32; +using ColorTool.ConsoleTargets; +using ColorTool.SchemeWriters; using System; -using System.Collections.Generic; -using System.Drawing; -using System.IO; using System.Linq; -using System.Reflection; -using System.Runtime.InteropServices; -using static ColorTool.ConsoleAPI; namespace ColorTool { class Program { - static int DARK_BLACK = 0; - static int DARK_BLUE = 1; - static int DARK_GREEN = 2; - static int DARK_CYAN = 3; - static int DARK_RED = 4; - static int DARK_MAGENTA = 5; - static int DARK_YELLOW = 6; - static int DARK_WHITE = 7; - static int BRIGHT_BLACK = 8; - static int BRIGHT_BLUE = 9; - static int BRIGHT_GREEN = 10; - static int BRIGHT_CYAN = 11; - static int BRIGHT_RED = 12; - static int BRIGHT_MAGENTA = 13; - static int BRIGHT_YELLOW = 14; - static int BRIGHT_WHITE = 15; - - static int[] saneFgs = { - DARK_BLACK , - DARK_RED , - DARK_GREEN , - DARK_YELLOW , - DARK_BLUE , - DARK_MAGENTA , - DARK_CYAN , - DARK_WHITE , - BRIGHT_BLACK , - BRIGHT_RED , - BRIGHT_GREEN , - BRIGHT_YELLOW , - BRIGHT_MAGENTA , - BRIGHT_BLUE , - BRIGHT_CYAN , - BRIGHT_WHITE - }; - - // This is the order of colors when output by the table. - static int[] outputFgs = { - BRIGHT_WHITE , - DARK_BLACK , - BRIGHT_BLACK , - DARK_RED , - BRIGHT_RED , - DARK_GREEN , - BRIGHT_GREEN , - DARK_YELLOW , - BRIGHT_YELLOW , - DARK_BLUE , - BRIGHT_BLUE , - DARK_MAGENTA , - BRIGHT_MAGENTA , - DARK_CYAN , - BRIGHT_CYAN , - DARK_WHITE , - BRIGHT_WHITE - }; - - static int[] saneBgs = { - DARK_BLACK , - DARK_RED , - DARK_GREEN , - DARK_YELLOW , - DARK_BLUE , - DARK_MAGENTA , - DARK_CYAN , - DARK_WHITE - }; - - // Use a Console index in to get a VT index out. - static int[] VT_INDICIES = { - 0, // DARK_BLACK - 4, // DARK_BLUE - 2, // DARK_GREEN - 6, // DARK_CYAN - 1, // DARK_RED - 5, // DARK_MAGENTA - 3, // DARK_YELLOW - 7, // DARK_WHITE - 8+0, // BRIGHT_BLACK - 8+4, // BRIGHT_BLUE - 8+2, // BRIGHT_GREEN - 8+6, // BRIGHT_CYAN - 8+1, // BRIGHT_RED - 8+5, // BRIGHT_MAGENTA - 8+3, // BRIGHT_YELLOW - 8+7,// BRIGHT_WHITE - }; - static bool quietMode = false; static bool reportErrors = false; static bool setDefaults = false; @@ -114,7 +21,7 @@ namespace ColorTool static void Usage() { Console.WriteLine(Resources.Usage, - string.Join($"{Environment.NewLine} ", GetParsers().Select(p => p.Name))); + string.Join($"{Environment.NewLine} ", SchemeManager.GetParsers().Select(p => p.Name))); } static void OutputUsage() @@ -129,368 +36,6 @@ namespace ColorTool Console.WriteLine($"colortool v{info.FileVersion}"); } - static void PrintTable() - { - ConsoleColor[] colors = (ConsoleColor[])ConsoleColor.GetValues(typeof(ConsoleColor)); - // Save the current background and foreground colors. - ConsoleColor currentBackground = Console.BackgroundColor; - ConsoleColor currentForeground = Console.ForegroundColor; - string test = " gYw "; - string[] FGs = { - "m", - "1m", - "30m", - "1;30m", - "31m", - "1;31m", - "32m", - "1;32m", - "33m", - "1;33m", - "34m", - "1;34m", - "35m", - "1;35m", - "36m", - "1;36m", - "37m", - "1;37m" - }; - string[] BGs = { - "m", - "40m", - "41m", - "42m", - "43m", - "44m", - "45m", - "46m", - "47m" - }; - - Console.Write("\t"); - for (int bg = 0; bg < BGs.Length; bg++) - { - if (bg > 0) Console.Write(" "); - Console.Write(" "); - Console.Write(bg == 0 ? " " : BGs[bg]); - Console.Write(" "); - } - Console.WriteLine(); - - for (int fg = 0; fg < FGs.Length; fg++) - { - Console.ForegroundColor = currentForeground; - Console.BackgroundColor = currentBackground; - - if (fg >= 0) Console.Write(FGs[fg] + "\t"); - - if (fg == 0) Console.ForegroundColor = currentForeground; - else Console.ForegroundColor = colors[outputFgs[fg - 1]]; - - for (int bg = 0; bg < BGs.Length; bg++) - { - if (bg > 0) Console.Write(" "); - if (bg == 0) - Console.BackgroundColor = currentBackground; - else Console.BackgroundColor = colors[saneBgs[bg - 1]]; - Console.Write(test); - Console.BackgroundColor = currentBackground; - } - Console.Write("\n"); - - } - Console.Write("\n"); - - // Reset foreground and background colors - Console.ForegroundColor = currentForeground; - Console.BackgroundColor = currentBackground; - } - - static void PrintTableWithVt() - { - // Save the current background and foreground colors. - string test = " gYw "; - string[] FGs = { - "m", - "1m", - "30m", - "1;30m", - "31m", - "1;31m", - "32m", - "1;32m", - "33m", - "1;33m", - "34m", - "1;34m", - "35m", - "1;35m", - "36m", - "1;36m", - "37m", - "1;37m" - }; - string[] BGs = { - "m", - "40m", - "41m", - "42m", - "43m", - "44m", - "45m", - "46m", - "47m" - }; - - Console.Write("\t"); - for (int bg = 0; bg < BGs.Length; bg++) - { - if (bg > 0) Console.Write(" "); - Console.Write(" "); - Console.Write(bg == 0 ? " " : BGs[bg]); - Console.Write(" "); - } - Console.WriteLine(); - - for (int fg = 0; fg < FGs.Length; fg++) - { - Console.Write("\x1b[m"); - - if (fg >= 0) - { - Console.Write(FGs[fg] + "\t"); - } - - if (fg == 0) - { - Console.Write("\x1b[39m"); - } - else - { - Console.Write("\x1b[" + FGs[fg]); - } - - for (int bg = 0; bg < BGs.Length; bg++) - { - if (bg > 0) - { - Console.Write(" "); - } - if (bg == 0) - { - Console.Write("\x1b[49m"); - } - else - { - Console.Write("\x1b[" + BGs[bg]); - } - - Console.Write(test); - Console.Write("\x1b[49m"); - } - Console.Write("\n"); - - } - Console.Write("\n"); - - // Reset foreground and background colors - Console.Write("\x1b[m"); - } - - private static IntPtr GetStdOutputHandle() - { - return GetStdHandle(STD_OUTPUT_HANDLE); - } - - static void PrintSchemes() - { - var schemeDirectory = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "schemes"); - - if (Directory.Exists(schemeDirectory)) - { - IntPtr handle = GetStdOutputHandle(); - GetConsoleMode(handle, out var mode); - SetConsoleMode(handle, mode | 0x4); - - int consoleWidth = Console.WindowWidth; - string fgText = " gYw "; - foreach (string schemeName in Directory.GetFiles(schemeDirectory).Select(Path.GetFileName)) - { - ColorScheme colorScheme = GetScheme(schemeName, false); - if (colorScheme != null) - { - string colors = string.Empty; - for (var index = 0; index < 8; index++) - { - uint t = colorScheme.colorTable[index]; - var color = UIntToColor(t); - // Set the background color to the color in the scheme, plus some text to show how it looks - colors += $"\x1b[48;2;{color.R};{color.G};{color.B}m{fgText}"; - } - // Align scheme colors right, or on newline if it doesn't fit - int schemeTextLength = fgText.Length * 8; - int bufferLength = consoleWidth - (schemeName.Length + schemeTextLength); - - string bufferString = bufferLength >= 0 - ? new string(' ', bufferLength) - : "\n" + new string(' ', consoleWidth - schemeTextLength); - - string outputString = schemeName + bufferString + colors; - Console.WriteLine(outputString); - Console.ResetColor(); - } - } - } - } - - static void PrintSchemesDirectory() - { - string schemeDirectory = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "schemes"); - Console.WriteLine(schemeDirectory); - } - - private static Color UIntToColor(uint color) - { - byte r = (byte)(color >> 0); - byte g = (byte)(color >> 8); - byte b = (byte)(color >> 16); - return Color.FromArgb(r, g, b); - } - - static bool SetProperties(ColorScheme colorScheme) - { - CONSOLE_SCREEN_BUFFER_INFO_EX csbiex = CONSOLE_SCREEN_BUFFER_INFO_EX.Create(); - IntPtr hOut = GetStdOutputHandle(); - bool success = GetConsoleScreenBufferInfoEx(hOut, ref csbiex); - if (success) - { - csbiex.srWindow.Bottom++; - for (int i = 0; i < 16; i++) - { - csbiex.ColorTable[i] = colorScheme.colorTable[i]; - } - if (colorScheme.consoleAttributes.background != null && colorScheme.consoleAttributes.foreground != null) - { - int fgidx = colorScheme.CalculateIndex(colorScheme.consoleAttributes.foreground.Value); - int bgidx = colorScheme.CalculateIndex(colorScheme.consoleAttributes.background.Value); - csbiex.wAttributes = (ushort)(fgidx | (bgidx << 4)); - } - if (colorScheme.consoleAttributes.popupBackground != null && colorScheme.consoleAttributes.popupForeground != null) - { - int fgidx = colorScheme.CalculateIndex(colorScheme.consoleAttributes.popupForeground.Value); - int bgidx = colorScheme.CalculateIndex(colorScheme.consoleAttributes.popupBackground.Value); - csbiex.wPopupAttributes = (ushort)(fgidx | (bgidx << 4)); - } - SetConsoleScreenBufferInfoEx(hOut, ref csbiex); - } - if (success) - { - if (!quietMode) - { - PrintTable(); - } - } - return success; - } - - static bool SetPropertiesWithVt(ColorScheme colorScheme) - { - IntPtr hOut = GetStdOutputHandle(); - uint originalMode; - uint requestedMode; - bool succeeded = GetConsoleMode(hOut, out originalMode); - if (succeeded) - { - requestedMode = originalMode | (uint)ConsoleAPI.ConsoleOutputModes.ENABLE_VIRTUAL_TERMINAL_PROCESSING; - SetConsoleMode(hOut, requestedMode); - - } - - for (int i = 0; i < colorScheme.colorTable.Length; i++) - { - int vtIndex = VT_INDICIES[i]; - Color color = UIntToColor(colorScheme.colorTable[i]); - string s = $"\x1b]4;{vtIndex};rgb:{color.R:X}/{color.G:X}/{color.B:X}\x7"; - Console.Write(s); - } - if (!quietMode) - { - PrintTableWithVt(); - } - - if (succeeded) - { - SetConsoleMode(hOut, originalMode); - } - - return true; - } - static bool SetDefaults(ColorScheme colorScheme) - { - //TODO - RegistryKey consoleKey = Registry.CurrentUser.OpenSubKey("Console", true); - for (int i = 0; i < colorScheme.colorTable.Length; i++) - { - string valueName = "ColorTable" + (i < 10 ? "0" : "") + i; - consoleKey.SetValue(valueName, colorScheme.colorTable[i], RegistryValueKind.DWord); - } - Console.WriteLine(Resources.WroteToDefaults); - return true; - } - - static bool ExportCurrentAsIni(string outputPath) - { - CONSOLE_SCREEN_BUFFER_INFO_EX csbiex = CONSOLE_SCREEN_BUFFER_INFO_EX.Create(); - IntPtr hOut = GetStdOutputHandle(); - bool success = GetConsoleScreenBufferInfoEx(hOut, ref csbiex); - if (success) - { - try - { - // StreamWriter can fail for a variety of file system reasons so catch exceptions and print message. - using (System.IO.StreamWriter file = new System.IO.StreamWriter(outputPath)) - { - file.WriteLine("[table]"); - for (int i = 0; i < 16; i++) - { - string line = IniSchemeParser.COLOR_NAMES[i]; - line += " = "; - uint color = csbiex.ColorTable[i]; - uint r = color & (0x000000ff); - uint g = (color & (0x0000ff00)) >> 8; - uint b = (color & (0x00ff0000)) >> 16; - line += r + "," + g + "," + b; - file.WriteLine(line); - } - - file.WriteLine(); - file.WriteLine("[screen]"); - var forgroundIndex = csbiex.wAttributes & 0xF; - var backgroundIndex = csbiex.wAttributes >> 4; - file.WriteLine($"FOREGROUND = {IniSchemeParser.COLOR_NAMES[forgroundIndex]}"); - file.WriteLine($"BACKGROUND = {IniSchemeParser.COLOR_NAMES[backgroundIndex]}"); - - file.WriteLine(); - file.WriteLine("[popup]"); - forgroundIndex = csbiex.wPopupAttributes & 0xF; - backgroundIndex = csbiex.wPopupAttributes >> 4; - file.WriteLine($"FOREGROUND = {IniSchemeParser.COLOR_NAMES[forgroundIndex]}"); - file.WriteLine($"BACKGROUND = {IniSchemeParser.COLOR_NAMES[backgroundIndex]}"); - } - } - catch (Exception ex) - { - Console.WriteLine(ex.Message); - } - } - else - { - Console.WriteLine("Failed to get console information."); - } - return success; - } - static void Main(string[] args) { if (args.Length < 1) @@ -505,7 +50,7 @@ namespace ColorTool { case "-c": case "--current": - PrintTable(); + ColorTable.PrintTable(); return; case "-e": case "--errors": @@ -535,7 +80,7 @@ namespace ColorTool return; case "-l": case "--location": - PrintSchemesDirectory(); + SchemeManager.PrintSchemesDirectory(); return; case "-x": case "--xterm": @@ -546,7 +91,7 @@ namespace ColorTool case "--output": if (i + 1 < args.Length) { - ExportCurrentAsIni(args[i + 1]); + new IniSchemeWriter().ExportCurrentAsIni(args[i + 1]); } else { @@ -555,7 +100,7 @@ namespace ColorTool return; case "-s": case "--schemes": - PrintSchemes(); + SchemeManager.PrintSchemes(); return; default: break; @@ -564,7 +109,7 @@ namespace ColorTool string schemeName = args[args.Length - 1]; - ColorScheme colorScheme = GetScheme(schemeName, reportErrors); + ColorScheme colorScheme = SchemeManager.GetScheme(schemeName, reportErrors); if (colorScheme == null) { @@ -574,39 +119,19 @@ namespace ColorTool if (setDefaults) { - SetDefaults(colorScheme); + new DefaultConsoleTarget().ApplyColorScheme(colorScheme, quietMode); } if (setProperties) { if (setUnixStyle) { - SetPropertiesWithVt(colorScheme); + new VirtualTerminalConsoleTarget().ApplyColorScheme(colorScheme, quietMode); } else { - SetProperties(colorScheme); + new CurrentConsoleTarget().ApplyColorScheme(colorScheme, quietMode); } } } - - private static IEnumerable GetParsers() - { - return typeof(Program).Assembly.GetTypes() - .Where(t => !t.IsAbstract && typeof(ISchemeParser).IsAssignableFrom(t)) - .Select(t => (ISchemeParser)Activator.CreateInstance(t)); - } - - private static ColorScheme GetScheme(string schemeName, bool reportErrors = false) - { - foreach (var parser in GetParsers()) - { - ColorScheme scheme = parser.ParseScheme(schemeName, reportErrors); - if (scheme != null) - { - return scheme; - } - } - return null; - } } } diff --git a/tools/ColorTool/ColorTool/Scheme.cs b/tools/ColorTool/ColorTool/Scheme.cs deleted file mode 100644 index 3d7eb6ce72..0000000000 --- a/tools/ColorTool/ColorTool/Scheme.cs +++ /dev/null @@ -1,41 +0,0 @@ -// -// Copyright (C) Microsoft. All rights reserved. -// Licensed under the terms described in the LICENSE file in the root of this project. -// - -using System.Collections.Generic; -using System.IO; - -namespace ColorTool -{ - static class Scheme - { - public static IEnumerable GetSearchPaths(string schemeName, string extension) - { - // Search order, for argument "name", where 'exe' is the dir of the exe. - // 1. ./name - // 2. ./name.ext - // 3. ./schemes/name - // 4. ./schemes/name.ext - // 5. exe/schemes/name - // 6. exe/schemes/name.ext - // 7. name (as an absolute path) - - string cwd = "./"; - yield return cwd + schemeName; - - string filename = schemeName + extension; - yield return cwd + filename; - - string cwdSchemes = "./schemes/"; - yield return cwdSchemes + schemeName; - yield return cwdSchemes + filename; - - string exeDir = Directory.GetParent(System.Reflection.Assembly.GetEntryAssembly().Location).FullName; - string exeSchemes = exeDir + "/schemes/"; - yield return exeSchemes + schemeName; - yield return exeSchemes + filename; - yield return schemeName; - } - } -} \ No newline at end of file diff --git a/tools/ColorTool/ColorTool/SchemeManager.cs b/tools/ColorTool/ColorTool/SchemeManager.cs new file mode 100644 index 0000000000..09b3ee341d --- /dev/null +++ b/tools/ColorTool/ColorTool/SchemeManager.cs @@ -0,0 +1,112 @@ +// +// Copyright (C) Microsoft. All rights reserved. +// Licensed under the terms described in the LICENSE file in the root of this project. +// + +using ColorTool.SchemeParsers; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using static ColorTool.ConsoleAPI; + +namespace ColorTool +{ + static class SchemeManager + { + public static IEnumerable GetSearchPaths(string schemeName, string extension) + { + // Search order, for argument "name", where 'exe' is the dir of the exe. + // 1. ./name + // 2. ./name.ext + // 3. ./schemes/name + // 4. ./schemes/name.ext + // 5. exe/schemes/name + // 6. exe/schemes/name.ext + // 7. name (as an absolute path) + + string cwd = "./"; + yield return cwd + schemeName; + + string filename = schemeName + extension; + yield return cwd + filename; + + string cwdSchemes = "./schemes/"; + yield return cwdSchemes + schemeName; + yield return cwdSchemes + filename; + + string exeDir = Directory.GetParent(System.Reflection.Assembly.GetEntryAssembly().Location).FullName; + string exeSchemes = exeDir + "/schemes/"; + yield return exeSchemes + schemeName; + yield return exeSchemes + filename; + yield return schemeName; + } + + public static void PrintSchemesDirectory() + { + string schemeDirectory = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "schemes"); + Console.WriteLine(schemeDirectory); + } + + + public static void PrintSchemes() + { + var schemeDirectory = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "schemes"); + + if (Directory.Exists(schemeDirectory)) + { + IntPtr handle = GetStdOutputHandle(); + GetConsoleMode(handle, out var mode); + SetConsoleMode(handle, mode | 0x4); + + int consoleWidth = Console.WindowWidth; + string fgText = " gYw "; + foreach (string schemeName in Directory.GetFiles(schemeDirectory).Select(Path.GetFileName)) + { + ColorScheme colorScheme = GetScheme(schemeName, false); + if (colorScheme != null) + { + string colors = string.Empty; + for (var index = 0; index < 8; index++) + { + var color = colorScheme[index]; + // Set the background color to the color in the scheme, plus some text to show how it looks + colors += $"\x1b[48;2;{color.R};{color.G};{color.B}m{fgText}"; + } + // Align scheme colors right, or on newline if it doesn't fit + int schemeTextLength = fgText.Length * 8; + int bufferLength = consoleWidth - (schemeName.Length + schemeTextLength); + + string bufferString = bufferLength >= 0 + ? new string(' ', bufferLength) + : "\n" + new string(' ', consoleWidth - schemeTextLength); + + string outputString = schemeName + bufferString + colors; + Console.WriteLine(outputString); + Console.ResetColor(); + } + } + } + } + + public static ColorScheme GetScheme(string schemeName, bool reportErrors = false) + { + foreach (var parser in GetParsers()) + { + ColorScheme scheme = parser.ParseScheme(schemeName, reportErrors); + if (scheme != null) + { + return scheme; + } + } + return null; + } + + public static IEnumerable GetParsers() + { + return typeof(Program).Assembly.GetTypes() + .Where(t => !t.IsAbstract && typeof(ISchemeParser).IsAssignableFrom(t)) + .Select(t => (ISchemeParser)Activator.CreateInstance(t)); + } + } +} \ No newline at end of file diff --git a/tools/ColorTool/ColorTool/ISchemeParser.cs b/tools/ColorTool/ColorTool/SchemeParsers/ISchemeParser.cs similarity index 74% rename from tools/ColorTool/ColorTool/ISchemeParser.cs rename to tools/ColorTool/ColorTool/SchemeParsers/ISchemeParser.cs index 0153150943..c90c0bdb78 100644 --- a/tools/ColorTool/ColorTool/ISchemeParser.cs +++ b/tools/ColorTool/ColorTool/SchemeParsers/ISchemeParser.cs @@ -1,9 +1,9 @@ // -// Copyright (C) Microsoft. All rights reserved. +// Copyright (C) Microsoft. All rights reserved. // Licensed under the terms described in the LICENSE file in the root of this project. // -namespace ColorTool +namespace ColorTool.SchemeParsers { interface ISchemeParser { diff --git a/tools/ColorTool/ColorTool/IniSchemeParser.cs b/tools/ColorTool/ColorTool/SchemeParsers/IniSchemeParser.cs similarity index 97% rename from tools/ColorTool/ColorTool/IniSchemeParser.cs rename to tools/ColorTool/ColorTool/SchemeParsers/IniSchemeParser.cs index be332d6002..ee88001415 100644 --- a/tools/ColorTool/ColorTool/IniSchemeParser.cs +++ b/tools/ColorTool/ColorTool/SchemeParsers/IniSchemeParser.cs @@ -1,5 +1,5 @@ // -// Copyright (C) Microsoft. All rights reserved. +// Copyright (C) Microsoft. All rights reserved. // Licensed under the terms described in the LICENSE file in the root of this project. // @@ -7,11 +7,11 @@ using System; using System.Linq; using System.Text; using System.Runtime.InteropServices; -using static ColorTool.ConsoleAPI; using System.IO; using System.Collections.Generic; +using static ColorTool.ConsoleAPI; -namespace ColorTool +namespace ColorTool.SchemeParsers { class IniSchemeParser : ISchemeParser { @@ -74,7 +74,7 @@ namespace ColorTool static string FindIniScheme(string schemeName) { - return Scheme.GetSearchPaths(schemeName, ".ini").FirstOrDefault(File.Exists); + return SchemeManager.GetSearchPaths(schemeName, ".ini").FirstOrDefault(File.Exists); } public ColorScheme ParseScheme(string schemeName, bool reportErrors = false) diff --git a/tools/ColorTool/ColorTool/JsonParser.cs b/tools/ColorTool/ColorTool/SchemeParsers/JsonParser.cs similarity index 94% rename from tools/ColorTool/ColorTool/JsonParser.cs rename to tools/ColorTool/ColorTool/SchemeParsers/JsonParser.cs index dde2145df6..abb1f99333 100644 --- a/tools/ColorTool/ColorTool/JsonParser.cs +++ b/tools/ColorTool/ColorTool/SchemeParsers/JsonParser.cs @@ -1,14 +1,17 @@ -using System; +// +// Copyright (C) Microsoft. All rights reserved. +// Licensed under the terms described in the LICENSE file in the root of this project. +// + +using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Runtime.Serialization.Json; -using System.Text; -using System.Threading.Tasks; using System.Xml; using static ColorTool.ConsoleAPI; -namespace ColorTool +namespace ColorTool.SchemeParsers { class JsonParser : ISchemeParser { @@ -42,7 +45,7 @@ namespace ColorTool static XmlDocument loadJsonFile(string schemeName) { XmlDocument xmlDoc = new XmlDocument(); - foreach (string path in Scheme.GetSearchPaths(schemeName, ".json") + foreach (string path in SchemeManager.GetSearchPaths(schemeName, ".json") .Where(File.Exists)) { try diff --git a/tools/ColorTool/ColorTool/XmlSchemeParser.cs b/tools/ColorTool/ColorTool/SchemeParsers/XmlSchemeParser.cs similarity index 96% rename from tools/ColorTool/ColorTool/XmlSchemeParser.cs rename to tools/ColorTool/ColorTool/SchemeParsers/XmlSchemeParser.cs index 615a399bb3..412f5739d8 100644 --- a/tools/ColorTool/ColorTool/XmlSchemeParser.cs +++ b/tools/ColorTool/ColorTool/SchemeParsers/XmlSchemeParser.cs @@ -1,16 +1,16 @@ // -// Copyright (C) Microsoft. All rights reserved. +// Copyright (C) Microsoft. All rights reserved. // Licensed under the terms described in the LICENSE file in the root of this project. // + using System; using System.Globalization; using System.IO; using System.Linq; -using System.Linq.Expressions; using System.Xml; using static ColorTool.ConsoleAPI; -namespace ColorTool +namespace ColorTool.SchemeParsers { class XmlSchemeParser : ISchemeParser { @@ -82,7 +82,7 @@ namespace ColorTool static XmlDocument loadXmlScheme(string schemeName) { XmlDocument xmlDoc = new XmlDocument(); // Create an XML document object - foreach (string path in Scheme.GetSearchPaths(schemeName, ".itermcolors") + foreach (string path in SchemeManager.GetSearchPaths(schemeName, ".itermcolors") .Where(File.Exists)) { try diff --git a/tools/ColorTool/ColorTool/SchemeWriters/IniSchemeWriter.cs b/tools/ColorTool/ColorTool/SchemeWriters/IniSchemeWriter.cs new file mode 100644 index 0000000000..18b4bb6650 --- /dev/null +++ b/tools/ColorTool/ColorTool/SchemeWriters/IniSchemeWriter.cs @@ -0,0 +1,66 @@ +// +// Copyright (C) Microsoft. All rights reserved. +// Licensed under the terms described in the LICENSE file in the root of this project. +// + +using ColorTool.SchemeParsers; +using System; +using static ColorTool.ConsoleAPI; + +namespace ColorTool.SchemeWriters +{ + class IniSchemeWriter + { + public bool ExportCurrentAsIni(string outputPath) + { + CONSOLE_SCREEN_BUFFER_INFO_EX csbiex = CONSOLE_SCREEN_BUFFER_INFO_EX.Create(); + IntPtr hOut = GetStdOutputHandle(); + bool success = GetConsoleScreenBufferInfoEx(hOut, ref csbiex); + if (success) + { + try + { + // StreamWriter can fail for a variety of file system reasons so catch exceptions and print message. + using (System.IO.StreamWriter file = new System.IO.StreamWriter(outputPath)) + { + file.WriteLine("[table]"); + for (int i = 0; i < 16; i++) + { + string line = IniSchemeParser.COLOR_NAMES[i]; + line += " = "; + uint color = csbiex.ColorTable[i]; + uint r = color & (0x000000ff); + uint g = (color & (0x0000ff00)) >> 8; + uint b = (color & (0x00ff0000)) >> 16; + line += r + "," + g + "," + b; + file.WriteLine(line); + } + + file.WriteLine(); + file.WriteLine("[screen]"); + var forgroundIndex = csbiex.wAttributes & 0xF; + var backgroundIndex = csbiex.wAttributes >> 4; + file.WriteLine($"FOREGROUND = {IniSchemeParser.COLOR_NAMES[forgroundIndex]}"); + file.WriteLine($"BACKGROUND = {IniSchemeParser.COLOR_NAMES[backgroundIndex]}"); + + file.WriteLine(); + file.WriteLine("[popup]"); + forgroundIndex = csbiex.wPopupAttributes & 0xF; + backgroundIndex = csbiex.wPopupAttributes >> 4; + file.WriteLine($"FOREGROUND = {IniSchemeParser.COLOR_NAMES[forgroundIndex]}"); + file.WriteLine($"BACKGROUND = {IniSchemeParser.COLOR_NAMES[backgroundIndex]}"); + } + } + catch (Exception ex) + { + Console.WriteLine(ex.Message); + } + } + else + { + Console.WriteLine("Failed to get console information."); + } + return success; + } + } +} From 05f518db5bf20eb49c294c87396f81d7579e56bd Mon Sep 17 00:00:00 2001 From: Will Fuqua Date: Tue, 23 Apr 2019 21:51:05 +0700 Subject: [PATCH 79/89] replace mutable public fields with properties The properties are made readonly where possible, which is possible in almost all cases. --- tools/ColorTool/ColorTool/ColorScheme.cs | 27 ++- tools/ColorTool/ColorTool/ColorTable.cs | 207 ++++++++---------- tools/ColorTool/ColorTool/ColorTool.csproj | 2 +- .../ColorTool/ColorTool/ConsoleAttributes.cs | 17 +- .../ConsoleTargets/CurrentConsoleTarget.cs | 14 +- .../ConsoleTargets/DefaultConsoleTarget.cs | 4 +- .../VirtualTerminalConsoleTarget.cs | 8 +- .../SchemeParsers/IniSchemeParser.cs | 83 +++---- .../ColorTool/SchemeParsers/JsonParser.cs | 65 +++--- .../SchemeParsers/XmlSchemeParser.cs | 106 ++++----- 10 files changed, 264 insertions(+), 269 deletions(-) diff --git a/tools/ColorTool/ColorTool/ColorScheme.cs b/tools/ColorTool/ColorTool/ColorScheme.cs index 507558f57d..17fcb15796 100644 --- a/tools/ColorTool/ColorTool/ColorScheme.cs +++ b/tools/ColorTool/ColorTool/ColorScheme.cs @@ -9,12 +9,21 @@ using System.Linq; namespace ColorTool { + /// + /// Represents a colorscheme that can be applied to a console. + /// public class ColorScheme { - public uint[] colorTable = null; - public ConsoleAttributes consoleAttributes; + public ColorScheme(uint[] colorTable, ConsoleAttributes consoleAttributes) + { + ColorTable = colorTable; + ConsoleAttributes = consoleAttributes; + } - public Color this[int index] => UIntToColor(colorTable[index]); + public uint[] ColorTable { get; } + public ConsoleAttributes ConsoleAttributes { get; } + + public Color this[int index] => UIntToColor(ColorTable[index]); private static Color UIntToColor(uint color) { @@ -25,7 +34,7 @@ namespace ColorTool } public int CalculateIndex(uint value) => - colorTable.Select((color, idx) => Tuple.Create(color, idx)) + ColorTable.Select((color, idx) => Tuple.Create(color, idx)) .OrderBy(Difference(value)) .First().Item2; @@ -87,17 +96,17 @@ namespace ColorTool for (int i = 0; i < 16; ++i) { - _dump($"Color[{i}]", colorTable[i]); + _dump($"Color[{i}]", ColorTable[i]); } - if (consoleAttributes.foreground != null) + if (ConsoleAttributes.Foreground != null) { - _dump("FG ", consoleAttributes.foreground.Value); + _dump("FG ", ConsoleAttributes.Foreground.Value); } - if (consoleAttributes.background != null) + if (ConsoleAttributes.Background != null) { - _dump("BG ", consoleAttributes.background.Value); + _dump("BG ", ConsoleAttributes.Background.Value); } } } diff --git a/tools/ColorTool/ColorTool/ColorTable.cs b/tools/ColorTool/ColorTool/ColorTable.cs index 7f5e3742cc..53909a59f2 100644 --- a/tools/ColorTool/ColorTool/ColorTable.cs +++ b/tools/ColorTool/ColorTool/ColorTable.cs @@ -4,61 +4,102 @@ // using System; +using System.Collections.Generic; namespace ColorTool { + /// + /// Displays the color table that demonstrates the current colorscheme. + /// class ColorTable { - static int DARK_BLACK = 0; - static int DARK_BLUE = 1; - static int DARK_GREEN = 2; - static int DARK_CYAN = 3; - static int DARK_RED = 4; - static int DARK_MAGENTA = 5; - static int DARK_YELLOW = 6; - static int DARK_WHITE = 7; - static int BRIGHT_BLACK = 8; - static int BRIGHT_BLUE = 9; - static int BRIGHT_GREEN = 10; - static int BRIGHT_CYAN = 11; - static int BRIGHT_RED = 12; - static int BRIGHT_MAGENTA = 13; - static int BRIGHT_YELLOW = 14; - static int BRIGHT_WHITE = 15; + const int DARK_BLACK = 0; + const int DARK_BLUE = 1; + const int DARK_GREEN = 2; + const int DARK_CYAN = 3; + const int DARK_RED = 4; + const int DARK_MAGENTA = 5; + const int DARK_YELLOW = 6; + const int DARK_WHITE = 7; + const int BRIGHT_BLACK = 8; + const int BRIGHT_BLUE = 9; + const int BRIGHT_GREEN = 10; + const int BRIGHT_CYAN = 11; + const int BRIGHT_RED = 12; + const int BRIGHT_MAGENTA = 13; + const int BRIGHT_YELLOW = 14; + const int BRIGHT_WHITE = 15; // This is the order of colors when output by the table. - static int[] outputFgs = { - BRIGHT_WHITE , - DARK_BLACK , - BRIGHT_BLACK , - DARK_RED , - BRIGHT_RED , - DARK_GREEN , - BRIGHT_GREEN , - DARK_YELLOW , - BRIGHT_YELLOW , - DARK_BLUE , - BRIGHT_BLUE , - DARK_MAGENTA , - BRIGHT_MAGENTA , - DARK_CYAN , - BRIGHT_CYAN , - DARK_WHITE , + private static readonly IReadOnlyList outputFgs = new[] + { + BRIGHT_WHITE, + DARK_BLACK, + BRIGHT_BLACK, + DARK_RED, + BRIGHT_RED, + DARK_GREEN, + BRIGHT_GREEN, + DARK_YELLOW, + BRIGHT_YELLOW, + DARK_BLUE, + BRIGHT_BLUE, + DARK_MAGENTA, + BRIGHT_MAGENTA, + DARK_CYAN, + BRIGHT_CYAN, + DARK_WHITE, BRIGHT_WHITE }; + private const string TestText = " gYw "; - static int[] saneBgs = { - DARK_BLACK , - DARK_RED , - DARK_GREEN , - DARK_YELLOW , - DARK_BLUE , - DARK_MAGENTA , - DARK_CYAN , - DARK_WHITE + private static readonly IReadOnlyList FGs = new[] + { + "m", + "1m", + "30m", + "1;30m", + "31m", + "1;31m", + "32m", + "1;32m", + "33m", + "1;33m", + "34m", + "1;34m", + "35m", + "1;35m", + "36m", + "1;36m", + "37m", + "1;37m" }; + private static readonly IReadOnlyList BGs = new[] + { + "m", + "40m", + "41m", + "42m", + "43m", + "44m", + "45m", + "46m", + "47m" + }; + + private static readonly IReadOnlyList saneBgs = new[] + { + DARK_BLACK, + DARK_RED, + DARK_GREEN, + DARK_YELLOW, + DARK_BLUE, + DARK_MAGENTA, + DARK_CYAN, + DARK_WHITE + }; public static void PrintTable() { @@ -66,41 +107,9 @@ namespace ColorTool // Save the current background and foreground colors. ConsoleColor currentBackground = Console.BackgroundColor; ConsoleColor currentForeground = Console.ForegroundColor; - string test = " gYw "; - string[] FGs = { - "m", - "1m", - "30m", - "1;30m", - "31m", - "1;31m", - "32m", - "1;32m", - "33m", - "1;33m", - "34m", - "1;34m", - "35m", - "1;35m", - "36m", - "1;36m", - "37m", - "1;37m" - }; - string[] BGs = { - "m", - "40m", - "41m", - "42m", - "43m", - "44m", - "45m", - "46m", - "47m" - }; Console.Write("\t"); - for (int bg = 0; bg < BGs.Length; bg++) + for (int bg = 0; bg < BGs.Count; bg++) { if (bg > 0) Console.Write(" "); Console.Write(" "); @@ -109,7 +118,7 @@ namespace ColorTool } Console.WriteLine(); - for (int fg = 0; fg < FGs.Length; fg++) + for (int fg = 0; fg < FGs.Count; fg++) { Console.ForegroundColor = currentForeground; Console.BackgroundColor = currentBackground; @@ -119,13 +128,13 @@ namespace ColorTool if (fg == 0) Console.ForegroundColor = currentForeground; else Console.ForegroundColor = colors[outputFgs[fg - 1]]; - for (int bg = 0; bg < BGs.Length; bg++) + for (int bg = 0; bg < BGs.Count; bg++) { if (bg > 0) Console.Write(" "); if (bg == 0) Console.BackgroundColor = currentBackground; else Console.BackgroundColor = colors[saneBgs[bg - 1]]; - Console.Write(test); + Console.Write(TestText); Console.BackgroundColor = currentBackground; } Console.Write("\n"); @@ -140,42 +149,8 @@ namespace ColorTool public static void PrintTableWithVt() { - // Save the current background and foreground colors. - string test = " gYw "; - string[] FGs = { - "m", - "1m", - "30m", - "1;30m", - "31m", - "1;31m", - "32m", - "1;32m", - "33m", - "1;33m", - "34m", - "1;34m", - "35m", - "1;35m", - "36m", - "1;36m", - "37m", - "1;37m" - }; - string[] BGs = { - "m", - "40m", - "41m", - "42m", - "43m", - "44m", - "45m", - "46m", - "47m" - }; - Console.Write("\t"); - for (int bg = 0; bg < BGs.Length; bg++) + for (int bg = 0; bg < BGs.Count; bg++) { if (bg > 0) Console.Write(" "); Console.Write(" "); @@ -184,7 +159,7 @@ namespace ColorTool } Console.WriteLine(); - for (int fg = 0; fg < FGs.Length; fg++) + for (int fg = 0; fg < FGs.Count; fg++) { Console.Write("\x1b[m"); @@ -202,7 +177,7 @@ namespace ColorTool Console.Write("\x1b[" + FGs[fg]); } - for (int bg = 0; bg < BGs.Length; bg++) + for (int bg = 0; bg < BGs.Count; bg++) { if (bg > 0) { @@ -217,7 +192,7 @@ namespace ColorTool Console.Write("\x1b[" + BGs[bg]); } - Console.Write(test); + Console.Write(TestText); Console.Write("\x1b[49m"); } Console.Write("\n"); diff --git a/tools/ColorTool/ColorTool/ColorTool.csproj b/tools/ColorTool/ColorTool/ColorTool.csproj index 5cfeab4d92..729fe7d6c4 100644 --- a/tools/ColorTool/ColorTool/ColorTool.csproj +++ b/tools/ColorTool/ColorTool/ColorTool.csproj @@ -2,7 +2,7 @@ Exe - net46 + net461 false diff --git a/tools/ColorTool/ColorTool/ConsoleAttributes.cs b/tools/ColorTool/ColorTool/ConsoleAttributes.cs index 17b5c7387d..23f28208f8 100644 --- a/tools/ColorTool/ColorTool/ConsoleAttributes.cs +++ b/tools/ColorTool/ColorTool/ConsoleAttributes.cs @@ -5,12 +5,19 @@ namespace ColorTool { - public struct ConsoleAttributes + public readonly struct ConsoleAttributes { - public uint? foreground; - public uint? background; + public ConsoleAttributes(uint? background, uint? foreground, uint? popupBackground, uint? popupForeground) + { + Background = background; + Foreground = foreground; + PopupBackground = popupBackground; + PopupForeground = popupForeground; + } - public uint? popupForeground; - public uint? popupBackground; + public uint? Foreground { get; } + public uint? Background { get; } + public uint? PopupForeground { get; } + public uint? PopupBackground { get; } } } diff --git a/tools/ColorTool/ColorTool/ConsoleTargets/CurrentConsoleTarget.cs b/tools/ColorTool/ColorTool/ConsoleTargets/CurrentConsoleTarget.cs index 97a9c95ba0..f52bab2b7a 100644 --- a/tools/ColorTool/ColorTool/ConsoleTargets/CurrentConsoleTarget.cs +++ b/tools/ColorTool/ColorTool/ConsoleTargets/CurrentConsoleTarget.cs @@ -26,18 +26,18 @@ namespace ColorTool.ConsoleTargets csbiex.srWindow.Bottom++; for (int i = 0; i < 16; i++) { - csbiex.ColorTable[i] = colorScheme.colorTable[i]; + csbiex.ColorTable[i] = colorScheme.ColorTable[i]; } - if (colorScheme.consoleAttributes.background != null && colorScheme.consoleAttributes.foreground != null) + if (colorScheme.ConsoleAttributes.Background != null && colorScheme.ConsoleAttributes.Foreground != null) { - int fgidx = colorScheme.CalculateIndex(colorScheme.consoleAttributes.foreground.Value); - int bgidx = colorScheme.CalculateIndex(colorScheme.consoleAttributes.background.Value); + int fgidx = colorScheme.CalculateIndex(colorScheme.ConsoleAttributes.Foreground.Value); + int bgidx = colorScheme.CalculateIndex(colorScheme.ConsoleAttributes.Background.Value); csbiex.wAttributes = (ushort)(fgidx | (bgidx << 4)); } - if (colorScheme.consoleAttributes.popupBackground != null && colorScheme.consoleAttributes.popupForeground != null) + if (colorScheme.ConsoleAttributes.PopupBackground != null && colorScheme.ConsoleAttributes.PopupForeground != null) { - int fgidx = colorScheme.CalculateIndex(colorScheme.consoleAttributes.popupForeground.Value); - int bgidx = colorScheme.CalculateIndex(colorScheme.consoleAttributes.popupBackground.Value); + int fgidx = colorScheme.CalculateIndex(colorScheme.ConsoleAttributes.PopupForeground.Value); + int bgidx = colorScheme.CalculateIndex(colorScheme.ConsoleAttributes.PopupBackground.Value); csbiex.wPopupAttributes = (ushort)(fgidx | (bgidx << 4)); } SetConsoleScreenBufferInfoEx(hOut, ref csbiex); diff --git a/tools/ColorTool/ColorTool/ConsoleTargets/DefaultConsoleTarget.cs b/tools/ColorTool/ColorTool/ConsoleTargets/DefaultConsoleTarget.cs index bb36487016..6dc34846ab 100644 --- a/tools/ColorTool/ColorTool/ConsoleTargets/DefaultConsoleTarget.cs +++ b/tools/ColorTool/ColorTool/ConsoleTargets/DefaultConsoleTarget.cs @@ -17,10 +17,10 @@ namespace ColorTool.ConsoleTargets { //TODO RegistryKey consoleKey = Registry.CurrentUser.OpenSubKey("Console", true); - for (int i = 0; i < colorScheme.colorTable.Length; i++) + for (int i = 0; i < colorScheme.ColorTable.Length; i++) { string valueName = "ColorTable" + (i < 10 ? "0" : "") + i; - consoleKey.SetValue(valueName, colorScheme.colorTable[i], RegistryValueKind.DWord); + consoleKey.SetValue(valueName, colorScheme.ColorTable[i], RegistryValueKind.DWord); } Console.WriteLine(Resources.WroteToDefaults); } diff --git a/tools/ColorTool/ColorTool/ConsoleTargets/VirtualTerminalConsoleTarget.cs b/tools/ColorTool/ColorTool/ConsoleTargets/VirtualTerminalConsoleTarget.cs index ea660ab167..692fe101c5 100644 --- a/tools/ColorTool/ColorTool/ConsoleTargets/VirtualTerminalConsoleTarget.cs +++ b/tools/ColorTool/ColorTool/ConsoleTargets/VirtualTerminalConsoleTarget.cs @@ -4,6 +4,7 @@ // using System; +using System.Collections.Generic; using System.Drawing; using static ColorTool.ConsoleAPI; @@ -15,7 +16,8 @@ namespace ColorTool.ConsoleTargets class VirtualTerminalConsoleTarget : IConsoleTarget { // Use a Console index in to get a VT index out. - static readonly int[] VT_INDICIES = { + public static readonly IReadOnlyList VT_INDICIES = new[] + { 0, // DARK_BLACK 4, // DARK_BLUE 2, // DARK_GREEN @@ -31,7 +33,7 @@ namespace ColorTool.ConsoleTargets 8+1, // BRIGHT_RED 8+5, // BRIGHT_MAGENTA 8+3, // BRIGHT_YELLOW - 8+7,// BRIGHT_WHITE + 8+7, // BRIGHT_WHITE }; public void ApplyColorScheme(ColorScheme colorScheme, bool quietMode) @@ -46,7 +48,7 @@ namespace ColorTool.ConsoleTargets SetConsoleMode(hOut, requestedMode); } - for (int i = 0; i < colorScheme.colorTable.Length; i++) + for (int i = 0; i < colorScheme.ColorTable.Length; i++) { int vtIndex = VT_INDICIES[i]; Color color = colorScheme[i]; diff --git a/tools/ColorTool/ColorTool/SchemeParsers/IniSchemeParser.cs b/tools/ColorTool/ColorTool/SchemeParsers/IniSchemeParser.cs index ee88001415..8e8f263c41 100644 --- a/tools/ColorTool/ColorTool/SchemeParsers/IniSchemeParser.cs +++ b/tools/ColorTool/ColorTool/SchemeParsers/IniSchemeParser.cs @@ -19,7 +19,8 @@ namespace ColorTool.SchemeParsers private static extern int GetPrivateProfileString(string section, string key, string def, StringBuilder retVal, int size, string filePath); // These are in Windows Color table order - BRG, not RGB. - public static string[] COLOR_NAMES = { + internal static readonly IReadOnlyList COLOR_NAMES = new[] + { "DARK_BLACK", "DARK_BLUE", "DARK_GREEN", @@ -38,44 +39,7 @@ namespace ColorTool.SchemeParsers "BRIGHT_WHITE" }; - public string Name => "INI File Parser"; - - static uint ParseHex(string arg) - { - System.Drawing.Color col = System.Drawing.ColorTranslator.FromHtml(arg); - return RGB(col.R, col.G, col.B); - } - - static uint ParseRgb(string arg) - { - int[] components = { 0, 0, 0 }; - string[] args = arg.Split(','); - if (args.Length != components.Length) throw new Exception("Invalid color format \"" + arg + "\""); - if (args.Length != 3) throw new Exception("Invalid color format \"" + arg + "\""); - for (int i = 0; i < args.Length; i++) - { - components[i] = Int32.Parse(args[i]); - } - - return RGB(components[0], components[1], components[2]); - } - - static uint ParseColor(string arg) - { - if (arg[0] == '#') - { - return ParseHex(arg.Substring(1)); - } - else - { - return ParseRgb(arg); - } - } - - static string FindIniScheme(string schemeName) - { - return SchemeManager.GetSearchPaths(schemeName, ".ini").FirstOrDefault(File.Exists); - } + public string Name { get; } = "INI File Parser"; public ColorScheme ParseScheme(string schemeName, bool reportErrors = false) { @@ -154,8 +118,8 @@ namespace ColorTool.SchemeParsers if (colorTable != null) { - var consoleAttributes = new ConsoleAttributes { background = backgroundColor, foreground = foregroundColor, popupBackground = popupBackgroundColor, popupForeground = popupForegroundColor }; - return new ColorScheme { colorTable = colorTable, consoleAttributes = consoleAttributes }; + var consoleAttributes = new ConsoleAttributes(backgroundColor, foregroundColor, popupBackgroundColor, popupForegroundColor); + return new ColorScheme(colorTable, consoleAttributes); } else { @@ -183,5 +147,42 @@ namespace ColorTool.SchemeParsers return true; } } + + private static uint ParseHex(string arg) + { + System.Drawing.Color col = System.Drawing.ColorTranslator.FromHtml(arg); + return RGB(col.R, col.G, col.B); + } + + private static uint ParseRgb(string arg) + { + int[] components = { 0, 0, 0 }; + string[] args = arg.Split(','); + if (args.Length != components.Length) throw new Exception("Invalid color format \"" + arg + "\""); + if (args.Length != 3) throw new Exception("Invalid color format \"" + arg + "\""); + for (int i = 0; i < args.Length; i++) + { + components[i] = Int32.Parse(args[i]); + } + + return RGB(components[0], components[1], components[2]); + } + + private static uint ParseColor(string arg) + { + if (arg[0] == '#') + { + return ParseHex(arg.Substring(1)); + } + else + { + return ParseRgb(arg); + } + } + + private static string FindIniScheme(string schemeName) + { + return SchemeManager.GetSearchPaths(schemeName, ".ini").FirstOrDefault(File.Exists); + } } } diff --git a/tools/ColorTool/ColorTool/SchemeParsers/JsonParser.cs b/tools/ColorTool/ColorTool/SchemeParsers/JsonParser.cs index abb1f99333..5940875dc4 100644 --- a/tools/ColorTool/ColorTool/SchemeParsers/JsonParser.cs +++ b/tools/ColorTool/ColorTool/SchemeParsers/JsonParser.cs @@ -15,7 +15,8 @@ namespace ColorTool.SchemeParsers { class JsonParser : ISchemeParser { - static string[] CONCFG_COLOR_NAMES = { + private static IReadOnlyList CONCFG_COLOR_NAMES = new[] + { "black", // DARK_BLACK "dark_blue", // DARK_BLUE "dark_green", // DARK_GREEN @@ -34,34 +35,7 @@ namespace ColorTool.SchemeParsers "white" // BRIGHT_WHITE }; - public string Name => "concfg Parser"; - - static uint ParseColor(string arg) - { - System.Drawing.Color col = System.Drawing.ColorTranslator.FromHtml(arg); - return RGB(col.R, col.G, col.B); - } - - static XmlDocument loadJsonFile(string schemeName) - { - XmlDocument xmlDoc = new XmlDocument(); - foreach (string path in SchemeManager.GetSearchPaths(schemeName, ".json") - .Where(File.Exists)) - { - try - { - var data = File.ReadAllBytes(path); - var reader = JsonReaderWriterFactory.CreateJsonReader(data, System.Xml.XmlDictionaryReaderQuotas.Max); - xmlDoc.Load(reader); - return xmlDoc; - } - catch (XmlException /*e*/) { /* failed to parse */ } - catch (IOException /*e*/) { /* failed to find */ } - catch (UnauthorizedAccessException /*e*/) { /* unauthorized */ } - } - - return null; - } + public string Name { get; } = "concfg Parser"; public ColorScheme ParseScheme(string schemeName, bool reportErrors = false) { @@ -119,18 +93,45 @@ namespace ColorTool.SchemeParsers } } - var consoleAttributes = new ConsoleAttributes { background = screenBackground, foreground = screenForeground, popupBackground = popupBackground, popupForeground = popupForeground }; - return new ColorScheme { colorTable = colorTable, consoleAttributes = consoleAttributes }; + var consoleAttributes = new ConsoleAttributes(screenBackground, screenForeground, popupBackground, popupForeground); + return new ColorScheme(colorTable, consoleAttributes); } catch (Exception /*e*/) { if (reportErrors) { - Console.WriteLine("failes to load json scheme"); + Console.WriteLine("failed to load json scheme"); } return null; } } + + private static uint ParseColor(string arg) + { + System.Drawing.Color col = System.Drawing.ColorTranslator.FromHtml(arg); + return RGB(col.R, col.G, col.B); + } + + private static XmlDocument loadJsonFile(string schemeName) + { + XmlDocument xmlDoc = new XmlDocument(); + foreach (string path in SchemeManager.GetSearchPaths(schemeName, ".json") + .Where(File.Exists)) + { + try + { + var data = File.ReadAllBytes(path); + var reader = JsonReaderWriterFactory.CreateJsonReader(data, System.Xml.XmlDictionaryReaderQuotas.Max); + xmlDoc.Load(reader); + return xmlDoc; + } + catch (XmlException /*e*/) { /* failed to parse */ } + catch (IOException /*e*/) { /* failed to find */ } + catch (UnauthorizedAccessException /*e*/) { /* unauthorized */ } + } + + return null; + } } } diff --git a/tools/ColorTool/ColorTool/SchemeParsers/XmlSchemeParser.cs b/tools/ColorTool/ColorTool/SchemeParsers/XmlSchemeParser.cs index 412f5739d8..aaa1e01d63 100644 --- a/tools/ColorTool/ColorTool/SchemeParsers/XmlSchemeParser.cs +++ b/tools/ColorTool/ColorTool/SchemeParsers/XmlSchemeParser.cs @@ -4,6 +4,7 @@ // using System; +using System.Collections.Generic; using System.Globalization; using System.IO; using System.Linq; @@ -15,8 +16,9 @@ namespace ColorTool.SchemeParsers class XmlSchemeParser : ISchemeParser { // In Windows Color Table order - static string[] PLIST_COLOR_NAMES = { - "Ansi 0 Color", // DARK_BLACK + private static readonly string[] PLIST_COLOR_NAMES = + { + "Ansi 0 Color", // DARK_BLACK "Ansi 4 Color", // DARK_BLUE "Ansi 2 Color", // DARK_GREEN "Ansi 6 Color", // DARK_CYAN @@ -31,17 +33,57 @@ namespace ColorTool.SchemeParsers "Ansi 9 Color", // BRIGHT_RED "Ansi 13 Color", // BRIGHT_MAGENTA "Ansi 11 Color", // BRIGHT_YELLOW - "Ansi 15 Color" // BRIGHT_WHITE + "Ansi 15 Color" // BRIGHT_WHITE }; - static string FG_KEY = "Foreground Color"; - static string BG_KEY = "Background Color"; - static string RED_KEY = "Red Component"; - static string GREEN_KEY = "Green Component"; - static string BLUE_KEY = "Blue Component"; + private const string FG_KEY = "Foreground Color"; + private const string BG_KEY = "Background Color"; + private const string RED_KEY = "Red Component"; + private const string GREEN_KEY = "Green Component"; + private const string BLUE_KEY = "Blue Component"; - public string Name => "iTerm Parser"; + public string Name { get; } = "iTerm Parser"; - static bool parseRgbFromXml(XmlNode components, ref uint rgb) + public ColorScheme ParseScheme(string schemeName, bool reportErrors = false) + { + XmlDocument xmlDoc = LoadXmlScheme(schemeName); // Create an XML document object + if (xmlDoc == null) return null; + XmlNode root = xmlDoc.GetElementsByTagName("dict")[0]; + XmlNodeList children = root.ChildNodes; + + uint[] colorTable = new uint[COLOR_TABLE_SIZE]; + uint? fgColor = null, bgColor = null; + int colorsFound = 0; + bool success = false; + foreach (var tableEntry in children.OfType().Where(_ => _.Name == "key")) + { + uint rgb = 0; + int index = -1; + XmlNode components = tableEntry.NextSibling; + success = ParseRgbFromXml(components, ref rgb); + if (!success) { break; } + else if (tableEntry.InnerText == FG_KEY) { fgColor = rgb; } + else if (tableEntry.InnerText == BG_KEY) { bgColor = rgb; } + else if (-1 != (index = Array.IndexOf(PLIST_COLOR_NAMES, tableEntry.InnerText))) + { colorTable[index] = rgb; colorsFound++; } + } + if (colorsFound < COLOR_TABLE_SIZE) + { + if (reportErrors) + { + Console.WriteLine(Resources.InvalidNumberOfColors); + } + success = false; + } + if (!success) + { + return null; + } + + var consoleAttributes = new ConsoleAttributes(bgColor, fgColor, null, null); + return new ColorScheme(colorTable, consoleAttributes); + } + + private static bool ParseRgbFromXml(XmlNode components, ref uint rgb) { int r = -1; int g = -1; @@ -78,8 +120,7 @@ namespace ColorTool.SchemeParsers return true; } - - static XmlDocument loadXmlScheme(string schemeName) + private static XmlDocument LoadXmlScheme(string schemeName) { XmlDocument xmlDoc = new XmlDocument(); // Create an XML document object foreach (string path in SchemeManager.GetSearchPaths(schemeName, ".itermcolors") @@ -97,46 +138,5 @@ namespace ColorTool.SchemeParsers return null; } - - - public ColorScheme ParseScheme(string schemeName, bool reportErrors = false) - { - XmlDocument xmlDoc = loadXmlScheme(schemeName); // Create an XML document object - if (xmlDoc == null) return null; - XmlNode root = xmlDoc.GetElementsByTagName("dict")[0]; - XmlNodeList children = root.ChildNodes; - - uint[] colorTable = new uint[COLOR_TABLE_SIZE]; - uint? fgColor = null, bgColor = null; - int colorsFound = 0; - bool success = false; - foreach (var tableEntry in children.OfType().Where(_ => _.Name == "key")) - { - uint rgb = 0; - int index = -1; - XmlNode components = tableEntry.NextSibling; - success = parseRgbFromXml(components, ref rgb); - if (!success) { break; } - else if (tableEntry.InnerText == FG_KEY) { fgColor = rgb; } - else if (tableEntry.InnerText == BG_KEY) { bgColor = rgb; } - else if (-1 != (index = Array.IndexOf(PLIST_COLOR_NAMES, tableEntry.InnerText))) - { colorTable[index] = rgb; colorsFound++; } - } - if (colorsFound < COLOR_TABLE_SIZE) - { - if (reportErrors) - { - Console.WriteLine(Resources.InvalidNumberOfColors); - } - success = false; - } - if (!success) - { - return null; - } - - var consoleAttributes = new ConsoleAttributes { foreground = fgColor, background = bgColor }; - return new ColorScheme { colorTable = colorTable, consoleAttributes = consoleAttributes }; - } } } From b61cb830c3a2110037c645fbb57f7345d703b86b Mon Sep 17 00:00:00 2001 From: Will Fuqua Date: Tue, 23 Apr 2019 22:04:18 +0700 Subject: [PATCH 80/89] allow scheme parsers to opt out of attempting to parse a file This fixes the issue where the INI file parser can throw errors because it's attempting to parse an `.itermcolors` (xml) file. --- tools/ColorTool/ColorTool/SchemeManager.cs | 13 ++++--------- .../ColorTool/SchemeParsers/ISchemeParser.cs | 2 +- .../ColorTool/SchemeParsers/IniSchemeParser.cs | 7 ++++++- .../ColorTool/ColorTool/SchemeParsers/JsonParser.cs | 10 +++++++--- .../ColorTool/SchemeParsers/XmlSchemeParser.cs | 6 +++++- 5 files changed, 23 insertions(+), 15 deletions(-) diff --git a/tools/ColorTool/ColorTool/SchemeManager.cs b/tools/ColorTool/ColorTool/SchemeManager.cs index 09b3ee341d..f00dcdd688 100644 --- a/tools/ColorTool/ColorTool/SchemeManager.cs +++ b/tools/ColorTool/ColorTool/SchemeManager.cs @@ -91,15 +91,10 @@ namespace ColorTool public static ColorScheme GetScheme(string schemeName, bool reportErrors = false) { - foreach (var parser in GetParsers()) - { - ColorScheme scheme = parser.ParseScheme(schemeName, reportErrors); - if (scheme != null) - { - return scheme; - } - } - return null; + return GetParsers() + .Where(parser => parser.CanParse(schemeName)) + .Select(parser => parser.ParseScheme(schemeName, reportErrors)) + .FirstOrDefault(); } public static IEnumerable GetParsers() diff --git a/tools/ColorTool/ColorTool/SchemeParsers/ISchemeParser.cs b/tools/ColorTool/ColorTool/SchemeParsers/ISchemeParser.cs index c90c0bdb78..cb4ebce6af 100644 --- a/tools/ColorTool/ColorTool/SchemeParsers/ISchemeParser.cs +++ b/tools/ColorTool/ColorTool/SchemeParsers/ISchemeParser.cs @@ -8,7 +8,7 @@ namespace ColorTool.SchemeParsers interface ISchemeParser { string Name { get; } - + bool CanParse(string schemeName); ColorScheme ParseScheme(string schemeName, bool reportErrors = false); } } diff --git a/tools/ColorTool/ColorTool/SchemeParsers/IniSchemeParser.cs b/tools/ColorTool/ColorTool/SchemeParsers/IniSchemeParser.cs index 8e8f263c41..bb4cbd1fc4 100644 --- a/tools/ColorTool/ColorTool/SchemeParsers/IniSchemeParser.cs +++ b/tools/ColorTool/ColorTool/SchemeParsers/IniSchemeParser.cs @@ -18,6 +18,8 @@ namespace ColorTool.SchemeParsers [DllImport("kernel32")] private static extern int GetPrivateProfileString(string section, string key, string def, StringBuilder retVal, int size, string filePath); + private const string FileExtension = ".ini"; + // These are in Windows Color table order - BRG, not RGB. internal static readonly IReadOnlyList COLOR_NAMES = new[] { @@ -41,6 +43,9 @@ namespace ColorTool.SchemeParsers public string Name { get; } = "INI File Parser"; + public bool CanParse(string schemeName) => + string.Equals(Path.GetExtension(schemeName), FileExtension, StringComparison.OrdinalIgnoreCase); + public ColorScheme ParseScheme(string schemeName, bool reportErrors = false) { bool success = true; @@ -182,7 +187,7 @@ namespace ColorTool.SchemeParsers private static string FindIniScheme(string schemeName) { - return SchemeManager.GetSearchPaths(schemeName, ".ini").FirstOrDefault(File.Exists); + return SchemeManager.GetSearchPaths(schemeName, FileExtension).FirstOrDefault(File.Exists); } } } diff --git a/tools/ColorTool/ColorTool/SchemeParsers/JsonParser.cs b/tools/ColorTool/ColorTool/SchemeParsers/JsonParser.cs index 5940875dc4..e3e817d0be 100644 --- a/tools/ColorTool/ColorTool/SchemeParsers/JsonParser.cs +++ b/tools/ColorTool/ColorTool/SchemeParsers/JsonParser.cs @@ -15,6 +15,7 @@ namespace ColorTool.SchemeParsers { class JsonParser : ISchemeParser { + private const string FileExtension = ".json"; private static IReadOnlyList CONCFG_COLOR_NAMES = new[] { "black", // DARK_BLACK @@ -37,9 +38,12 @@ namespace ColorTool.SchemeParsers public string Name { get; } = "concfg Parser"; + public bool CanParse(string schemeName) => + string.Equals(Path.GetExtension(schemeName), FileExtension, StringComparison.OrdinalIgnoreCase); + public ColorScheme ParseScheme(string schemeName, bool reportErrors = false) { - XmlDocument xmlDoc = loadJsonFile(schemeName); + XmlDocument xmlDoc = LoadJsonFile(schemeName); if (xmlDoc == null) return null; try @@ -113,10 +117,10 @@ namespace ColorTool.SchemeParsers return RGB(col.R, col.G, col.B); } - private static XmlDocument loadJsonFile(string schemeName) + private static XmlDocument LoadJsonFile(string schemeName) { XmlDocument xmlDoc = new XmlDocument(); - foreach (string path in SchemeManager.GetSearchPaths(schemeName, ".json") + foreach (string path in SchemeManager.GetSearchPaths(schemeName, FileExtension) .Where(File.Exists)) { try diff --git a/tools/ColorTool/ColorTool/SchemeParsers/XmlSchemeParser.cs b/tools/ColorTool/ColorTool/SchemeParsers/XmlSchemeParser.cs index aaa1e01d63..39177a12c0 100644 --- a/tools/ColorTool/ColorTool/SchemeParsers/XmlSchemeParser.cs +++ b/tools/ColorTool/ColorTool/SchemeParsers/XmlSchemeParser.cs @@ -40,9 +40,13 @@ namespace ColorTool.SchemeParsers private const string RED_KEY = "Red Component"; private const string GREEN_KEY = "Green Component"; private const string BLUE_KEY = "Blue Component"; + private const string FileExtension = ".itermcolors"; public string Name { get; } = "iTerm Parser"; + public bool CanParse(string schemeName) => + string.Equals(Path.GetExtension(schemeName), FileExtension, StringComparison.OrdinalIgnoreCase); + public ColorScheme ParseScheme(string schemeName, bool reportErrors = false) { XmlDocument xmlDoc = LoadXmlScheme(schemeName); // Create an XML document object @@ -123,7 +127,7 @@ namespace ColorTool.SchemeParsers private static XmlDocument LoadXmlScheme(string schemeName) { XmlDocument xmlDoc = new XmlDocument(); // Create an XML document object - foreach (string path in SchemeManager.GetSearchPaths(schemeName, ".itermcolors") + foreach (string path in SchemeManager.GetSearchPaths(schemeName, FileExtension) .Where(File.Exists)) { try From 12fff3126be6c41bc6a1b124c4a3085c5eb01925 Mon Sep 17 00:00:00 2001 From: Will Fuqua Date: Tue, 23 Apr 2019 22:42:32 +0700 Subject: [PATCH 81/89] add support for writing foreground / background indices to registry This functionality was implemented for the "current console" but was never implemented for writing to the registry, which affects all future consoles. --- tools/ColorTool/ColorTool/ColorScheme.cs | 27 ++++++++++++++++--- .../ConsoleTargets/CurrentConsoleTarget.cs | 12 +++------ .../ConsoleTargets/DefaultConsoleTarget.cs | 10 ++++++- tools/ColorTool/ColorTool/Program.cs | 19 ++++++++++--- 4 files changed, 53 insertions(+), 15 deletions(-) diff --git a/tools/ColorTool/ColorTool/ColorScheme.cs b/tools/ColorTool/ColorTool/ColorScheme.cs index 17fcb15796..302e0459e3 100644 --- a/tools/ColorTool/ColorTool/ColorScheme.cs +++ b/tools/ColorTool/ColorTool/ColorScheme.cs @@ -23,6 +23,18 @@ namespace ColorTool public uint[] ColorTable { get; } public ConsoleAttributes ConsoleAttributes { get; } + public ushort? ScreenColorAttributes => + CalculateBackgroundForegroundAttributes( + this.ConsoleAttributes.Background, + this.ConsoleAttributes.Foreground + ); + + public ushort? PopupColorAttributes => + CalculateBackgroundForegroundAttributes( + this.ConsoleAttributes.PopupBackground, + this.ConsoleAttributes.PopupForeground + ); + public Color this[int index] => UIntToColor(ColorTable[index]); private static Color UIntToColor(uint color) @@ -33,6 +45,18 @@ namespace ColorTool return Color.FromArgb(r, g, b); } + private ushort? CalculateBackgroundForegroundAttributes(uint? background, uint? foreground) + { + if(!(background.HasValue && foreground.HasValue)) + { + return null; + } + int fgidx = this.CalculateIndex(foreground.Value); + int bgidx = this.CalculateIndex(background.Value); + var attributes = (ushort)(fgidx | (bgidx << 4)); + return attributes; + } + public int CalculateIndex(uint value) => ColorTable.Select((color, idx) => Tuple.Create(color, idx)) .OrderBy(Difference(value)) @@ -55,9 +79,6 @@ namespace ColorTool return Math.Sqrt(dist[0] * (2 + rbar / 256.0) + dist[1] * 4 + dist[2] * (2 + (255 - rbar) / 256.0)); } - private static double Distance(uint[] c1c, uint[] c2c) - => Math.Sqrt(c1c.Zip(c2c, (a, b) => Math.Pow((int)a - (int)b, 2)).Sum()); - internal static uint[] RGB(uint c) => new[] { c & 0xFF, (c >> 8) & 0xFF, (c >> 16) & 0xFF }; internal static uint[] HSV(uint c) diff --git a/tools/ColorTool/ColorTool/ConsoleTargets/CurrentConsoleTarget.cs b/tools/ColorTool/ColorTool/ConsoleTargets/CurrentConsoleTarget.cs index f52bab2b7a..f116d75cd1 100644 --- a/tools/ColorTool/ColorTool/ConsoleTargets/CurrentConsoleTarget.cs +++ b/tools/ColorTool/ColorTool/ConsoleTargets/CurrentConsoleTarget.cs @@ -28,17 +28,13 @@ namespace ColorTool.ConsoleTargets { csbiex.ColorTable[i] = colorScheme.ColorTable[i]; } - if (colorScheme.ConsoleAttributes.Background != null && colorScheme.ConsoleAttributes.Foreground != null) + if(colorScheme.ScreenColorAttributes is ushort wAttrs) { - int fgidx = colorScheme.CalculateIndex(colorScheme.ConsoleAttributes.Foreground.Value); - int bgidx = colorScheme.CalculateIndex(colorScheme.ConsoleAttributes.Background.Value); - csbiex.wAttributes = (ushort)(fgidx | (bgidx << 4)); + csbiex.wAttributes = wAttrs; } - if (colorScheme.ConsoleAttributes.PopupBackground != null && colorScheme.ConsoleAttributes.PopupForeground != null) + if(colorScheme.PopupColorAttributes is ushort wPopupAttrs) { - int fgidx = colorScheme.CalculateIndex(colorScheme.ConsoleAttributes.PopupForeground.Value); - int bgidx = colorScheme.CalculateIndex(colorScheme.ConsoleAttributes.PopupBackground.Value); - csbiex.wPopupAttributes = (ushort)(fgidx | (bgidx << 4)); + csbiex.wPopupAttributes = wPopupAttrs; } SetConsoleScreenBufferInfoEx(hOut, ref csbiex); diff --git a/tools/ColorTool/ColorTool/ConsoleTargets/DefaultConsoleTarget.cs b/tools/ColorTool/ColorTool/ConsoleTargets/DefaultConsoleTarget.cs index 6dc34846ab..1948078119 100644 --- a/tools/ColorTool/ColorTool/ConsoleTargets/DefaultConsoleTarget.cs +++ b/tools/ColorTool/ColorTool/ConsoleTargets/DefaultConsoleTarget.cs @@ -15,13 +15,21 @@ namespace ColorTool.ConsoleTargets { public void ApplyColorScheme(ColorScheme colorScheme, bool quietMode) { - //TODO RegistryKey consoleKey = Registry.CurrentUser.OpenSubKey("Console", true); for (int i = 0; i < colorScheme.ColorTable.Length; i++) { string valueName = "ColorTable" + (i < 10 ? "0" : "") + i; consoleKey.SetValue(valueName, colorScheme.ColorTable[i], RegistryValueKind.DWord); } + if(colorScheme.ScreenColorAttributes is ushort screenColors) + { + consoleKey.SetValue("ScreenColors", screenColors, RegistryValueKind.DWord); + } + if(colorScheme.PopupColorAttributes is ushort popupColors) + { + consoleKey.SetValue("PopupColors", popupColors, RegistryValueKind.DWord); + } + Console.WriteLine(Resources.WroteToDefaults); } } diff --git a/tools/ColorTool/ColorTool/Program.cs b/tools/ColorTool/ColorTool/Program.cs index 36fe40fe3c..75939618b3 100644 --- a/tools/ColorTool/ColorTool/Program.cs +++ b/tools/ColorTool/ColorTool/Program.cs @@ -6,6 +6,7 @@ using ColorTool.ConsoleTargets; using ColorTool.SchemeWriters; using System; +using System.Collections.Generic; using System.Linq; namespace ColorTool @@ -117,19 +118,31 @@ namespace ColorTool return; } + foreach (var target in GetConsoleTargets()) + { + target.ApplyColorScheme(colorScheme, quietMode); + } + } + + /// + /// Returns an enumerable of consoles that we want to apply the colorscheme to. + /// The contents of this enumerable depends on the user's provided command line flags. + /// + public static IEnumerable GetConsoleTargets() + { if (setDefaults) { - new DefaultConsoleTarget().ApplyColorScheme(colorScheme, quietMode); + yield return new DefaultConsoleTarget(); } if (setProperties) { if (setUnixStyle) { - new VirtualTerminalConsoleTarget().ApplyColorScheme(colorScheme, quietMode); + yield return new VirtualTerminalConsoleTarget(); } else { - new CurrentConsoleTarget().ApplyColorScheme(colorScheme, quietMode); + yield return new CurrentConsoleTarget(); } } } From 2dc178b852b1ed7fecea1ce9132b44ec3a44e28b Mon Sep 17 00:00:00 2001 From: oising Date: Tue, 23 Apr 2019 17:38:35 -0400 Subject: [PATCH 82/89] address issues and suggestions in PR review --- ...ularQueue.cs => ConcurrentBoundedQueue.cs} | 11 ++- tools/ReadConsoleInputStream/NativeMethods.cs | 11 ++- tools/ReadConsoleInputStream/Program.cs | 24 ++--- .../ReadConsoleInputStream.cs | 94 ++++++++++--------- 4 files changed, 75 insertions(+), 65 deletions(-) rename tools/ReadConsoleInputStream/{ConcurrentCircularQueue.cs => ConcurrentBoundedQueue.cs} (75%) diff --git a/tools/ReadConsoleInputStream/ConcurrentCircularQueue.cs b/tools/ReadConsoleInputStream/ConcurrentBoundedQueue.cs similarity index 75% rename from tools/ReadConsoleInputStream/ConcurrentCircularQueue.cs rename to tools/ReadConsoleInputStream/ConcurrentBoundedQueue.cs index db14019f37..67c32a51ca 100644 --- a/tools/ReadConsoleInputStream/ConcurrentCircularQueue.cs +++ b/tools/ReadConsoleInputStream/ConcurrentBoundedQueue.cs @@ -2,15 +2,15 @@ using System.Collections.Concurrent; using System.Collections.Generic; -namespace Nivot.Terminal +namespace Samples.Terminal { /// - /// Implements a circular buffer. + /// Implements a bounded queue that won't block on overflow; instead the oldest item is discarded. /// /// - public class ConcurrentCircularQueue : ConcurrentQueue + public class ConcurrentBoundedQueue : ConcurrentQueue { - public ConcurrentCircularQueue(int capacity) + public ConcurrentBoundedQueue(int capacity) { Capacity = GetAlignedCapacity(capacity); } @@ -20,7 +20,7 @@ namespace Nivot.Terminal /// /// /// - public ConcurrentCircularQueue(IEnumerable collection, int capacity) : base(collection) + public ConcurrentBoundedQueue(IEnumerable collection, int capacity) : base(collection) { Capacity = GetAlignedCapacity(capacity); } @@ -40,6 +40,7 @@ namespace Nivot.Terminal public new void Enqueue(T item) { + // if we're about to overflow, dump oldest item if (Count >= Capacity) { lock (this) diff --git a/tools/ReadConsoleInputStream/NativeMethods.cs b/tools/ReadConsoleInputStream/NativeMethods.cs index f08640f02e..3cae186345 100644 --- a/tools/ReadConsoleInputStream/NativeMethods.cs +++ b/tools/ReadConsoleInputStream/NativeMethods.cs @@ -1,7 +1,8 @@ using System; +using System.Diagnostics; using System.Runtime.InteropServices; -namespace Nivot.Terminal +namespace Samples.Terminal { internal static class NativeMethods { @@ -9,7 +10,10 @@ namespace Nivot.Terminal { // Don't convert it if it is already an HRESULT if ((0xFFFF0000 & errorCode) != 0) + { + Debug.Assert(false, "errorCode is already HRESULT"); return errorCode; + } return unchecked(((int)0x80070000) | errorCode); } @@ -18,5 +22,10 @@ namespace Nivot.Terminal { return Marshal.GetExceptionForHR(MakeHRFromErrorCode(errorCode)); } + + internal static Exception GetExceptionForLastWin32Error() + { + return GetExceptionForWin32Error(Marshal.GetLastWin32Error()); + } } } \ No newline at end of file diff --git a/tools/ReadConsoleInputStream/Program.cs b/tools/ReadConsoleInputStream/Program.cs index d4f97f3eef..ef1192d27a 100644 --- a/tools/ReadConsoleInputStream/Program.cs +++ b/tools/ReadConsoleInputStream/Program.cs @@ -39,14 +39,18 @@ using System.Threading.Tasks; using Pipelines.Sockets.Unofficial; using Vanara.PInvoke; -namespace Nivot.Terminal +namespace Samples.Terminal { internal class Program { private static async Task Main(string[] args) { // run for 90 seconds - const int timeout = 90000; + var timeout = TimeSpan.FromSeconds(90); + + // in reality this will likely never be reached, but it is useful to guard against + // conditions where the queue isn't drained, or not drained fast enough. + const int maxNonKeyEventRetention = 128; var source = new CancellationTokenSource(timeout); var token = source.Token; @@ -55,25 +59,17 @@ namespace Nivot.Terminal if (!Kernel32.GetConsoleMode(handle, out Kernel32.CONSOLE_INPUT_MODE mode)) throw NativeMethods.GetExceptionForWin32Error(Marshal.GetLastWin32Error()); - // enable VT sequences so cursor movement etc is encapsulated in the stream mode |= Kernel32.CONSOLE_INPUT_MODE.ENABLE_WINDOW_INPUT; mode |= Kernel32.CONSOLE_INPUT_MODE.ENABLE_VIRTUAL_TERMINAL_INPUT; mode &= ~Kernel32.CONSOLE_INPUT_MODE.ENABLE_ECHO_INPUT; mode &= ~Kernel32.CONSOLE_INPUT_MODE.ENABLE_LINE_INPUT; if (!Kernel32.SetConsoleMode(handle, mode)) - throw NativeMethods.GetExceptionForWin32Error(Marshal.GetLastWin32Error()); + throw NativeMethods.GetExceptionForLastWin32Error(); - // set utf-8 cp - if (!Kernel32.SetConsoleCP(65001)) - throw NativeMethods.GetExceptionForWin32Error(Marshal.GetLastWin32Error()); - - if (!Kernel32.SetConsoleOutputCP(65001)) - throw NativeMethods.GetExceptionForWin32Error(Marshal.GetLastWin32Error()); - - // base our provider/consumer on a circular buffer to keep memory usage under control + // base our provider/consumer on a bounded queue to keep memory usage under control var events = new BlockingCollection( - new ConcurrentCircularQueue(256)); + new ConcurrentBoundedQueue(maxNonKeyEventRetention)); // Task that will consume non-key events asynchronously var consumeEvents = Task.Run(() => @@ -124,7 +120,7 @@ namespace Nivot.Terminal while (sequence.TryGet(ref segment, out var mem)) { - // decode back from unicode (2 bytes per char) + // decode back from unicode var datum = Encoding.Unicode.GetString(mem.Span); Console.Write(datum); } diff --git a/tools/ReadConsoleInputStream/ReadConsoleInputStream.cs b/tools/ReadConsoleInputStream/ReadConsoleInputStream.cs index 64a99f7377..0d2526766b 100644 --- a/tools/ReadConsoleInputStream/ReadConsoleInputStream.cs +++ b/tools/ReadConsoleInputStream/ReadConsoleInputStream.cs @@ -5,7 +5,7 @@ using System.IO; using Vanara.PInvoke; -namespace Nivot.Terminal +namespace Samples.Terminal { /// /// Provides a Stream-oriented view over the console's input buffer key events @@ -93,61 +93,65 @@ namespace Nivot.Terminal var records = new Kernel32.INPUT_RECORD[BufferSize]; // begin input loop - waitForInput: - - var readSuccess = Kernel32.ReadConsoleInput(_handle, records, 256, out var recordsRead); - Debug.WriteLine("Read {0} input record(s)", recordsRead); - - if (readSuccess && recordsRead > 0) + do { - for (var index = 0; index < recordsRead; index++) + var readSuccess = Kernel32.ReadConsoleInput(_handle, records, BufferSize, out var recordsRead); + Debug.WriteLine("Read {0} input record(s)", recordsRead); + + // some of the arithmetic here is deliberately more explicit than it needs to be + // in order to show how 16-bit unicode WCHARs are packed into the buffer. The console + // subsystem is one of the last bastions of UCS-2, so until UTF-16 is fully adopted + // the two-byte character assumptions below will hold. + if (readSuccess && recordsRead > 0) { - var record = records[index]; - - if (record.EventType == Kernel32.EVENT_TYPE.KEY_EVENT) + for (var index = 0; index < recordsRead; index++) { - // skip key up events - if not, every key will be duped in the stream - if (record.Event.KeyEvent.bKeyDown == false) continue; + var record = records[index]; - // pack ucs-2/utf-16le/unicode chars into position in our byte[] buffer. - var glyph = (ushort) record.Event.KeyEvent.uChar; - - var lsb = (byte) (glyph & 0xFFu); - var msb = (byte) ((glyph >> 8) & 0xFFu); - - // ensure we accommodate key repeat counts - for (var n = 0; n < record.Event.KeyEvent.wRepeatCount; n++) + if (record.EventType == Kernel32.EVENT_TYPE.KEY_EVENT) { - buffer[offset + charsRead * BytesPerWChar] = lsb; - buffer[offset + charsRead * BytesPerWChar + 1] = msb; + // skip key up events - if not, every key will be duped in the stream + if (record.Event.KeyEvent.bKeyDown == false) continue; - charsRead++; - } - } - else - { - // ignore focus events (not doing so makes debugging absolutely hilarious) - if (record.EventType != Kernel32.EVENT_TYPE.FOCUS_EVENT) - { - // I assume success adding records - this is not so critical - // if it is critical to you, loop on this with a miniscule delay - _nonKeyEvents.TryAdd(record); + // pack ucs-2/utf-16le/unicode chars into position in our byte[] buffer. + var glyph = (ushort) record.Event.KeyEvent.uChar; + + var lsb = (byte) (glyph & 0xFFu); + var msb = (byte) ((glyph >> 8) & 0xFFu); + + // ensure we accommodate key repeat counts + for (var n = 0; n < record.Event.KeyEvent.wRepeatCount; n++) + { + buffer[offset + charsRead * BytesPerWChar] = lsb; + buffer[offset + charsRead * BytesPerWChar + 1] = msb; + + charsRead++; + } + } + else + { + // ignore focus events; not doing so makes debugging absolutely hilarious + // when breakpoints repeatedly cause focus events to occur as your view toggles + // between IDE and console. + if (record.EventType != Kernel32.EVENT_TYPE.FOCUS_EVENT) + { + // I assume success adding records - this is not so critical + // if it is critical to you, loop on this with a miniscule delay + _nonKeyEvents.TryAdd(record); + } } } + bytesRead = charsRead * BytesPerWChar; + } + else + { + Debug.Assert(bytesRead == 0, "bytesRead == 0"); } - bytesRead = charsRead * BytesPerWChar; - - // we should continue to block if no chars read (KEY_EVENT) - // even though non-key events were dispatched - if (bytesRead == 0) goto waitForInput; - } - else - { - Debug.Assert(bytesRead == 0, "bytesRead == 0"); - } - + } while (bytesRead == 0); + Debug.WriteLine("Read {0} character(s)", charsRead); + ret = Win32Error.ERROR_SUCCESS; } From 5bd3f887b1b14290fba892685cb42f3e2f50f950 Mon Sep 17 00:00:00 2001 From: oising Date: Tue, 23 Apr 2019 17:40:10 -0400 Subject: [PATCH 83/89] remove empty xmldoc --- tools/ReadConsoleInputStream/ConcurrentBoundedQueue.cs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/tools/ReadConsoleInputStream/ConcurrentBoundedQueue.cs b/tools/ReadConsoleInputStream/ConcurrentBoundedQueue.cs index 67c32a51ca..cad81034fc 100644 --- a/tools/ReadConsoleInputStream/ConcurrentBoundedQueue.cs +++ b/tools/ReadConsoleInputStream/ConcurrentBoundedQueue.cs @@ -15,11 +15,6 @@ namespace Samples.Terminal Capacity = GetAlignedCapacity(capacity); } - /// - /// - /// - /// - /// public ConcurrentBoundedQueue(IEnumerable collection, int capacity) : base(collection) { Capacity = GetAlignedCapacity(capacity); From 370cea5cab942a1ff954a5d5928aa64d3597b00c Mon Sep 17 00:00:00 2001 From: Rich Turner Date: Wed, 24 Apr 2019 17:20:20 -0700 Subject: [PATCH 84/89] Retargeted EchoCon sample project to 17763 now Win10 1809 has shipped (#340) --- samples/ConPTY/EchoCon/EchoCon/EchoCon.vcxproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/ConPTY/EchoCon/EchoCon/EchoCon.vcxproj b/samples/ConPTY/EchoCon/EchoCon/EchoCon.vcxproj index 42fc73fea5..1f96a0ac46 100644 --- a/samples/ConPTY/EchoCon/EchoCon/EchoCon.vcxproj +++ b/samples/ConPTY/EchoCon/EchoCon/EchoCon.vcxproj @@ -23,7 +23,7 @@ {96274800-9574-423E-892A-909FBE2AC8BE} Win32Proj EchoCon - 10.0.17738.0 + 10.0.17763.0 From cfe3eb9624352ac5eb3f1c7f7a5dad2778618979 Mon Sep 17 00:00:00 2001 From: oising Date: Thu, 25 Apr 2019 10:15:02 -0400 Subject: [PATCH 85/89] address PR comments (root namespace) --- tools/ReadConsoleInputStream/ReadConsoleInputStreamDemo.csproj | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tools/ReadConsoleInputStream/ReadConsoleInputStreamDemo.csproj b/tools/ReadConsoleInputStream/ReadConsoleInputStreamDemo.csproj index e6b445ee51..a0cfb7f3e7 100644 --- a/tools/ReadConsoleInputStream/ReadConsoleInputStreamDemo.csproj +++ b/tools/ReadConsoleInputStream/ReadConsoleInputStreamDemo.csproj @@ -4,8 +4,7 @@ Exe netcoreapp2.2 latest - true - Nivot.Terminal + Samples.Terminal From f8f4f263a527cea45b897e43667a528335e0f3f7 Mon Sep 17 00:00:00 2001 From: Will Fuqua Date: Fri, 26 Apr 2019 12:34:55 +0700 Subject: [PATCH 86/89] standardize casing on PascalCase Feedback from review. I've decided to go with PascalCase as that's more standard in C# and recommended by MS (see the "Field" row in the table on https://docs.microsoft.com/en-us/dotnet/standard/design-guidelines/capitalization-conventions) --- tools/ColorTool/ColorTool/ColorScheme.cs | 12 +- tools/ColorTool/ColorTool/ColorTable.cs | 128 +++++++++--------- tools/ColorTool/ColorTool/ColorTool.csproj | 1 + tools/ColorTool/ColorTool/ConsoleAPI.cs | 14 +- .../ColorTool/ColorTool/ConsoleAttributes.cs | 3 + .../VirtualTerminalConsoleTarget.cs | 36 ++--- tools/ColorTool/ColorTool/Program.cs | 52 +++---- tools/ColorTool/ColorTool/SchemeManager.cs | 1 - .../SchemeParsers/IniSchemeParser.cs | 24 ++-- .../ColorTool/SchemeParsers/JsonParser.cs | 48 +++---- .../SchemeParsers/XmlSchemeParser.cs | 61 +++++---- .../SchemeWriters/IniSchemeWriter.cs | 10 +- 12 files changed, 194 insertions(+), 196 deletions(-) diff --git a/tools/ColorTool/ColorTool/ColorScheme.cs b/tools/ColorTool/ColorTool/ColorScheme.cs index 302e0459e3..62c0eb47d1 100644 --- a/tools/ColorTool/ColorTool/ColorScheme.cs +++ b/tools/ColorTool/ColorTool/ColorScheme.cs @@ -63,12 +63,12 @@ namespace ColorTool .First().Item2; private static Func, double> Difference(uint c1) => - // heuristic 1: nearest neighbor in RGB space - // tup => Distance(RGB(c1), RGB(tup.Item1)); - // heuristic 2: nearest neighbor in RGB space - // tup => Distance(HSV(c1), HSV(tup.Item1)); - // heuristic 3: weighted RGB L2 distance - tup => WeightedRGBSimilarity(c1, tup.Item1); + // heuristic 1: nearest neighbor in RGB space + // tup => Distance(RGB(c1), RGB(tup.Item1)); + // heuristic 2: nearest neighbor in RGB space + // tup => Distance(HSV(c1), HSV(tup.Item1)); + // heuristic 3: weighted RGB L2 distance + tup => WeightedRGBSimilarity(c1, tup.Item1); private static double WeightedRGBSimilarity(uint c1, uint c2) { diff --git a/tools/ColorTool/ColorTool/ColorTable.cs b/tools/ColorTool/ColorTool/ColorTable.cs index 53909a59f2..29470ac112 100644 --- a/tools/ColorTool/ColorTool/ColorTable.cs +++ b/tools/ColorTool/ColorTool/ColorTable.cs @@ -11,50 +11,62 @@ namespace ColorTool /// /// Displays the color table that demonstrates the current colorscheme. /// - class ColorTable + static class ColorTable { - const int DARK_BLACK = 0; - const int DARK_BLUE = 1; - const int DARK_GREEN = 2; - const int DARK_CYAN = 3; - const int DARK_RED = 4; - const int DARK_MAGENTA = 5; - const int DARK_YELLOW = 6; - const int DARK_WHITE = 7; - const int BRIGHT_BLACK = 8; - const int BRIGHT_BLUE = 9; - const int BRIGHT_GREEN = 10; - const int BRIGHT_CYAN = 11; - const int BRIGHT_RED = 12; - const int BRIGHT_MAGENTA = 13; - const int BRIGHT_YELLOW = 14; - const int BRIGHT_WHITE = 15; + private const int DarkBlack = 0; + private const int DarkBlue = 1; + private const int DarkGreen = 2; + private const int DarkCyan = 3; + private const int DarkRed = 4; + private const int DarkMagenta = 5; + private const int DarkYellow = 6; + private const int DarkWhite = 7; + private const int BrightBlack = 8; + private const int BrightBlue = 9; + private const int BrightGreen = 10; + private const int BrightCyan = 11; + private const int BrightRed = 12; + private const int BrightMagenta = 13; + private const int BrightYellow = 14; + private const int BrightWhite = 15; // This is the order of colors when output by the table. - private static readonly IReadOnlyList outputFgs = new[] + private static readonly IReadOnlyList Foregrounds = new[] { - BRIGHT_WHITE, - DARK_BLACK, - BRIGHT_BLACK, - DARK_RED, - BRIGHT_RED, - DARK_GREEN, - BRIGHT_GREEN, - DARK_YELLOW, - BRIGHT_YELLOW, - DARK_BLUE, - BRIGHT_BLUE, - DARK_MAGENTA, - BRIGHT_MAGENTA, - DARK_CYAN, - BRIGHT_CYAN, - DARK_WHITE, - BRIGHT_WHITE + BrightWhite, + DarkBlack, + BrightBlack, + DarkRed, + BrightRed, + DarkGreen, + BrightGreen, + DarkYellow, + BrightYellow, + DarkBlue, + BrightBlue, + DarkMagenta, + BrightMagenta, + DarkCyan, + BrightCyan, + DarkWhite, + BrightWhite + }; + + private static readonly IReadOnlyList Backgrounds = new[] + { + DarkBlack, + DarkRed, + DarkGreen, + DarkYellow, + DarkBlue, + DarkMagenta, + DarkCyan, + DarkWhite }; private const string TestText = " gYw "; - private static readonly IReadOnlyList FGs = new[] + private static readonly IReadOnlyList AnsiForegroundSequences = new[] { "m", "1m", @@ -76,7 +88,7 @@ namespace ColorTool "1;37m" }; - private static readonly IReadOnlyList BGs = new[] + private static readonly IReadOnlyList AnsiBackgroundSequences = new[] { "m", "40m", @@ -89,18 +101,6 @@ namespace ColorTool "47m" }; - private static readonly IReadOnlyList saneBgs = new[] - { - DARK_BLACK, - DARK_RED, - DARK_GREEN, - DARK_YELLOW, - DARK_BLUE, - DARK_MAGENTA, - DARK_CYAN, - DARK_WHITE - }; - public static void PrintTable() { ConsoleColor[] colors = (ConsoleColor[])ConsoleColor.GetValues(typeof(ConsoleColor)); @@ -109,36 +109,35 @@ namespace ColorTool ConsoleColor currentForeground = Console.ForegroundColor; Console.Write("\t"); - for (int bg = 0; bg < BGs.Count; bg++) + for (int bg = 0; bg < AnsiBackgroundSequences.Count; bg++) { if (bg > 0) Console.Write(" "); Console.Write(" "); - Console.Write(bg == 0 ? " " : BGs[bg]); + Console.Write(bg == 0 ? " " : AnsiBackgroundSequences[bg]); Console.Write(" "); } Console.WriteLine(); - for (int fg = 0; fg < FGs.Count; fg++) + for (int fg = 0; fg < AnsiForegroundSequences.Count; fg++) { Console.ForegroundColor = currentForeground; Console.BackgroundColor = currentBackground; - if (fg >= 0) Console.Write(FGs[fg] + "\t"); + if (fg >= 0) Console.Write(AnsiForegroundSequences[fg] + "\t"); if (fg == 0) Console.ForegroundColor = currentForeground; - else Console.ForegroundColor = colors[outputFgs[fg - 1]]; + else Console.ForegroundColor = colors[Foregrounds[fg - 1]]; - for (int bg = 0; bg < BGs.Count; bg++) + for (int bg = 0; bg < AnsiBackgroundSequences.Count; bg++) { if (bg > 0) Console.Write(" "); if (bg == 0) Console.BackgroundColor = currentBackground; - else Console.BackgroundColor = colors[saneBgs[bg - 1]]; + else Console.BackgroundColor = colors[Backgrounds[bg - 1]]; Console.Write(TestText); Console.BackgroundColor = currentBackground; } Console.Write("\n"); - } Console.Write("\n"); @@ -150,22 +149,22 @@ namespace ColorTool public static void PrintTableWithVt() { Console.Write("\t"); - for (int bg = 0; bg < BGs.Count; bg++) + for (int bg = 0; bg < AnsiBackgroundSequences.Count; bg++) { if (bg > 0) Console.Write(" "); Console.Write(" "); - Console.Write(bg == 0 ? " " : BGs[bg]); + Console.Write(bg == 0 ? " " : AnsiBackgroundSequences[bg]); Console.Write(" "); } Console.WriteLine(); - for (int fg = 0; fg < FGs.Count; fg++) + for (int fg = 0; fg < AnsiForegroundSequences.Count; fg++) { Console.Write("\x1b[m"); if (fg >= 0) { - Console.Write(FGs[fg] + "\t"); + Console.Write(AnsiForegroundSequences[fg] + "\t"); } if (fg == 0) @@ -174,10 +173,10 @@ namespace ColorTool } else { - Console.Write("\x1b[" + FGs[fg]); + Console.Write("\x1b[" + AnsiForegroundSequences[fg]); } - for (int bg = 0; bg < BGs.Count; bg++) + for (int bg = 0; bg < AnsiBackgroundSequences.Count; bg++) { if (bg > 0) { @@ -189,14 +188,13 @@ namespace ColorTool } else { - Console.Write("\x1b[" + BGs[bg]); + Console.Write("\x1b[" + AnsiBackgroundSequences[bg]); } Console.Write(TestText); Console.Write("\x1b[49m"); } Console.Write("\n"); - } Console.Write("\n"); diff --git a/tools/ColorTool/ColorTool/ColorTool.csproj b/tools/ColorTool/ColorTool/ColorTool.csproj index 729fe7d6c4..a1df3abb45 100644 --- a/tools/ColorTool/ColorTool/ColorTool.csproj +++ b/tools/ColorTool/ColorTool/ColorTool.csproj @@ -4,5 +4,6 @@ Exe net461 false + latest diff --git a/tools/ColorTool/ColorTool/ConsoleAPI.cs b/tools/ColorTool/ColorTool/ConsoleAPI.cs index 1f1c62309c..8df31f64dc 100644 --- a/tools/ColorTool/ColorTool/ConsoleAPI.cs +++ b/tools/ColorTool/ColorTool/ConsoleAPI.cs @@ -8,9 +8,11 @@ using System.Runtime.InteropServices; namespace ColorTool { - class ConsoleAPI + static class ConsoleAPI { - //////////////////////////////////////////////////////////////////////// + private const int StdOutputHandle = -11; + public const int ColorTableSize = 16; + [StructLayout(LayoutKind.Sequential)] public struct COORD { @@ -58,10 +60,7 @@ namespace ColorTool } } - public static int STD_OUTPUT_HANDLE = -11; - - - public static IntPtr GetStdOutputHandle() => GetStdHandle(STD_OUTPUT_HANDLE); + public static IntPtr GetStdOutputHandle() => GetStdHandle(StdOutputHandle); [DllImport("kernel32.dll", SetLastError = true)] public static extern IntPtr GetStdHandle(int nStdHandle); @@ -86,13 +85,10 @@ namespace ColorTool [DllImport("kernel32.dll", SetLastError = true)] public static extern bool SetConsoleMode(IntPtr hConsoleHandle, uint dwMode); - //////////////////////////////////////////////////////////////////////// public static uint RGB(int r, int g, int b) { return (uint)r + (((uint)g) << 8) + (((uint)b) << 16); } - - public const int COLOR_TABLE_SIZE = 16; } } diff --git a/tools/ColorTool/ColorTool/ConsoleAttributes.cs b/tools/ColorTool/ColorTool/ConsoleAttributes.cs index 23f28208f8..40234528fc 100644 --- a/tools/ColorTool/ColorTool/ConsoleAttributes.cs +++ b/tools/ColorTool/ColorTool/ConsoleAttributes.cs @@ -5,6 +5,9 @@ namespace ColorTool { + /// + /// Keeps track of the color table indices for the background/foreground in a colorscheme. + /// public readonly struct ConsoleAttributes { public ConsoleAttributes(uint? background, uint? foreground, uint? popupBackground, uint? popupForeground) diff --git a/tools/ColorTool/ColorTool/ConsoleTargets/VirtualTerminalConsoleTarget.cs b/tools/ColorTool/ColorTool/ConsoleTargets/VirtualTerminalConsoleTarget.cs index 692fe101c5..bbc24d96b0 100644 --- a/tools/ColorTool/ColorTool/ConsoleTargets/VirtualTerminalConsoleTarget.cs +++ b/tools/ColorTool/ColorTool/ConsoleTargets/VirtualTerminalConsoleTarget.cs @@ -16,24 +16,24 @@ namespace ColorTool.ConsoleTargets class VirtualTerminalConsoleTarget : IConsoleTarget { // Use a Console index in to get a VT index out. - public static readonly IReadOnlyList VT_INDICIES = new[] + public static readonly IReadOnlyList VirtualTerminalIndices = new[] { - 0, // DARK_BLACK - 4, // DARK_BLUE - 2, // DARK_GREEN - 6, // DARK_CYAN - 1, // DARK_RED - 5, // DARK_MAGENTA - 3, // DARK_YELLOW - 7, // DARK_WHITE - 8+0, // BRIGHT_BLACK - 8+4, // BRIGHT_BLUE - 8+2, // BRIGHT_GREEN - 8+6, // BRIGHT_CYAN - 8+1, // BRIGHT_RED - 8+5, // BRIGHT_MAGENTA - 8+3, // BRIGHT_YELLOW - 8+7, // BRIGHT_WHITE + 0, // Dark Black + 4, // Dark Blue + 2, // Dark Green + 6, // Dark Cyan + 1, // Dark Red + 5, // Dark Magenta + 3, // Dark Yellow + 7, // Dark White + 8+0, // Bright Black + 8+4, // Bright Blue + 8+2, // Bright Green + 8+6, // Bright Cyan + 8+1, // Bright Red + 8+5, // Bright Magenta + 8+3, // Bright Yellow + 8+7, // Bright White }; public void ApplyColorScheme(ColorScheme colorScheme, bool quietMode) @@ -50,7 +50,7 @@ namespace ColorTool.ConsoleTargets for (int i = 0; i < colorScheme.ColorTable.Length; i++) { - int vtIndex = VT_INDICIES[i]; + int vtIndex = VirtualTerminalIndices[i]; Color color = colorScheme[i]; string s = $"\x1b]4;{vtIndex};rgb:{color.R:X}/{color.G:X}/{color.B:X}\x7"; Console.Write(s); diff --git a/tools/ColorTool/ColorTool/Program.cs b/tools/ColorTool/ColorTool/Program.cs index 75939618b3..b9d12f4785 100644 --- a/tools/ColorTool/ColorTool/Program.cs +++ b/tools/ColorTool/ColorTool/Program.cs @@ -11,33 +11,15 @@ using System.Linq; namespace ColorTool { - class Program + static class Program { - static bool quietMode = false; - static bool reportErrors = false; - static bool setDefaults = false; - static bool setProperties = true; - static bool setUnixStyle = false; + private static bool quietMode = false; + private static bool reportErrors = false; + private static bool setDefaults = false; + private static bool setProperties = true; + private static bool setUnixStyle = false; - static void Usage() - { - Console.WriteLine(Resources.Usage, - string.Join($"{Environment.NewLine} ", SchemeManager.GetParsers().Select(p => p.Name))); - } - - static void OutputUsage() - { - Console.WriteLine(Resources.OutputUsage); - } - - static void Version() - { - var assembly = System.Reflection.Assembly.GetExecutingAssembly(); - var info = System.Diagnostics.FileVersionInfo.GetVersionInfo(assembly.Location); - Console.WriteLine($"colortool v{info.FileVersion}"); - } - - static void Main(string[] args) + public static void Main(string[] args) { if (args.Length < 1) { @@ -124,11 +106,29 @@ namespace ColorTool } } + private static void Usage() + { + Console.WriteLine(Resources.Usage, + string.Join($"{Environment.NewLine} ", SchemeManager.GetParsers().Select(p => p.Name))); + } + + private static void OutputUsage() + { + Console.WriteLine(Resources.OutputUsage); + } + + private static void Version() + { + var assembly = System.Reflection.Assembly.GetExecutingAssembly(); + var info = System.Diagnostics.FileVersionInfo.GetVersionInfo(assembly.Location); + Console.WriteLine($"colortool v{info.FileVersion}"); + } + /// /// Returns an enumerable of consoles that we want to apply the colorscheme to. /// The contents of this enumerable depends on the user's provided command line flags. /// - public static IEnumerable GetConsoleTargets() + private static IEnumerable GetConsoleTargets() { if (setDefaults) { diff --git a/tools/ColorTool/ColorTool/SchemeManager.cs b/tools/ColorTool/ColorTool/SchemeManager.cs index f00dcdd688..1f84a74601 100644 --- a/tools/ColorTool/ColorTool/SchemeManager.cs +++ b/tools/ColorTool/ColorTool/SchemeManager.cs @@ -48,7 +48,6 @@ namespace ColorTool Console.WriteLine(schemeDirectory); } - public static void PrintSchemes() { var schemeDirectory = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "schemes"); diff --git a/tools/ColorTool/ColorTool/SchemeParsers/IniSchemeParser.cs b/tools/ColorTool/ColorTool/SchemeParsers/IniSchemeParser.cs index bb4cbd1fc4..e4e1add824 100644 --- a/tools/ColorTool/ColorTool/SchemeParsers/IniSchemeParser.cs +++ b/tools/ColorTool/ColorTool/SchemeParsers/IniSchemeParser.cs @@ -21,7 +21,7 @@ namespace ColorTool.SchemeParsers private const string FileExtension = ".ini"; // These are in Windows Color table order - BRG, not RGB. - internal static readonly IReadOnlyList COLOR_NAMES = new[] + internal static readonly IReadOnlyList ColorNames = new[] { "DARK_BLACK", "DARK_BLUE", @@ -53,16 +53,16 @@ namespace ColorTool.SchemeParsers string filename = FindIniScheme(schemeName); if (filename == null) return null; - string[] tableStrings = new string[COLOR_TABLE_SIZE]; + string[] tableStrings = new string[ColorTableSize]; uint[] colorTable = null; uint? foregroundColor = null; uint? backgroundColor = null; uint? popupForegroundColor = null; uint? popupBackgroundColor = null; - for (int i = 0; i < COLOR_TABLE_SIZE; i++) + for (int i = 0; i < ColorTableSize; i++) { - string name = COLOR_NAMES[i]; + string name = ColorNames[i]; StringBuilder buffer = new StringBuilder(512); GetPrivateProfileString("table", name, null, buffer, 512, filename); @@ -82,16 +82,16 @@ namespace ColorTool.SchemeParsers { try { - colorTable = new uint[COLOR_TABLE_SIZE]; - for (int i = 0; i < COLOR_TABLE_SIZE; i++) + colorTable = new uint[ColorTableSize]; + for (int i = 0; i < ColorTableSize; i++) { colorTable[i] = ParseColor(tableStrings[i]); } if (ReadAttributes("popup", out var foreground, out var background)) { - var foregroundIndex = (COLOR_NAMES as IList).IndexOf(foreground); - var backgroundIndex = (COLOR_NAMES as IList).IndexOf(background); + var foregroundIndex = (ColorNames as IList).IndexOf(foreground); + var backgroundIndex = (ColorNames as IList).IndexOf(background); if (foregroundIndex != -1 && backgroundIndex != -1) { popupForegroundColor = colorTable[foregroundIndex]; @@ -101,8 +101,8 @@ namespace ColorTool.SchemeParsers if (ReadAttributes("screen", out foreground, out background)) { - var foregroundIndex = (COLOR_NAMES as IList).IndexOf(foreground); - var backgroundIndex = (COLOR_NAMES as IList).IndexOf(background); + var foregroundIndex = (ColorNames as IList).IndexOf(foreground); + var backgroundIndex = (ColorNames as IList).IndexOf(background); if (foregroundIndex != -1 && backgroundIndex != -1) { foregroundColor = colorTable[foregroundIndex]; @@ -139,14 +139,14 @@ namespace ColorTool.SchemeParsers StringBuilder buffer = new StringBuilder(512); GetPrivateProfileString(section, "FOREGROUND", null, buffer, 512, filename); foreground = buffer.ToString(); - if (!COLOR_NAMES.Contains(foreground)) + if (!ColorNames.Contains(foreground)) return false; buffer = new StringBuilder(512); GetPrivateProfileString(section, "BACKGROUND", null, buffer, 512, filename); background = buffer.ToString(); - if (!COLOR_NAMES.Contains(background)) + if (!ColorNames.Contains(background)) return false; return true; diff --git a/tools/ColorTool/ColorTool/SchemeParsers/JsonParser.cs b/tools/ColorTool/ColorTool/SchemeParsers/JsonParser.cs index e3e817d0be..37218ba18a 100644 --- a/tools/ColorTool/ColorTool/SchemeParsers/JsonParser.cs +++ b/tools/ColorTool/ColorTool/SchemeParsers/JsonParser.cs @@ -16,24 +16,24 @@ namespace ColorTool.SchemeParsers class JsonParser : ISchemeParser { private const string FileExtension = ".json"; - private static IReadOnlyList CONCFG_COLOR_NAMES = new[] + private static readonly IReadOnlyList ConcfgColorNames = new[] { - "black", // DARK_BLACK - "dark_blue", // DARK_BLUE - "dark_green", // DARK_GREEN - "dark_cyan", // DARK_CYAN - "dark_red", // DARK_RED - "dark_magenta", // DARK_MAGENTA - "dark_yellow", // DARK_YELLOW - "gray", // DARK_WHITE - "dark_gray", // BRIGHT_BLACK - "blue", // BRIGHT_BLUE - "green", // BRIGHT_GREEN - "cyan", // BRIGHT_CYAN - "red", // BRIGHT_RED - "magenta", // BRIGHT_MAGENTA - "yellow", // BRIGHT_YELLOW - "white" // BRIGHT_WHITE + "black", // Dark Black + "dark_blue", // Dark Blue + "dark_green", // Dark Green + "dark_cyan", // Dark Cyan + "dark_red", // Dark Red + "dark_magenta", // Dark Magenta + "dark_yellow", // Dark Yellow + "gray", // Dark White + "dark_gray", // Bright Black + "blue", // Bright Blue + "green", // Bright Green + "cyan", // Bright Cyan + "red", // Bright Red + "magenta", // Bright Magenta + "yellow", // Bright Yellow + "white" // Bright White }; public string Name { get; } = "concfg Parser"; @@ -50,10 +50,10 @@ namespace ColorTool.SchemeParsers { XmlNode root = xmlDoc.DocumentElement; XmlNodeList children = root.ChildNodes; - uint[] colorTable = new uint[COLOR_TABLE_SIZE]; ; - for (int i = 0; i < COLOR_TABLE_SIZE; i++) + uint[] colorTable = new uint[ColorTableSize]; ; + for (int i = 0; i < ColorTableSize; i++) { - string name = CONCFG_COLOR_NAMES[i]; + string name = ConcfgColorNames[i]; var node = children.OfType().Where(n => n.Name == name).Single(); colorTable[i] = ParseColor(node.InnerText); } @@ -68,8 +68,8 @@ namespace ColorTool.SchemeParsers var parts = popupNode.InnerText.Split(','); if (parts.Length == 2) { - var foregroundIndex = (CONCFG_COLOR_NAMES as IList).IndexOf(parts[0]); - var backgroundIndex = (CONCFG_COLOR_NAMES as IList).IndexOf(parts[1]); + var foregroundIndex = (ConcfgColorNames as IList).IndexOf(parts[0]); + var backgroundIndex = (ConcfgColorNames as IList).IndexOf(parts[1]); if (foregroundIndex != -1 && backgroundIndex != -1) { popupForeground = colorTable[foregroundIndex]; @@ -87,8 +87,8 @@ namespace ColorTool.SchemeParsers var parts = screenNode.InnerText.Split(','); if (parts.Length == 2) { - var foregroundIndex = (CONCFG_COLOR_NAMES as IList).IndexOf(parts[0]); - var backgroundIndex = (CONCFG_COLOR_NAMES as IList).IndexOf(parts[1]); + var foregroundIndex = (ConcfgColorNames as IList).IndexOf(parts[0]); + var backgroundIndex = (ConcfgColorNames as IList).IndexOf(parts[1]); if (foregroundIndex != -1 && backgroundIndex != -1) { screenForeground = colorTable[foregroundIndex]; diff --git a/tools/ColorTool/ColorTool/SchemeParsers/XmlSchemeParser.cs b/tools/ColorTool/ColorTool/SchemeParsers/XmlSchemeParser.cs index 39177a12c0..4747fd0157 100644 --- a/tools/ColorTool/ColorTool/SchemeParsers/XmlSchemeParser.cs +++ b/tools/ColorTool/ColorTool/SchemeParsers/XmlSchemeParser.cs @@ -16,30 +16,31 @@ namespace ColorTool.SchemeParsers class XmlSchemeParser : ISchemeParser { // In Windows Color Table order - private static readonly string[] PLIST_COLOR_NAMES = + private static readonly string[] PListColorNames = { - "Ansi 0 Color", // DARK_BLACK - "Ansi 4 Color", // DARK_BLUE - "Ansi 2 Color", // DARK_GREEN - "Ansi 6 Color", // DARK_CYAN - "Ansi 1 Color", // DARK_RED - "Ansi 5 Color", // DARK_MAGENTA - "Ansi 3 Color", // DARK_YELLOW - "Ansi 7 Color", // DARK_WHITE - "Ansi 8 Color", // BRIGHT_BLACK - "Ansi 12 Color", // BRIGHT_BLUE - "Ansi 10 Color", // BRIGHT_GREEN - "Ansi 14 Color", // BRIGHT_CYAN - "Ansi 9 Color", // BRIGHT_RED - "Ansi 13 Color", // BRIGHT_MAGENTA - "Ansi 11 Color", // BRIGHT_YELLOW - "Ansi 15 Color" // BRIGHT_WHITE + "Ansi 0 Color", // Dark Black + "Ansi 4 Color", // Dark Blue + "Ansi 2 Color", // Dark Green + "Ansi 6 Color", // Dark Cyan + "Ansi 1 Color", // Dark Red + "Ansi 5 Color", // Dark Magenta + "Ansi 3 Color", // Dark Yellow + "Ansi 7 Color", // Dark White + "Ansi 8 Color", // Bright Black + "Ansi 12 Color", // Bright Blue + "Ansi 10 Color", // Bright Green + "Ansi 14 Color", // Bright Cyan + "Ansi 9 Color", // Bright Red + "Ansi 13 Color", // Bright Magenta + "Ansi 11 Color", // Bright Yellow + "Ansi 15 Color" // Bright White }; - private const string FG_KEY = "Foreground Color"; - private const string BG_KEY = "Background Color"; - private const string RED_KEY = "Red Component"; - private const string GREEN_KEY = "Green Component"; - private const string BLUE_KEY = "Blue Component"; + + private const string ForegroundKey = "Foreground Color"; + private const string BackgroundKey = "Background Color"; + private const string RedKey = "Red Component"; + private const string GreenKey = "Green Component"; + private const string BlueKey = "Blue Component"; private const string FileExtension = ".itermcolors"; public string Name { get; } = "iTerm Parser"; @@ -54,7 +55,7 @@ namespace ColorTool.SchemeParsers XmlNode root = xmlDoc.GetElementsByTagName("dict")[0]; XmlNodeList children = root.ChildNodes; - uint[] colorTable = new uint[COLOR_TABLE_SIZE]; + uint[] colorTable = new uint[ColorTableSize]; uint? fgColor = null, bgColor = null; int colorsFound = 0; bool success = false; @@ -65,12 +66,12 @@ namespace ColorTool.SchemeParsers XmlNode components = tableEntry.NextSibling; success = ParseRgbFromXml(components, ref rgb); if (!success) { break; } - else if (tableEntry.InnerText == FG_KEY) { fgColor = rgb; } - else if (tableEntry.InnerText == BG_KEY) { bgColor = rgb; } - else if (-1 != (index = Array.IndexOf(PLIST_COLOR_NAMES, tableEntry.InnerText))) + else if (tableEntry.InnerText == ForegroundKey) { fgColor = rgb; } + else if (tableEntry.InnerText == BackgroundKey) { bgColor = rgb; } + else if (-1 != (index = Array.IndexOf(PListColorNames, tableEntry.InnerText))) { colorTable[index] = rgb; colorsFound++; } } - if (colorsFound < COLOR_TABLE_SIZE) + if (colorsFound < ColorTableSize) { if (reportErrors) { @@ -97,15 +98,15 @@ namespace ColorTool.SchemeParsers { if (c.Name == "key") { - if (c.InnerText == RED_KEY) + if (c.InnerText == RedKey) { r = (int)(255 * Convert.ToDouble(c.NextSibling.InnerText, CultureInfo.InvariantCulture)); } - else if (c.InnerText == GREEN_KEY) + else if (c.InnerText == GreenKey) { g = (int)(255 * Convert.ToDouble(c.NextSibling.InnerText, CultureInfo.InvariantCulture)); } - else if (c.InnerText == BLUE_KEY) + else if (c.InnerText == BlueKey) { b = (int)(255 * Convert.ToDouble(c.NextSibling.InnerText, CultureInfo.InvariantCulture)); } diff --git a/tools/ColorTool/ColorTool/SchemeWriters/IniSchemeWriter.cs b/tools/ColorTool/ColorTool/SchemeWriters/IniSchemeWriter.cs index 18b4bb6650..e72a35fe0c 100644 --- a/tools/ColorTool/ColorTool/SchemeWriters/IniSchemeWriter.cs +++ b/tools/ColorTool/ColorTool/SchemeWriters/IniSchemeWriter.cs @@ -26,7 +26,7 @@ namespace ColorTool.SchemeWriters file.WriteLine("[table]"); for (int i = 0; i < 16; i++) { - string line = IniSchemeParser.COLOR_NAMES[i]; + string line = IniSchemeParser.ColorNames[i]; line += " = "; uint color = csbiex.ColorTable[i]; uint r = color & (0x000000ff); @@ -40,15 +40,15 @@ namespace ColorTool.SchemeWriters file.WriteLine("[screen]"); var forgroundIndex = csbiex.wAttributes & 0xF; var backgroundIndex = csbiex.wAttributes >> 4; - file.WriteLine($"FOREGROUND = {IniSchemeParser.COLOR_NAMES[forgroundIndex]}"); - file.WriteLine($"BACKGROUND = {IniSchemeParser.COLOR_NAMES[backgroundIndex]}"); + file.WriteLine($"FOREGROUND = {IniSchemeParser.ColorNames[forgroundIndex]}"); + file.WriteLine($"BACKGROUND = {IniSchemeParser.ColorNames[backgroundIndex]}"); file.WriteLine(); file.WriteLine("[popup]"); forgroundIndex = csbiex.wPopupAttributes & 0xF; backgroundIndex = csbiex.wPopupAttributes >> 4; - file.WriteLine($"FOREGROUND = {IniSchemeParser.COLOR_NAMES[forgroundIndex]}"); - file.WriteLine($"BACKGROUND = {IniSchemeParser.COLOR_NAMES[backgroundIndex]}"); + file.WriteLine($"FOREGROUND = {IniSchemeParser.ColorNames[forgroundIndex]}"); + file.WriteLine($"BACKGROUND = {IniSchemeParser.ColorNames[backgroundIndex]}"); } } catch (Exception ex) From 987805ebafd796a09b63a9a718a9d8c489eab70a Mon Sep 17 00:00:00 2001 From: oising Date: Mon, 29 Apr 2019 14:50:38 -0400 Subject: [PATCH 87/89] moved readconsoleinputstream to samples folder; added readme; updated root readme. --- README.md | 1 + .../ConcurrentBoundedQueue.cs | 0 .../ReadConsoleInputStream/NativeMethods.cs | 0 .../ReadConsoleInputStream/Program.cs | 0 samples/ReadConsoleInputStream/README.md | 16 ++++++++++++++++ .../ReadConsoleInputStream.cs | 0 .../ReadConsoleInputStreamDemo.csproj | 0 .../ReadConsoleInputStreamDemo.sln | 0 8 files changed, 17 insertions(+) rename {tools => samples}/ReadConsoleInputStream/ConcurrentBoundedQueue.cs (100%) rename {tools => samples}/ReadConsoleInputStream/NativeMethods.cs (100%) rename {tools => samples}/ReadConsoleInputStream/Program.cs (100%) create mode 100644 samples/ReadConsoleInputStream/README.md rename {tools => samples}/ReadConsoleInputStream/ReadConsoleInputStream.cs (100%) rename {tools => samples}/ReadConsoleInputStream/ReadConsoleInputStreamDemo.csproj (100%) rename {tools => samples}/ReadConsoleInputStream/ReadConsoleInputStreamDemo.sln (100%) diff --git a/README.md b/README.md index fe9a518991..56a59ca8d4 100644 --- a/README.md +++ b/README.md @@ -19,6 +19,7 @@ You'll also find assorted Console tools, samples, including the following: * [ColorTool](https://github.com/Microsoft/Console/tree/master/tools/ColorTool) - A tool for changing the color scheme of the Windows console. * [EchoCon](https://github.com/Microsoft/console/tree/master/samples/ConPTY/EchoCon) - A C++ sample application that illustrates how to use the new Win32 Pseudo Console (ConPTY). * [MiniTerm](https://github.com/Microsoft/console/tree/master/samples/ConPTY/MiniTerm) - A C# sample terminal that illustrates how to use ConPTY. +* [ReadConsoleInputStream](https://github.com/Microsoft/console/tree/master/samples/ReadConsoleInputStream) - A C# sample console application that shows how to use the console APIs to stream stdin while asynchronously watching for console events (buffer size, viewport size, mouse input etc.) ### Tool Build Status diff --git a/tools/ReadConsoleInputStream/ConcurrentBoundedQueue.cs b/samples/ReadConsoleInputStream/ConcurrentBoundedQueue.cs similarity index 100% rename from tools/ReadConsoleInputStream/ConcurrentBoundedQueue.cs rename to samples/ReadConsoleInputStream/ConcurrentBoundedQueue.cs diff --git a/tools/ReadConsoleInputStream/NativeMethods.cs b/samples/ReadConsoleInputStream/NativeMethods.cs similarity index 100% rename from tools/ReadConsoleInputStream/NativeMethods.cs rename to samples/ReadConsoleInputStream/NativeMethods.cs diff --git a/tools/ReadConsoleInputStream/Program.cs b/samples/ReadConsoleInputStream/Program.cs similarity index 100% rename from tools/ReadConsoleInputStream/Program.cs rename to samples/ReadConsoleInputStream/Program.cs diff --git a/samples/ReadConsoleInputStream/README.md b/samples/ReadConsoleInputStream/README.md new file mode 100644 index 0000000000..c6ce6e616a --- /dev/null +++ b/samples/ReadConsoleInputStream/README.md @@ -0,0 +1,16 @@ +# ReadConsoleInputStream Demo + +This is a demo that shows how we can have a stream-oriented view of characters from the console while also listening to console events like mouse, menu, focus, buffer/viewport resize events. This is partcularly useful when working with VT100 streams and ConPTY. + +This has always been tricky to do because ReadConsoleW/A doesn't allow retrieving events. Only ReadConsoleInputW/A returns events, but isn't stream-oriented. Using both doesn't work because ReadConsoleW/A flushes the input queue, meaning calls to ReadConsoleInputW/A will wait forever. + +I do this by deriving a new Stream class which wraps ReadConsoleInputW and accepts a provider/consumer implementation of BlockingCollection. This allows asynchronous monitoring of console events while simultaneously streaming the character input. I also use Mark Gravell's great System.IO.Pipelines utility classes and David Hall's excellent P/Invoke wrappers to make this demo cleaner to read; both are pulled from NuGet. + +**Note:** + +In versions of windows 10 prior to 1809, the buffer resize event only fires for enlarging the viewport, as this would cause the buffer to be enlarged too. Now it fires even when shrinking the viewport, which won't change the buffer size. + +NuGet packages used (GitHub links): + +* [Pipelines.Sockets.Unofficial](https://github.com/mgravell/Pipelines.Sockets.Unofficial) +* [Vanara P/Invoke](https://github.com/dahall/Vanara) \ No newline at end of file diff --git a/tools/ReadConsoleInputStream/ReadConsoleInputStream.cs b/samples/ReadConsoleInputStream/ReadConsoleInputStream.cs similarity index 100% rename from tools/ReadConsoleInputStream/ReadConsoleInputStream.cs rename to samples/ReadConsoleInputStream/ReadConsoleInputStream.cs diff --git a/tools/ReadConsoleInputStream/ReadConsoleInputStreamDemo.csproj b/samples/ReadConsoleInputStream/ReadConsoleInputStreamDemo.csproj similarity index 100% rename from tools/ReadConsoleInputStream/ReadConsoleInputStreamDemo.csproj rename to samples/ReadConsoleInputStream/ReadConsoleInputStreamDemo.csproj diff --git a/tools/ReadConsoleInputStream/ReadConsoleInputStreamDemo.sln b/samples/ReadConsoleInputStream/ReadConsoleInputStreamDemo.sln similarity index 100% rename from tools/ReadConsoleInputStream/ReadConsoleInputStreamDemo.sln rename to samples/ReadConsoleInputStream/ReadConsoleInputStreamDemo.sln From 864f45fa112e05138b4084fe224ad2c671cba961 Mon Sep 17 00:00:00 2001 From: "Dustin L. Howett (MSFT)" Date: Tue, 30 Apr 2019 12:27:06 -0700 Subject: [PATCH 88/89] Move ColorTool to src/ (#422) --- README.md | 4 ++-- {tools => src/tools}/ColorTool/ColorTool.sln | 0 {tools => src/tools}/ColorTool/ColorTool/App.config | 0 {tools => src/tools}/ColorTool/ColorTool/ColorScheme.cs | 0 {tools => src/tools}/ColorTool/ColorTool/ColorTable.cs | 0 {tools => src/tools}/ColorTool/ColorTool/ColorTool.csproj | 0 {tools => src/tools}/ColorTool/ColorTool/ConsoleAPI.cs | 0 {tools => src/tools}/ColorTool/ColorTool/ConsoleAttributes.cs | 0 .../ColorTool/ConsoleTargets/CurrentConsoleTarget.cs | 0 .../ColorTool/ConsoleTargets/DefaultConsoleTarget.cs | 0 .../ColorTool/ColorTool/ConsoleTargets/IConsoleTarget.cs | 0 .../ColorTool/ConsoleTargets/VirtualTerminalConsoleTarget.cs | 0 {tools => src/tools}/ColorTool/ColorTool/Program.cs | 0 .../tools}/ColorTool/ColorTool/Properties/launchSettings.json | 0 .../tools}/ColorTool/ColorTool/Resources.Designer.cs | 0 {tools => src/tools}/ColorTool/ColorTool/Resources.resx | 0 {tools => src/tools}/ColorTool/ColorTool/SchemeManager.cs | 0 .../tools}/ColorTool/ColorTool/SchemeParsers/ISchemeParser.cs | 0 .../ColorTool/ColorTool/SchemeParsers/IniSchemeParser.cs | 0 .../tools}/ColorTool/ColorTool/SchemeParsers/JsonParser.cs | 0 .../ColorTool/ColorTool/SchemeParsers/XmlSchemeParser.cs | 0 .../ColorTool/ColorTool/SchemeWriters/IniSchemeWriter.cs | 0 {tools => src/tools}/ColorTool/LICENSE | 0 {tools => src/tools}/ColorTool/README.md | 0 {tools => src/tools}/ColorTool/ThirdPartyNotices.md | 0 {tools => src/tools}/ColorTool/all.bat | 0 {tools => src/tools}/ColorTool/build.bat | 0 .../tools}/ColorTool/schemes/OneHalfDark.itermcolors | 0 .../tools}/ColorTool/schemes/OneHalfLight.itermcolors | 0 {tools => src/tools}/ColorTool/schemes/campbell-legacy.ini | 0 {tools => src/tools}/ColorTool/schemes/campbell.ini | 0 {tools => src/tools}/ColorTool/schemes/cmd-legacy.ini | 0 .../tools}/ColorTool/schemes/deuteranopia.itermcolors | 0 .../tools}/ColorTool/schemes/solarized_dark.itermcolors | 0 .../tools}/ColorTool/schemes/solarized_light.itermcolors | 0 {tools => src/tools}/ColorTool/signing/CopySignFiles.cmd | 0 {tools => src/tools}/ColorTool/signing/SignConfig.xml | 0 37 files changed, 2 insertions(+), 2 deletions(-) rename {tools => src/tools}/ColorTool/ColorTool.sln (100%) rename {tools => src/tools}/ColorTool/ColorTool/App.config (100%) rename {tools => src/tools}/ColorTool/ColorTool/ColorScheme.cs (100%) rename {tools => src/tools}/ColorTool/ColorTool/ColorTable.cs (100%) rename {tools => src/tools}/ColorTool/ColorTool/ColorTool.csproj (100%) rename {tools => src/tools}/ColorTool/ColorTool/ConsoleAPI.cs (100%) rename {tools => src/tools}/ColorTool/ColorTool/ConsoleAttributes.cs (100%) rename {tools => src/tools}/ColorTool/ColorTool/ConsoleTargets/CurrentConsoleTarget.cs (100%) rename {tools => src/tools}/ColorTool/ColorTool/ConsoleTargets/DefaultConsoleTarget.cs (100%) rename {tools => src/tools}/ColorTool/ColorTool/ConsoleTargets/IConsoleTarget.cs (100%) rename {tools => src/tools}/ColorTool/ColorTool/ConsoleTargets/VirtualTerminalConsoleTarget.cs (100%) rename {tools => src/tools}/ColorTool/ColorTool/Program.cs (100%) rename {tools => src/tools}/ColorTool/ColorTool/Properties/launchSettings.json (100%) rename {tools => src/tools}/ColorTool/ColorTool/Resources.Designer.cs (100%) rename {tools => src/tools}/ColorTool/ColorTool/Resources.resx (100%) rename {tools => src/tools}/ColorTool/ColorTool/SchemeManager.cs (100%) rename {tools => src/tools}/ColorTool/ColorTool/SchemeParsers/ISchemeParser.cs (100%) rename {tools => src/tools}/ColorTool/ColorTool/SchemeParsers/IniSchemeParser.cs (100%) rename {tools => src/tools}/ColorTool/ColorTool/SchemeParsers/JsonParser.cs (100%) rename {tools => src/tools}/ColorTool/ColorTool/SchemeParsers/XmlSchemeParser.cs (100%) rename {tools => src/tools}/ColorTool/ColorTool/SchemeWriters/IniSchemeWriter.cs (100%) rename {tools => src/tools}/ColorTool/LICENSE (100%) rename {tools => src/tools}/ColorTool/README.md (100%) rename {tools => src/tools}/ColorTool/ThirdPartyNotices.md (100%) rename {tools => src/tools}/ColorTool/all.bat (100%) rename {tools => src/tools}/ColorTool/build.bat (100%) rename {tools => src/tools}/ColorTool/schemes/OneHalfDark.itermcolors (100%) rename {tools => src/tools}/ColorTool/schemes/OneHalfLight.itermcolors (100%) rename {tools => src/tools}/ColorTool/schemes/campbell-legacy.ini (100%) rename {tools => src/tools}/ColorTool/schemes/campbell.ini (100%) rename {tools => src/tools}/ColorTool/schemes/cmd-legacy.ini (100%) rename {tools => src/tools}/ColorTool/schemes/deuteranopia.itermcolors (100%) rename {tools => src/tools}/ColorTool/schemes/solarized_dark.itermcolors (100%) rename {tools => src/tools}/ColorTool/schemes/solarized_light.itermcolors (100%) rename {tools => src/tools}/ColorTool/signing/CopySignFiles.cmd (100%) rename {tools => src/tools}/ColorTool/signing/SignConfig.xml (100%) diff --git a/README.md b/README.md index 56a59ca8d4..34c06827ea 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ In addition, the team reserve the right to actively manage issues, closing dupli ## Tools & Samples You'll also find assorted Console tools, samples, including the following: -* [ColorTool](https://github.com/Microsoft/Console/tree/master/tools/ColorTool) - A tool for changing the color scheme of the Windows console. +* [ColorTool](https://github.com/Microsoft/Console/tree/master/src/tools/ColorTool) - A tool for changing the color scheme of the Windows console. * [EchoCon](https://github.com/Microsoft/console/tree/master/samples/ConPTY/EchoCon) - A C++ sample application that illustrates how to use the new Win32 Pseudo Console (ConPTY). * [MiniTerm](https://github.com/Microsoft/console/tree/master/samples/ConPTY/MiniTerm) - A C# sample terminal that illustrates how to use ConPTY. * [ReadConsoleInputStream](https://github.com/Microsoft/console/tree/master/samples/ReadConsoleInputStream) - A C# sample console application that shows how to use the console APIs to stream stdin while asynchronously watching for console events (buffer size, viewport size, mouse input etc.) @@ -25,4 +25,4 @@ You'll also find assorted Console tools, samples, including the following: Project|Build Status ---|--- -tools/ColorTool|![](https://microsoft.visualstudio.com/_apis/public/build/definitions/c93e867a-8815-43c1-92c4-e7dd5404f1e1/17023/badge) +src/tools/ColorTool|![](https://microsoft.visualstudio.com/_apis/public/build/definitions/c93e867a-8815-43c1-92c4-e7dd5404f1e1/17023/badge) diff --git a/tools/ColorTool/ColorTool.sln b/src/tools/ColorTool/ColorTool.sln similarity index 100% rename from tools/ColorTool/ColorTool.sln rename to src/tools/ColorTool/ColorTool.sln diff --git a/tools/ColorTool/ColorTool/App.config b/src/tools/ColorTool/ColorTool/App.config similarity index 100% rename from tools/ColorTool/ColorTool/App.config rename to src/tools/ColorTool/ColorTool/App.config diff --git a/tools/ColorTool/ColorTool/ColorScheme.cs b/src/tools/ColorTool/ColorTool/ColorScheme.cs similarity index 100% rename from tools/ColorTool/ColorTool/ColorScheme.cs rename to src/tools/ColorTool/ColorTool/ColorScheme.cs diff --git a/tools/ColorTool/ColorTool/ColorTable.cs b/src/tools/ColorTool/ColorTool/ColorTable.cs similarity index 100% rename from tools/ColorTool/ColorTool/ColorTable.cs rename to src/tools/ColorTool/ColorTool/ColorTable.cs diff --git a/tools/ColorTool/ColorTool/ColorTool.csproj b/src/tools/ColorTool/ColorTool/ColorTool.csproj similarity index 100% rename from tools/ColorTool/ColorTool/ColorTool.csproj rename to src/tools/ColorTool/ColorTool/ColorTool.csproj diff --git a/tools/ColorTool/ColorTool/ConsoleAPI.cs b/src/tools/ColorTool/ColorTool/ConsoleAPI.cs similarity index 100% rename from tools/ColorTool/ColorTool/ConsoleAPI.cs rename to src/tools/ColorTool/ColorTool/ConsoleAPI.cs diff --git a/tools/ColorTool/ColorTool/ConsoleAttributes.cs b/src/tools/ColorTool/ColorTool/ConsoleAttributes.cs similarity index 100% rename from tools/ColorTool/ColorTool/ConsoleAttributes.cs rename to src/tools/ColorTool/ColorTool/ConsoleAttributes.cs diff --git a/tools/ColorTool/ColorTool/ConsoleTargets/CurrentConsoleTarget.cs b/src/tools/ColorTool/ColorTool/ConsoleTargets/CurrentConsoleTarget.cs similarity index 100% rename from tools/ColorTool/ColorTool/ConsoleTargets/CurrentConsoleTarget.cs rename to src/tools/ColorTool/ColorTool/ConsoleTargets/CurrentConsoleTarget.cs diff --git a/tools/ColorTool/ColorTool/ConsoleTargets/DefaultConsoleTarget.cs b/src/tools/ColorTool/ColorTool/ConsoleTargets/DefaultConsoleTarget.cs similarity index 100% rename from tools/ColorTool/ColorTool/ConsoleTargets/DefaultConsoleTarget.cs rename to src/tools/ColorTool/ColorTool/ConsoleTargets/DefaultConsoleTarget.cs diff --git a/tools/ColorTool/ColorTool/ConsoleTargets/IConsoleTarget.cs b/src/tools/ColorTool/ColorTool/ConsoleTargets/IConsoleTarget.cs similarity index 100% rename from tools/ColorTool/ColorTool/ConsoleTargets/IConsoleTarget.cs rename to src/tools/ColorTool/ColorTool/ConsoleTargets/IConsoleTarget.cs diff --git a/tools/ColorTool/ColorTool/ConsoleTargets/VirtualTerminalConsoleTarget.cs b/src/tools/ColorTool/ColorTool/ConsoleTargets/VirtualTerminalConsoleTarget.cs similarity index 100% rename from tools/ColorTool/ColorTool/ConsoleTargets/VirtualTerminalConsoleTarget.cs rename to src/tools/ColorTool/ColorTool/ConsoleTargets/VirtualTerminalConsoleTarget.cs diff --git a/tools/ColorTool/ColorTool/Program.cs b/src/tools/ColorTool/ColorTool/Program.cs similarity index 100% rename from tools/ColorTool/ColorTool/Program.cs rename to src/tools/ColorTool/ColorTool/Program.cs diff --git a/tools/ColorTool/ColorTool/Properties/launchSettings.json b/src/tools/ColorTool/ColorTool/Properties/launchSettings.json similarity index 100% rename from tools/ColorTool/ColorTool/Properties/launchSettings.json rename to src/tools/ColorTool/ColorTool/Properties/launchSettings.json diff --git a/tools/ColorTool/ColorTool/Resources.Designer.cs b/src/tools/ColorTool/ColorTool/Resources.Designer.cs similarity index 100% rename from tools/ColorTool/ColorTool/Resources.Designer.cs rename to src/tools/ColorTool/ColorTool/Resources.Designer.cs diff --git a/tools/ColorTool/ColorTool/Resources.resx b/src/tools/ColorTool/ColorTool/Resources.resx similarity index 100% rename from tools/ColorTool/ColorTool/Resources.resx rename to src/tools/ColorTool/ColorTool/Resources.resx diff --git a/tools/ColorTool/ColorTool/SchemeManager.cs b/src/tools/ColorTool/ColorTool/SchemeManager.cs similarity index 100% rename from tools/ColorTool/ColorTool/SchemeManager.cs rename to src/tools/ColorTool/ColorTool/SchemeManager.cs diff --git a/tools/ColorTool/ColorTool/SchemeParsers/ISchemeParser.cs b/src/tools/ColorTool/ColorTool/SchemeParsers/ISchemeParser.cs similarity index 100% rename from tools/ColorTool/ColorTool/SchemeParsers/ISchemeParser.cs rename to src/tools/ColorTool/ColorTool/SchemeParsers/ISchemeParser.cs diff --git a/tools/ColorTool/ColorTool/SchemeParsers/IniSchemeParser.cs b/src/tools/ColorTool/ColorTool/SchemeParsers/IniSchemeParser.cs similarity index 100% rename from tools/ColorTool/ColorTool/SchemeParsers/IniSchemeParser.cs rename to src/tools/ColorTool/ColorTool/SchemeParsers/IniSchemeParser.cs diff --git a/tools/ColorTool/ColorTool/SchemeParsers/JsonParser.cs b/src/tools/ColorTool/ColorTool/SchemeParsers/JsonParser.cs similarity index 100% rename from tools/ColorTool/ColorTool/SchemeParsers/JsonParser.cs rename to src/tools/ColorTool/ColorTool/SchemeParsers/JsonParser.cs diff --git a/tools/ColorTool/ColorTool/SchemeParsers/XmlSchemeParser.cs b/src/tools/ColorTool/ColorTool/SchemeParsers/XmlSchemeParser.cs similarity index 100% rename from tools/ColorTool/ColorTool/SchemeParsers/XmlSchemeParser.cs rename to src/tools/ColorTool/ColorTool/SchemeParsers/XmlSchemeParser.cs diff --git a/tools/ColorTool/ColorTool/SchemeWriters/IniSchemeWriter.cs b/src/tools/ColorTool/ColorTool/SchemeWriters/IniSchemeWriter.cs similarity index 100% rename from tools/ColorTool/ColorTool/SchemeWriters/IniSchemeWriter.cs rename to src/tools/ColorTool/ColorTool/SchemeWriters/IniSchemeWriter.cs diff --git a/tools/ColorTool/LICENSE b/src/tools/ColorTool/LICENSE similarity index 100% rename from tools/ColorTool/LICENSE rename to src/tools/ColorTool/LICENSE diff --git a/tools/ColorTool/README.md b/src/tools/ColorTool/README.md similarity index 100% rename from tools/ColorTool/README.md rename to src/tools/ColorTool/README.md diff --git a/tools/ColorTool/ThirdPartyNotices.md b/src/tools/ColorTool/ThirdPartyNotices.md similarity index 100% rename from tools/ColorTool/ThirdPartyNotices.md rename to src/tools/ColorTool/ThirdPartyNotices.md diff --git a/tools/ColorTool/all.bat b/src/tools/ColorTool/all.bat similarity index 100% rename from tools/ColorTool/all.bat rename to src/tools/ColorTool/all.bat diff --git a/tools/ColorTool/build.bat b/src/tools/ColorTool/build.bat similarity index 100% rename from tools/ColorTool/build.bat rename to src/tools/ColorTool/build.bat diff --git a/tools/ColorTool/schemes/OneHalfDark.itermcolors b/src/tools/ColorTool/schemes/OneHalfDark.itermcolors similarity index 100% rename from tools/ColorTool/schemes/OneHalfDark.itermcolors rename to src/tools/ColorTool/schemes/OneHalfDark.itermcolors diff --git a/tools/ColorTool/schemes/OneHalfLight.itermcolors b/src/tools/ColorTool/schemes/OneHalfLight.itermcolors similarity index 100% rename from tools/ColorTool/schemes/OneHalfLight.itermcolors rename to src/tools/ColorTool/schemes/OneHalfLight.itermcolors diff --git a/tools/ColorTool/schemes/campbell-legacy.ini b/src/tools/ColorTool/schemes/campbell-legacy.ini similarity index 100% rename from tools/ColorTool/schemes/campbell-legacy.ini rename to src/tools/ColorTool/schemes/campbell-legacy.ini diff --git a/tools/ColorTool/schemes/campbell.ini b/src/tools/ColorTool/schemes/campbell.ini similarity index 100% rename from tools/ColorTool/schemes/campbell.ini rename to src/tools/ColorTool/schemes/campbell.ini diff --git a/tools/ColorTool/schemes/cmd-legacy.ini b/src/tools/ColorTool/schemes/cmd-legacy.ini similarity index 100% rename from tools/ColorTool/schemes/cmd-legacy.ini rename to src/tools/ColorTool/schemes/cmd-legacy.ini diff --git a/tools/ColorTool/schemes/deuteranopia.itermcolors b/src/tools/ColorTool/schemes/deuteranopia.itermcolors similarity index 100% rename from tools/ColorTool/schemes/deuteranopia.itermcolors rename to src/tools/ColorTool/schemes/deuteranopia.itermcolors diff --git a/tools/ColorTool/schemes/solarized_dark.itermcolors b/src/tools/ColorTool/schemes/solarized_dark.itermcolors similarity index 100% rename from tools/ColorTool/schemes/solarized_dark.itermcolors rename to src/tools/ColorTool/schemes/solarized_dark.itermcolors diff --git a/tools/ColorTool/schemes/solarized_light.itermcolors b/src/tools/ColorTool/schemes/solarized_light.itermcolors similarity index 100% rename from tools/ColorTool/schemes/solarized_light.itermcolors rename to src/tools/ColorTool/schemes/solarized_light.itermcolors diff --git a/tools/ColorTool/signing/CopySignFiles.cmd b/src/tools/ColorTool/signing/CopySignFiles.cmd similarity index 100% rename from tools/ColorTool/signing/CopySignFiles.cmd rename to src/tools/ColorTool/signing/CopySignFiles.cmd diff --git a/tools/ColorTool/signing/SignConfig.xml b/src/tools/ColorTool/signing/SignConfig.xml similarity index 100% rename from tools/ColorTool/signing/SignConfig.xml rename to src/tools/ColorTool/signing/SignConfig.xml From 00bb050826ce15c092b915c3de24c263ce5dc031 Mon Sep 17 00:00:00 2001 From: "Dustin L. Howett (MSFT)" Date: Tue, 30 Apr 2019 12:27:12 -0700 Subject: [PATCH 89/89] cleanup: move ISSUE_TEMPLATE to .github/ (#423) --- ISSUE_TEMPLATE.md => .github/ISSUE_TEMPLATE.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename ISSUE_TEMPLATE.md => .github/ISSUE_TEMPLATE.md (100%) diff --git a/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md similarity index 100% rename from ISSUE_TEMPLATE.md rename to .github/ISSUE_TEMPLATE.md