public void Initialize(bool alreadyActive) { // Console is always considered active on Unix ConsoleActive = true; StdoutRedirected = UnixStreamHelper.isatty(1) != 1; var duplicateStream = UnixStreamHelper.CreateDuplicateStream(1); if (UseMonoTtyDriver && !StdoutRedirected) { // Mono implementation handles xterm for us var writer = ConsoleWriter.CreateConsoleStreamWriter(duplicateStream, Console.Out.Encoding, true); StandardOut = TextWriter.Synchronized(writer); var driver = AccessTools.Field(AccessTools.TypeByName("System.ConsoleDriver"), "driver").GetValue(null); AccessTools.Field(AccessTools.TypeByName("System.TermInfoDriver"), "stdout").SetValue(driver, writer); } else { // Handle TTY ourselves var writer = new StreamWriter(duplicateStream, Console.Out.Encoding); writer.AutoFlush = true; StandardOut = TextWriter.Synchronized(writer); TtyInfo = TtyHandler.GetTtyInfo(); } ConsoleOut = StandardOut; }
public void SetConsoleColor(ConsoleColor color) { if (StdoutRedirected) { return; } if (UseMonoTtyDriver) { // Use mono's inbuilt terminfo driver to set the foreground color for us SafeConsole.ForegroundColor = color; } else { ConsoleOut.Write(TtyInfo.GetAnsiCode(color)); } }
public static TtyInfo Parse(byte[] buffer) { int intSize; int magic = GetInt16(buffer, 0); switch (magic) { case 0x11a: intSize = 2; break; case 0x21E: intSize = 4; break; default: // Unknown ttyinfo format return(TtyInfo.Default); } int boolFieldLength = GetInt16(buffer, 4); int intFieldLength = GetInt16(buffer, 6); int strOffsetFieldLength = GetInt16(buffer, 8); // Normally i'd put a more complete implementation here, but I only need to parse this info to get the max color count // Feel free to implement the rest of this using these sources: // https://github.com/mono/mono/blob/master/mcs/class/corlib/System/TermInfoReader.cs // https://invisible-island.net/ncurses/man/term.5.html // https://invisible-island.net/ncurses/man/terminfo.5.html int baseOffset = 12 + GetString(buffer, 12).Length + 1; // Skip the terminal name baseOffset += boolFieldLength; // Length of bool field section baseOffset += baseOffset % 2; // Correct for boundary int colorOffset = baseOffset + (intSize * (int)TermInfoNumbers.MaxColors); // Finally the offset for the max color integer //int stringOffset = baseOffset + (intSize * intFieldLength); //int foregoundColorOffset = // stringOffset // + (2 * (int)TermInfoStrings.SetAForeground); //foregoundColorOffset = stringOffset // + (2 * strOffsetFieldLength) // + GetInt16(buffer, foregoundColorOffset); var info = new TtyInfo(); info.MaxColors = GetInteger(intSize, buffer, colorOffset); //string setForegroundTemplate = GetString(buffer, foregoundColorOffset); //info.ForegroundColorStrings = ansiColorMapping.Select(x => setForegroundTemplate.Replace("%p1%", x.ToString())).ToArray(); info.ForegroundColorStrings = ansiColorMapping.Select(x => $"\u001B[{(x > 7 ? 82 + x : 30 + x)}m").ToArray(); return(info); }