// Copyright (c) Microsoft Corporation // The Microsoft Corporation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. using System; using System.Collections.Generic; using System.Globalization; using PowerDisplay.Common.Drivers; namespace PowerDisplay.Common.Utils { /// /// Unified helper class for parsing monitor feature support from VCP capabilities. /// This eliminates duplicate VCP parsing logic across PowerDisplay.exe and Settings.UI. /// public static class MonitorFeatureHelper { /// /// Result of parsing monitor feature support from VCP capabilities /// public readonly struct FeatureSupportResult { public bool SupportsBrightness { get; init; } public bool SupportsContrast { get; init; } public bool SupportsColorTemperature { get; init; } public bool SupportsVolume { get; init; } public string CapabilitiesStatus { get; init; } public static FeatureSupportResult Unavailable => new() { SupportsBrightness = false, SupportsContrast = false, SupportsColorTemperature = false, SupportsVolume = false, CapabilitiesStatus = "unavailable", }; } /// /// Parse feature support from a list of VCP code strings. /// This is the single source of truth for determining monitor capabilities. /// /// List of VCP codes as strings (e.g., "0x10", "10", "0x12") /// Raw capabilities string, used to determine availability status /// Feature support result public static FeatureSupportResult ParseFeatureSupport(IReadOnlyList? vcpCodes, string? capabilitiesRaw) { // Check capabilities availability if (string.IsNullOrEmpty(capabilitiesRaw)) { return FeatureSupportResult.Unavailable; } // Convert all VCP codes to integers for comparison var vcpCodeInts = ParseVcpCodesToIntegers(vcpCodes); // Determine feature support based on VCP codes return new FeatureSupportResult { SupportsBrightness = vcpCodeInts.Contains(NativeConstants.VcpCodeBrightness), SupportsContrast = vcpCodeInts.Contains(NativeConstants.VcpCodeContrast), SupportsColorTemperature = vcpCodeInts.Contains(NativeConstants.VcpCodeSelectColorPreset), SupportsVolume = vcpCodeInts.Contains(NativeConstants.VcpCodeVolume), CapabilitiesStatus = "available", }; } /// /// Parse VCP codes from string list to integer set /// Handles both hex formats: "0x10" and "10" /// private static HashSet ParseVcpCodesToIntegers(IReadOnlyList? vcpCodes) { var result = new HashSet(); if (vcpCodes == null) { return result; } foreach (var code in vcpCodes) { if (string.IsNullOrWhiteSpace(code)) { continue; } // Remove "0x" prefix if present and parse as hex var cleanCode = code.Trim(); if (cleanCode.StartsWith("0x", StringComparison.OrdinalIgnoreCase)) { cleanCode = cleanCode.Substring(2); } if (int.TryParse(cleanCode, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out int codeInt)) { result.Add(codeInt); } } return result; } } }