Get sixel resolution using CSI 16 t

This commit is contained in:
tznind
2024-10-06 19:00:07 +01:00
parent ffe8969b50
commit fe7e10a130
2 changed files with 53 additions and 18 deletions

View File

@@ -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/

View File

@@ -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;
}
}