Procházet zdrojové kódy

Get sixel resolution using CSI 16 t

tznind před 10 měsíci
rodič
revize
fe7e10a130

+ 6 - 0
Terminal.Gui/ConsoleDrivers/EscSeqUtils/EscSeqUtils.cs

@@ -1356,6 +1356,12 @@ public static class EscSeqUtils
     /// </summary>
     public const string CSI_ReportDeviceAttributes_Terminator = "c";
 
+    /// <summary>
+    ///     CSI 16 t - Request sixel resolution (width and height in pixels)
+    /// </summary>
+    public static readonly AnsiEscapeSequenceRequest CSI_RequestSixelResolution = new () { Request = CSI + "16t", Terminator = "t" };
+
+
     /// <summary>
     ///     CSI 1 8 t  | yes | yes |  yes  | report window size in chars
     ///     https://terminalguide.namepad.de/seq/csi_st-18/

+ 47 - 18
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;
 
 /// <summary>
-/// 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.
 /// </summary>
 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:
+            //<esc>[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
 {
     /// <summary>
-    /// Whether the current driver supports sixel graphic format.
-    /// Defaults to false.
+    ///     Whether the current driver supports sixel graphic format.
+    ///     Defaults to false.
     /// </summary>
     public bool IsSupported { get; set; }
 
     /// <summary>
-    /// The number of pixels of sixel that corresponds to each Col (<see cref="Size.Width"/>)
-    /// and each Row (<see cref="Size.Height"/>.  Defaults to 10x20.
+    ///     The number of pixels of sixel that corresponds to each Col (<see cref="Size.Width"/>)
+    ///     and each Row (<see cref="Size.Height"/>.  Defaults to 10x20.
     /// </summary>
-    public Size Resolution { get; set; } = new Size (10, 20);
+    public Size Resolution { get; set; } = new (10, 20);
 
     /// <summary>
-    /// 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.
     /// </summary>
     public int MaxPaletteColors { get; set; } = 256;
-}
+}