SixelSupportDetector.cs 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. using System.Text.RegularExpressions;
  2. using Microsoft.CodeAnalysis;
  3. namespace Terminal.Gui;
  4. /// <summary>
  5. /// Uses ANSII escape sequences to detect whether sixel is supported
  6. /// by the terminal.
  7. /// </summary>
  8. public class SixelSupportDetector
  9. {
  10. public SixelSupport Detect ()
  11. {
  12. var result = new SixelSupport ();
  13. result.IsSupported =
  14. AnsiEscapeSequenceRequest.TryExecuteAnsiRequest (EscSeqUtils.CSI_SendDeviceAttributes, out AnsiEscapeSequenceResponse darResponse)
  15. ? darResponse.Response.Split (';').Contains ("4")
  16. : false;
  17. if (result.IsSupported)
  18. {
  19. // Expect something like:
  20. //<esc>[6;20;10t
  21. bool gotResolutionDirectly = false;
  22. if (AnsiEscapeSequenceRequest.TryExecuteAnsiRequest (EscSeqUtils.CSI_RequestSixelResolution, out var resolution))
  23. {
  24. // Terminal supports directly responding with resolution
  25. var match = Regex.Match (resolution.Response, @"\[\d+;(\d+);(\d+)t$");
  26. if (match.Success)
  27. {
  28. if (int.TryParse (match.Groups [1].Value, out var ry) &&
  29. int.TryParse (match.Groups [2].Value, out var rx))
  30. {
  31. result.Resolution = new Size (rx, ry);
  32. gotResolutionDirectly = true;
  33. }
  34. }
  35. }
  36. if (!gotResolutionDirectly)
  37. {
  38. // TODO: Try pixel/window resolution getting
  39. }
  40. }
  41. return result;
  42. }
  43. }
  44. public class SixelSupport
  45. {
  46. /// <summary>
  47. /// Whether the current driver supports sixel graphic format.
  48. /// Defaults to false.
  49. /// </summary>
  50. public bool IsSupported { get; set; }
  51. /// <summary>
  52. /// The number of pixels of sixel that corresponds to each Col (<see cref="Size.Width"/>)
  53. /// and each Row (<see cref="Size.Height"/>. Defaults to 10x20.
  54. /// </summary>
  55. public Size Resolution { get; set; } = new (10, 20);
  56. /// <summary>
  57. /// The maximum number of colors that can be included in a sixel image. Defaults
  58. /// to 256.
  59. /// </summary>
  60. public int MaxPaletteColors { get; set; } = 256;
  61. }