From 85dcd194cbd0cfc12c67a62cdc7df01b74218fc2 Mon Sep 17 00:00:00 2001 From: Terry MacDonald Date: Tue, 28 Jun 2022 20:40:33 +1200 Subject: [PATCH] Updated to v1.8.3 Also patched a Windows DPIS Scaling fault. --- AMDInfo/CCD.cs | 18 ++++++++++++++- AMDInfo/Program.cs | 4 ++-- AMDInfo/Properties/AssemblyInfo.cs | 4 ++-- AMDInfo/WinLibrary.cs | 37 ++++++++++++++++++++++++++---- 4 files changed, 53 insertions(+), 10 deletions(-) diff --git a/AMDInfo/CCD.cs b/AMDInfo/CCD.cs index fcc67f7..4f3ab7a 100644 --- a/AMDInfo/CCD.cs +++ b/AMDInfo/CCD.cs @@ -19,6 +19,16 @@ public enum WIN32STATUS : UInt32 ERROR_BAD_CONFIGURATION = 1610, } + public enum DPI_AWARENESS_CONTEXT : Int32 + { + DPI_AWARENESS_CONTEXT_UNDEFINED = 0, + DPI_AWARENESS_CONTEXT_UNAWARE = -1, //' DPI unaware. This window does not scale for DPI changes and is always assumed to have a scale factor of 100% (96 DPI). It will be automatically scaled by the system on any other DPI setting. + DPI_AWARENESS_CONTEXT_SYSTEM_AWARE = -2, //' System DPI aware. This window does not scale for DPI changes. It will query for the DPI once and use that value for the lifetime of the process. If the DPI changes, the process will not adjust to the new DPI value. It will be automatically scaled up or down by the system when the DPI changes from the system value. + DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE = -3, // ' Per monitor DPI aware. This window checks for the DPI when it is created and adjusts the scale factor whenever the DPI changes. These processes are not automatically scaled by the system. + DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 = -4, //' Also known as Per Monitor v2. An advancement over the original per-monitor DPI awareness mode, which enables applications to access new DPI-related scaling behaviors on a per top-level window basis. + DPI_AWARENESS_CONTEXT_UNAWARE_GDISCALED = -5, //' DPI unaware with improved quality of GDI-based content. This mode behaves similarly to DPI_AWARENESS_CONTEXT_UNAWARE, but also enables the system to automatically improve the rendering quality of text and other GDI-based primitives when the window is displayed on a high-DPI monitor. + }; + public enum DISPLAYCONFIG_DEVICE_INFO_TYPE : Int32 { // MS Private API (which seems to use negative numbers) @@ -1095,7 +1105,7 @@ class CCDImport // Set some useful constants public const SDC SDC_CCD_TEST_IF_VALID = (SDC.SDC_VALIDATE | SDC.SDC_USE_SUPPLIED_DISPLAY_CONFIG); public const uint DISPLAYCONFIG_PATH_MODE_IDX_INVALID = 0xffffffff; - public static readonly UInt32[] DPI_VALUES = { 100, 125, 150, 175, 200, 225, 250, 300, 350, 400, 450, 500 }; + //public static readonly UInt32[] DPI_VALUES = { 100, 125, 150, 175, 200, 225, 250, 300, 350, 400, 450, 500 }; // GetDisplayConfigBufferSizes @@ -1167,5 +1177,11 @@ class CCDImport // SetDisplayConfig [DllImport("user32")] public static extern WIN32STATUS SetDisplayConfig([In] uint numPathArrayElements, [In] DISPLAYCONFIG_PATH_INFO[] pathArray, [In] uint numModeInfoArrayElements, [In] DISPLAYCONFIG_MODE_INFO[] modeInfoArray, [In] SDC flags); + + [DllImport("user32")] + public static extern bool SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT value); + + + } } \ No newline at end of file diff --git a/AMDInfo/Program.cs b/AMDInfo/Program.cs index 88e9e07..7e4bf44 100644 --- a/AMDInfo/Program.cs +++ b/AMDInfo/Program.cs @@ -52,10 +52,10 @@ static void Main(string[] args) NLog.LogManager.Configuration = config; // Start the Log file - SharedLogger.logger.Info($"AMDInfo/Main: Starting AMDInfo v1.8.1"); + SharedLogger.logger.Info($"AMDInfo/Main: Starting AMDInfo v1.8.3"); - Console.WriteLine($"\nAMDInfo v1.8.1"); + Console.WriteLine($"\nAMDInfo v1.8.3"); Console.WriteLine($"=============="); Console.WriteLine($"By Terry MacDonald 2022\n"); diff --git a/AMDInfo/Properties/AssemblyInfo.cs b/AMDInfo/Properties/AssemblyInfo.cs index f9fd2a8..28c3fac 100644 --- a/AMDInfo/Properties/AssemblyInfo.cs +++ b/AMDInfo/Properties/AssemblyInfo.cs @@ -32,5 +32,5 @@ // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.8.1.0")] -[assembly: AssemblyFileVersion("1.8.1.0")] +[assembly: AssemblyVersion("1.8.3.0")] +[assembly: AssemblyFileVersion("1.8.3.0")] diff --git a/AMDInfo/WinLibrary.cs b/AMDInfo/WinLibrary.cs index 5b1ac85..40feb1d 100644 --- a/AMDInfo/WinLibrary.cs +++ b/AMDInfo/WinLibrary.cs @@ -169,6 +169,10 @@ public WinLibrary() SharedLogger.logger.Trace("WinLibrary/WinLibrary: Intialising Windows CCD library interface"); _initialised = true; + + // Set the DPI awareness for the process this thread is running within so that the DPI calls return the right values at the right times + CCDImport.SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT.DPI_AWARENESS_CONTEXT_UNAWARE_GDISCALED); + _activeDisplayConfig = GetActiveConfig(); _allConnectedDisplayIdentifiers = GetAllConnectedDisplayIdentifiers(); } @@ -564,9 +568,13 @@ private WINDOWS_DISPLAY_CONFIG GetWindowsDisplayConfig(QDC selector = QDC.QDC_ON } } - // Now cycle through the paths and grab the HDR state information + // Now cycle through the paths and grab the state information we need // and map the adapter name to adapter id // and populate the display source information + + // Set the DPI awareness for the process this thread is running within so that the DPI calls return the right values + CCDImport.SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT.DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2); + List targetPathIdsToChange = new List(); List targetModeIdsToChange = new List(); List targetIdsFound = new List(); @@ -574,6 +582,19 @@ private WINDOWS_DISPLAY_CONFIG GetWindowsDisplayConfig(QDC selector = QDC.QDC_ON bool isClonedProfile = false; for (int i = 0; i < paths.Length; i++) { + + if (selector == QDC.QDC_ONLY_ACTIVE_PATHS && paths[i].TargetInfo.TargetInUse == false) + { + SharedLogger.logger.Trace($"WinLibrary/GetWindowsDisplayConfig: Skipping display target {paths[i].TargetInfo.Id} as we only want displays currently in use"); + continue; + } + + if (selector == QDC.QDC_ALL_PATHS && paths[i].TargetInfo.TargetAvailable == false) + { + SharedLogger.logger.Trace($"WinLibrary/GetWindowsDisplayConfig: Skipping display target {paths[i].TargetInfo.Id} as we want all available displays and this one isn't available"); + continue; + } + //bool gotSourceDeviceName = false; //bool gotAdapterName = false; bool gotAdvancedColorInfo = false; @@ -603,12 +624,13 @@ private WINDOWS_DISPLAY_CONFIG GetWindowsDisplayConfig(QDC selector = QDC.QDC_ON err = CCDImport.DisplayConfigGetDeviceInfo(ref displayScalingInfo); if (err == WIN32STATUS.ERROR_SUCCESS) { - SharedLogger.logger.Trace($"WinLibrary/GetWindowsDisplayConfig: Found DPI value for source {paths[i].SourceInfo.Id} is {CCDImport.DPI_VALUES[displayScalingInfo.CurrrentScaleRel]}%."); + SharedLogger.logger.Trace($"WinLibrary/GetWindowsDisplayConfig: Found Windows DPI scasling value for source {paths[i].SourceInfo.Id} is {displayScalingInfo.CurrrentScaleRel}."); sourceDpiScalingRel = displayScalingInfo.CurrrentScaleRel; + } else { - SharedLogger.logger.Warn($"WinLibrary/GetWindowsDisplayConfig: WARNING - Unabled to get advanced color settings for display {paths[i].TargetInfo.Id}."); + SharedLogger.logger.Warn($"WinLibrary/GetWindowsDisplayConfig: WARNING - Unabled to get Windows DPI Scaling value for display {paths[i].TargetInfo.Id}."); } @@ -774,6 +796,9 @@ private WINDOWS_DISPLAY_CONFIG GetWindowsDisplayConfig(QDC selector = QDC.QDC_ON } } + // Set the DPI awareness for the process this thread is running within so that the DPI calls return the right values + CCDImport.SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT.DPI_AWARENESS_CONTEXT_UNAWARE_GDISCALED); + // Get all the DisplayAdapters currently in the system // This will be used for windows to translate the adapter details beween reboots windowsDisplayConfig.DisplayAdapters = GetAllAdapterIDs(); @@ -1510,6 +1535,7 @@ public bool SetActiveConfig(WINDOWS_DISPLAY_CONFIG displayConfig) System.Threading.Thread.Sleep(100); SharedLogger.logger.Trace($"WinLibrary/SetWindowsDisplayConfig: Attempting to set Windows DPI Scaling setting for display sources."); + CCDImport.SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT.DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2); foreach (var displaySourceEntry in displayConfig.DisplaySources) { // We only need to set the source on the first display source @@ -1523,13 +1549,14 @@ public bool SetActiveConfig(WINDOWS_DISPLAY_CONFIG displayConfig) err = CCDImport.DisplayConfigSetDeviceInfo(ref displayScalingInfo); if (err == WIN32STATUS.ERROR_SUCCESS) { - SharedLogger.logger.Trace($"WinLibrary/SetWindowsDisplayConfig: Setting DPI value for source {displaySourceEntry.Value[0].SourceId} to {CCDImport.DPI_VALUES[displayScalingInfo.ScaleRel]}%."); + SharedLogger.logger.Trace($"WinLibrary/SetWindowsDisplayConfig: Setting DPI value for source {displaySourceEntry.Value[0].SourceId} to {displayScalingInfo.ScaleRel}."); } else { - SharedLogger.logger.Warn($"WinLibrary/SetWindowsDisplayConfig: WARNING - Unable to set DPI value for source {displaySourceEntry.Value[0].SourceId} to {CCDImport.DPI_VALUES[displayScalingInfo.ScaleRel]}%."); + SharedLogger.logger.Warn($"WinLibrary/SetWindowsDisplayConfig: WARNING - Unable to set DPI value for source {displaySourceEntry.Value[0].SourceId} to {displayScalingInfo.ScaleRel}."); } } + CCDImport.SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT.DPI_AWARENESS_CONTEXT_UNAWARE_GDISCALED); // NOTE: There is currently no way within Windows CCD API to set the HDR settings to any particular setting