Skip to content

Commit 0ef6896

Browse files
committed
fix(Core): trim Linux OpenGL info from NVIDIA Driver Version
1 parent 352e369 commit 0ef6896

1 file changed

Lines changed: 73 additions & 28 deletions

File tree

SnapX.Core/Utils/OsInfo.cs

Lines changed: 73 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
using System.Runtime.InteropServices;
44
using System.Runtime.Versioning;
55
using System.Text.RegularExpressions;
6+
using SixLabors.ImageSharp;
67
#if WINDOWS
78
using SnapX.Core.Utils.Native;
89
using Windows.Win32.System.SystemInformation;
@@ -16,25 +17,26 @@ namespace SnapX.Core.Utils;
1617

1718
public static partial class OsInfo
1819
{
20+
#if WINDOWS
1921
public record WindowsGpuInfo(string Description, string DriverVersion);
20-
public record WindowsMonitorInfo(string Name, string Position, string Resolution);
22+
public record WindowsMonitorInfo(string Name, Point Position, string Resolution);
2123
public record WindowsGraphicsInfo(List<WindowsGpuInfo> Gpus, List<WindowsMonitorInfo> Monitors);
22-
24+
#endif
2325
public record LinuxGpuInfo(string Description, string Vendor, string DriverVersion);
24-
public record LinuxMonitorInfo(string Name, string Resolution, string Coordinates);
26+
public record LinuxMonitorInfo(string Name, string Resolution, Point Coordinates);
2527
public record LinuxGraphicsInfo(List<LinuxGpuInfo>? Gpus, List<LinuxMonitorInfo> Monitors);
2628

2729
public record MacOSGraphicsInfo(string GpuChipset, string GpuDriverVersion, string MonitorResolution);
2830
public record GenericGpuInfo(string Description, string DriverVersion, string? Vendor = null);
29-
public record GenericMonitorInfo(string Name, string Resolution, string? Position = null)
31+
public record GenericMonitorInfo(string Name, string Resolution, Point? Position = null)
3032
{
3133
public override string ToString() =>
3234
Position is not null
3335
? $"{Name} [{Resolution} @ {Position}]"
3436
: $"{Name} [{Resolution}]";
3537
}
3638
public record GenericGraphicsInfo(List<GenericGpuInfo>? Gpus, List<GenericMonitorInfo>? Monitors, string OperatingSystemName, string? ErrorMessage = null);
37-
39+
#if WINDOWS
3840
private static readonly Dictionary<string, string> BuildToFriendlyName = new()
3941
{
4042
// Windows 11
@@ -61,6 +63,7 @@ public record GenericGraphicsInfo(List<GenericGpuInfo>? Gpus, List<GenericMonito
6163
{ "19044", "21H2" },
6264
{ "19045", "22H2" }
6365
};
66+
#endif
6467
public static string GetFancyOSNameAndVersion()
6568
{
6669
if (OperatingSystem.IsWindows()) return GetWindowsVersion();
@@ -218,7 +221,7 @@ private static string GetProcessorNameLinux()
218221
foreach (var line in lines)
219222
{
220223
if (!line.StartsWith("model name")) continue;
221-
var processorName = line[(line.IndexOf(":") + 2)..].Trim();
224+
var processorName = line[(line.IndexOf(':') + 2)..].Trim();
222225
return processorName;
223226
}
224227
}
@@ -294,10 +297,10 @@ public static (long totalMemory, long usedMemory) GetMemoryInfo()
294297

295298
return (0, 0);
296299
}
300+
#if WINDOWS
297301
[SupportedOSPlatform("windows5.1.2600")]
298302
private static (long totalMemory, long usedMemory) GetMemoryInfoWindows()
299303
{
300-
#if WINDOWS
301304
try
302305
{
303306
var status = new MEMORYSTATUSEX
@@ -320,13 +323,11 @@ private static (long totalMemory, long usedMemory) GetMemoryInfoWindows()
320323
{
321324
DebugHelper.WriteException("Error reading memory info on Windows: " + ex.Message);
322325
}
323-
#endif
324326
return (0, 0);
325327
}
326328
[SupportedOSPlatform("windows5.1.2600")]
327329
private static long GetAvailableMemoryWindows()
328330
{
329-
#if WINDOWS
330331
var status = new MEMORYSTATUSEX
331332
{
332333
dwLength = (uint)Marshal.SizeOf(typeof(MEMORYSTATUSEX))
@@ -337,9 +338,9 @@ private static long GetAvailableMemoryWindows()
337338
return (long)status.ullAvailPhys;
338339
}
339340
DebugHelper.WriteException(new Exception("Unable to retrieve memory information."));
340-
#endif
341341
return -1;
342342
}
343+
#endif
343344
[SupportedOSPlatform("linux")]
344345
private static (long totalMemory, long usedMemory) GetMemoryInfoLinux()
345346
{
@@ -501,13 +502,17 @@ public static GenericGraphicsInfo GetGenericGraphicsInfo()
501502
{
502503
if (OperatingSystem.IsWindows())
503504
{
505+
#if WINDOWS
504506
var windowsInfo = GetGraphicsInfoWindows();
505507
if (windowsInfo == null)
506508
return new GenericGraphicsInfo([], [], "Windows",
507509
"Error retrieving Windows graphics info.");
508510
var genericGpus = windowsInfo.Gpus.Select(g => new GenericGpuInfo(g.Description, g.DriverVersion)).ToList();
509511
var genericMonitors = windowsInfo.Monitors.Select(m => new GenericMonitorInfo(m.Name, m.Resolution, m.Position)).ToList();
510512
return new GenericGraphicsInfo(genericGpus, genericMonitors, "Windows");
513+
#else
514+
return new GenericGraphicsInfo([], [], "Windows", "Compilation error for Windows specific code not being included??");
515+
#endif
511516
}
512517
else
513518
{
@@ -546,10 +551,10 @@ public static GenericGraphicsInfo GetGenericGraphicsInfo()
546551
return new GenericGraphicsInfo(genericGpusmacOS, genericMonitors, "macOS");
547552
}
548553
}
554+
#if WINDOWS
549555
[SupportedOSPlatform("windows")]
550556
public static WindowsGraphicsInfo? GetGraphicsInfoWindows()
551557
{
552-
#if WINDOWS
553558
try
554559
{
555560
const string gpuCommand = """
@@ -610,22 +615,63 @@ public static GenericGraphicsInfo GetGenericGraphicsInfo()
610615
{
611616
return null;
612617
}
613-
#else
614-
return null;
615-
#endif
616618
}
617619
private static List<WindowsGpuInfo> ParseWindowsGpuInfo(string rawOutput)
618620
{
619621
var lines = rawOutput.Trim().Split(Environment.NewLine, StringSplitOptions.RemoveEmptyEntries);
620622
var regex = WindowsGPUInfoRegex();
621623
return (from line in lines select line.Trim() into trimmedLine select regex.Match(trimmedLine) into match where match.Success let name = match.Groups[1].Value.Trim() let driver = match.Groups[2].Value.Trim() select new WindowsGpuInfo(name, driver)).ToList();
622624
}
623-
624625
private static List<WindowsMonitorInfo> ParseWindowsMonitorInfo(string rawOutput)
625626
{
626627
var lines = rawOutput.Split(Environment.NewLine, StringSplitOptions.RemoveEmptyEntries);
627-
return (from line in lines where line.StartsWith("Monitor:") select line["Monitor: ".Length..].Split([", Position: ", ", Resolution: "], StringSplitOptions.RemoveEmptyEntries) into parts where parts.Length == 3 let name = parts[0] let positionPart = parts[1] let resolutionPart = parts[2] select new WindowsMonitorInfo(name, positionPart, resolutionPart)).ToList();
628+
return (from line in lines where line.StartsWith("Monitor:") select line["Monitor: ".Length..].Split([", Position: ", ", Resolution: "], StringSplitOptions.RemoveEmptyEntries) into parts where parts.Length == 3 let name = parts[0] let positionPart = parts[1] let resolutionPart = parts[2] select new WindowsMonitorInfo(name, ParsePosition(positionPart), resolutionPart)).ToList();
629+
}
630+
public static Point ParsePosition(string position)
631+
{
632+
if (string.IsNullOrWhiteSpace(position))
633+
return new Point(0, 0);
634+
635+
try
636+
{
637+
// Remove surrounding parentheses if present
638+
position = position.Trim();
639+
if (position.StartsWith("(") && position.EndsWith(")"))
640+
{
641+
position = position.Substring(1, position.Length - 2).Trim();
642+
}
643+
644+
// Expected format after trimming: "X: 0, Y: 0"
645+
var parts = position.Split(',');
646+
int x = 0, y = 0;
647+
648+
foreach (var part in parts)
649+
{
650+
var kv = part.Split(':');
651+
if (kv.Length != 2) continue;
652+
653+
var key = kv[0].Trim().ToUpperInvariant();
654+
var value = int.Parse(kv[1].Trim());
655+
656+
switch (key)
657+
{
658+
case "X":
659+
x = value;
660+
break;
661+
case "Y":
662+
y = value;
663+
break;
664+
}
665+
}
666+
667+
return new Point(x, y);
668+
}
669+
catch
670+
{
671+
return new Point(0, 0); // fallback if parsing fails
672+
}
628673
}
674+
#endif
629675
public static LinuxGraphicsInfo? GetGraphicsInfoLinux()
630676
{
631677
try
@@ -658,9 +704,9 @@ private static List<WindowsMonitorInfo> ParseWindowsMonitorInfo(string rawOutput
658704
var glxLines = glxInfo.Split(Environment.NewLine, StringSplitOptions.RemoveEmptyEntries);
659705
if (string.IsNullOrWhiteSpace(driverVersion))
660706
{
661-
driverVersion = glxLines.FirstOrDefault(line => line.Contains("OpenGL version"))?.Split(':')[1]?.Trim();
707+
driverVersion = glxLines.FirstOrDefault(glxLine => glxLine.Contains("OpenGL version"))?.Split(':')[1]?.Trim();
662708
var mesaRegex = MesaRegex();
663-
var versionLine = glxLines.FirstOrDefault(line => line.Contains("OpenGL version"));
709+
var versionLine = glxLines.FirstOrDefault(glxLine => glxLine.Contains("OpenGL version"));
664710
var mesaMatch = mesaRegex.Match(versionLine ?? string.Empty);
665711
if (mesaMatch.Success)
666712
driverVersion = mesaMatch.Value;
@@ -669,6 +715,10 @@ private static List<WindowsMonitorInfo> ParseWindowsMonitorInfo(string rawOutput
669715
{
670716
driverVersion = $"Kernel {kernelVersion} {driverVersion}";
671717
}
718+
else if (driverVersion?.Contains("NVIDIA", StringComparison.InvariantCultureIgnoreCase) ?? false)
719+
{
720+
driverVersion = driverVersion?.Split(' ').Last();
721+
}
672722
}
673723
var vendor = glxLines.FirstOrDefault(line => line.Contains("OpenGL vendor string"))?.Split(':')[1]?.Trim();
674724
gpuInfoList.Add(new LinuxGpuInfo(gpu, vendor, driverVersion));
@@ -700,11 +750,10 @@ private static List<WindowsMonitorInfo> ParseWindowsMonitorInfo(string rawOutput
700750
}
701751

702752
var coordinateParts = resolutionAndCoords.Split('+');
703-
var x = coordinateParts.Length > 1 ? coordinateParts[1] : string.Empty;
704-
var y = coordinateParts.Length > 2 ? coordinateParts[2] : string.Empty;
705-
var coordinates = $"({x}, {y})";
753+
var x = int.Parse(coordinateParts.Length > 1 ? coordinateParts[1] : string.Empty);
754+
var y = int.Parse(coordinateParts.Length > 2 ? coordinateParts[2] : string.Empty);
706755

707-
monitors.Add(new LinuxMonitorInfo(monitorName, resolution, coordinates));
756+
monitors.Add(new LinuxMonitorInfo(monitorName, resolution, new Point(x, y)));
708757
}
709758
}
710759
catch (Exception ex)
@@ -779,7 +828,6 @@ public static bool IsHdrSupported()
779828
// If they're on Linux, they should know they're using things like HDR.
780829
}
781830

782-
[SupportedOSPlatform("linux")]
783831
public static bool IsWSL()
784832
{
785833
if (!OperatingSystem.IsLinux()) return false;
@@ -793,18 +841,15 @@ public static bool IsWSL()
793841
return false;
794842
}
795843
}
844+
#if WINDOWS
796845
[SupportedOSPlatform("windows5.0")]
797846
private static bool CheckWindowsHdr()
798847
{
799-
#if WINDOWS
800848
var hdc = PInvoke.GetDC(new HWND(IntPtr.Zero));
801849
var bpp = PInvoke.GetDeviceCaps(hdc, GET_DEVICE_CAPS_INDEX.BITSPIXEL);
802850
return bpp >= 30;
803-
#else
804-
return false;
805-
#endif
806851
}
807-
852+
#endif
808853
private static bool CheckMacOSHdr()
809854
{
810855
var displayInfo = GetMacOSDisplayInfo();

0 commit comments

Comments
 (0)