From fe7e10a130c23bb95f755ee53e489c4bbdac9bb6 Mon Sep 17 00:00:00 2001 From: tznind Date: Sun, 6 Oct 2024 19:00:07 +0100 Subject: [PATCH] Get sixel resolution using CSI 16 t --- .../ConsoleDrivers/EscSeqUtils/EscSeqUtils.cs | 6 ++ Terminal.Gui/Drawing/SixelSupportDetector.cs | 65 ++++++++++++++----- 2 files changed, 53 insertions(+), 18 deletions(-) diff --git a/Terminal.Gui/ConsoleDrivers/EscSeqUtils/EscSeqUtils.cs b/Terminal.Gui/ConsoleDrivers/EscSeqUtils/EscSeqUtils.cs index 1eb63e34a..8bd970966 100644 --- a/Terminal.Gui/ConsoleDrivers/EscSeqUtils/EscSeqUtils.cs +++ b/Terminal.Gui/ConsoleDrivers/EscSeqUtils/EscSeqUtils.cs @@ -1356,6 +1356,12 @@ public static class EscSeqUtils /// public const string CSI_ReportDeviceAttributes_Terminator = "c"; + /// + /// CSI 16 t - Request sixel resolution (width and height in pixels) + /// + public static readonly AnsiEscapeSequenceRequest CSI_RequestSixelResolution = new () { Request = CSI + "16t", Terminator = "t" }; + + /// /// CSI 1 8 t | yes | yes | yes | report window size in chars /// https://terminalguide.namepad.de/seq/csi_st-18/ diff --git a/Terminal.Gui/Drawing/SixelSupportDetector.cs b/Terminal.Gui/Drawing/SixelSupportDetector.cs index 16d933afd..295dcd4ba 100644 --- a/Terminal.Gui/Drawing/SixelSupportDetector.cs +++ b/Terminal.Gui/Drawing/SixelSupportDetector.cs @@ -1,45 +1,74 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +using System.Text.RegularExpressions; +using Microsoft.CodeAnalysis; namespace Terminal.Gui; /// -/// Uses ANSII escape sequences to detect whether sixel is supported -/// by the terminal. +/// Uses ANSII escape sequences to detect whether sixel is supported +/// by the terminal. /// public class SixelSupportDetector { public SixelSupport Detect () { - var darResponse = AnsiEscapeSequenceRequest.ExecuteAnsiRequest (EscSeqUtils.CSI_SendDeviceAttributes); var result = new SixelSupport (); - result.IsSupported = darResponse.Response.Split (';').Contains ("4"); + + result.IsSupported = + AnsiEscapeSequenceRequest.TryExecuteAnsiRequest (EscSeqUtils.CSI_SendDeviceAttributes, out AnsiEscapeSequenceResponse darResponse) + ? darResponse.Response.Split (';').Contains ("4") + : false; + + if (result.IsSupported) + { + // Expect something like: + //[6;20;10t + + bool gotResolutionDirectly = false; + + if (AnsiEscapeSequenceRequest.TryExecuteAnsiRequest (EscSeqUtils.CSI_RequestSixelResolution, out var resolution)) + { + // Terminal supports directly responding with resolution + var match = Regex.Match (resolution.Response, @"\[\d+;(\d+);(\d+)t$"); + + if (match.Success) + { + if (int.TryParse (match.Groups [1].Value, out var ry) && + int.TryParse (match.Groups [2].Value, out var rx)) + { + result.Resolution = new Size (rx, ry); + gotResolutionDirectly = true; + } + } + } + + + if (!gotResolutionDirectly) + { + // TODO: Try pixel/window resolution getting + } + } return result; } } - public class SixelSupport { /// - /// Whether the current driver supports sixel graphic format. - /// Defaults to false. + /// Whether the current driver supports sixel graphic format. + /// Defaults to false. /// public bool IsSupported { get; set; } /// - /// The number of pixels of sixel that corresponds to each Col () - /// and each Row (. Defaults to 10x20. + /// The number of pixels of sixel that corresponds to each Col () + /// and each Row (. Defaults to 10x20. /// - public Size Resolution { get; set; } = new Size (10, 20); + public Size Resolution { get; set; } = new (10, 20); /// - /// The maximum number of colors that can be included in a sixel image. Defaults - /// to 256. + /// The maximum number of colors that can be included in a sixel image. Defaults + /// to 256. /// public int MaxPaletteColors { get; set; } = 256; -} \ No newline at end of file +}