diff --git a/src/Linux/Avalonia.LinuxFramebuffer/Output/DrmBindings.cs b/src/Linux/Avalonia.LinuxFramebuffer/Output/DrmBindings.cs index b80976e540..0ecb231b7b 100644 --- a/src/Linux/Avalonia.LinuxFramebuffer/Output/DrmBindings.cs +++ b/src/Linux/Avalonia.LinuxFramebuffer/Output/DrmBindings.cs @@ -2,9 +2,9 @@ using System; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; +using System.Globalization; using System.IO; using System.Runtime.InteropServices; -using System.Text.RegularExpressions; using static Avalonia.LinuxFramebuffer.NativeUnsafeMethods; using static Avalonia.LinuxFramebuffer.Output.LibDrm; @@ -149,23 +149,37 @@ namespace Avalonia.LinuxFramebuffer.Output public unsafe class DrmCard : IDisposable { - public int Fd { get; private set; } + public int Fd { get; private set; } = -1; public DrmCard(string? path = null) { if (path == null) { - var files = Directory.GetFiles("/dev/dri/"); + var files = new SortedDictionary(); + foreach (var file in Directory.GetFiles("/dev/dri/", "card*")) + { + if (int.TryParse(Path.GetFileName(file).AsSpan(4), NumberStyles.None, CultureInfo.InvariantCulture, + out var cardNumber)) + files[cardNumber] = file; + } - foreach (var file in files) + foreach (var file in files.Values) { - var match = Regex.Match(file, "card[0-9]+"); + var fd = open(file, 2, 0); + if (fd == -1) + continue; - if (match.Success) + var resources = drmModeGetResources(fd); + if (resources != null && resources->count_crtcs > 0 && resources->count_encoders > 0 && + resources->count_connectors > 0) { - Fd = open(file, 2, 0); - if (Fd != -1) - break; + drmModeFreeResources(resources); + Fd = fd; + break; } + + if (resources != null) + drmModeFreeResources(resources); + close(fd); } if (Fd == -1) @@ -187,6 +201,8 @@ namespace Avalonia.LinuxFramebuffer.Output public DrmResources GetResources(bool connectorsForceProbe = false) => new DrmResources(Fd, connectorsForceProbe); public void Dispose() { + if (Fd == -1) + return; close(Fd); Fd = -1; }