diff --git a/DisplayMagician/Program.cs b/DisplayMagician/Program.cs index ef86cec..31b0060 100644 --- a/DisplayMagician/Program.cs +++ b/DisplayMagician/Program.cs @@ -602,7 +602,7 @@ namespace DisplayMagician { { Console.WriteLine("Program/ApplyProfile : Applying AMD Profile " + profile.Name); AMDProfileItem amdProfile = (AMDProfileItem)profile; - if (!AMDLibrary.GetLibrary().SetActiveProfile(amdProfile.ProfileData)) + if (!AMDLibrary.GetLibrary().SetActiveConfig(amdProfile.DisplayConfig)) { // Somehow return that this profile topology didn't apply throw new ApplyTopologyException("Program/ApplyProfile: amdApplyProfileTask: Error applying the AMD Profile!"); diff --git a/DisplayMagicianShared/AMD/ADL.cs b/DisplayMagicianShared/AMD/ADL.cs index cd5c8d6..d7897e9 100644 --- a/DisplayMagicianShared/AMD/ADL.cs +++ b/DisplayMagicianShared/AMD/ADL.cs @@ -1,344 +1,121 @@ -#region Copyright - -/******************************************************************************* - Copyright(c) 2008 - 2009 Advanced Micro Devices, Inc. All Rights Reserved. - Copyright (c) 2002 - 2006 ATI Technologies Inc. All Rights Reserved. - - THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF - ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDED BUT NOT LIMITED TO - THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A - PARTICULAR PURPOSE. - - File: ADL.cs - - Purpose: Implements ADL interface - - Description: Implements some of the methods defined in ADL interface. - - ********************************************************************************/ - -#endregion Copyright - -#region Using - using System; -using System.Collections.Generic; -using System.Text; using System.Runtime.InteropServices; -using System.Diagnostics; -using System.Threading; using FARPROC = System.IntPtr; using HMODULE = System.IntPtr; -#endregion Using - -#region ATI.ADL - -namespace ATI.ADL +namespace DisplayMagicianShared.AMD { - #region Export Delegates - /// ADL Memory allocation function allows ADL to callback for memory allocation - /// input size - /// retrun ADL Error Code - public delegate IntPtr ADL_Main_Memory_Alloc (int size); + public delegate IntPtr ADL_Main_Memory_Alloc_Delegate(int size); - // ADL2 version of function delagates + public enum ADL_STATUS + { + // Result Codes + /// ADL function completed successfully. + ADL_OK = 0, + /// Generic Error.Most likely one or more of the Escape calls to the driver failed! + ADL_ERR = -1, + /// Call can't be made due to disabled adapter. + ADL_ERR_DISABLED_ADAPTER = -10, + /// Invalid ADL index passed. + ADL_ERR_INVALID_ADL_IDX = -5, + /// Invalid Callback. + ADL_ERR_INVALID_CALLBACK = -11, + /// Invalid controller index passed. + ADL_ERR_INVALID_CONTROLLER_IDX = -6, + /// Invalid display index passed. + ADL_ERR_INVALID_DISPLAY_IDX = -7, + /// One of the parameter passed is invalid. + ADL_ERR_INVALID_PARAM = -3, + /// One of the parameter size is invalid. + ADL_ERR_INVALID_PARAM_SIZE = -4, + /// There's no Linux XDisplay in Linux Console environment. + ADL_ERR_NO_XDISPLAY = -21, + /// ADL not initialized. + ADL_ERR_NOT_INIT = -2, + /// Function not supported by the driver. + ADL_ERR_NOT_SUPPORTED = -8, + /// Null Pointer error. + ADL_ERR_NULL_POINTER = -9, + /// Display Resource conflict. + ADL_ERR_RESOURCE_CONFLICT = -12, + /// Err Set incomplete + ADL_ERR_SET_INCOMPLETE = -20, + /// All OK but need mode change. + ADL_OK_MODE_CHANGE = 2, + /// All OK, but need restart. + ADL_OK_RESTART = 3, + /// All OK, but need to wait + ADL_OK_WAIT = 4, + /// All OK, but with warning. + ADL_OK_WARNING = 1, + } - /// ADL2 Create Function to create ADL Data - /// Call back functin pointer which is ised to allocate memory - /// If it is 1, then ADL will only retuen the physical exist adapters - /// Handle to ADL client context. - /// retrun ADL Error Code - public delegate int ADL2_Main_Control_Create(ADL_Main_Memory_Alloc callback, int numConnectedAdapters, out IntPtr contextHandle); + public enum ADL_CONNECTION_TYPE + { + VGA = 0, + DVI = 1, + DVI_SL = 2, + HDMI = 4, + DisplayPort = 4, + ActiveDongleDPToDVI_SL = 5, + ActiveDongleDPToDVI_DL = 6, + ActiveDongleDPToHDMI = 7, + ActiveDongleDPToVGA = 8, + PassiveDongleDPToHDMI = 9, + PassiveDongleDPToDVI = 10, + MST = 11, + ActiveDongle = 12, + Virtual = 13 + } - /// ADL2 Destroy Function to free up ADL Data - /// Handle to ADL client context. - /// retrun ADL Error Code - public delegate int ADL2_Main_Control_Destroy(IntPtr contextHandle); + public enum ADL_DISPLAY_CONNECTION_TYPE + { + Unknown = 0, + VGA = 1, + DVI_D = 2, + DVI_I = 3, + HDMI = 4, + ATICV_NTSC_Dongle = 4, + ATICV_JPN_Dongle = 5, + ATICV_NONI2C_NTSC_Dongle = 6, + ATICV_NONI2C_JPN_Dongle = 7, + Proprietary = 8, + HDMITypeA = 10, + HTMITypeB = 11, + SVideo = 12, + Composite = 13, + RCA_3Component = 14, + DisplayPort = 15, + EDP = 16, + WirelessDisplay = 17, + USBTypeC = 18 + } - /// ADL2 Function to get the number of adapters - /// Handle to ADL client context. - /// return number of adapters - public delegate int ADL2_Adapter_NumberOfAdapters_Get(IntPtr ADLContextHandle, ref int numAdapters); + public enum ADL_DISPLAY_MODE_FLAG + { + ColourFormat565 = 1, + ColourFormat8888 = 2, + Degrees0 = 4, + Degrees90 = 8, + Degrees180 = 10, + Degrees270 = 20, + ExactRefreshRate = 80, + RoundedRefreshRate = 40 + } + public enum ADL_DISPLAY_MODE_INTERLACING + { + Progressive = 0, + Interlaced = 2 + } - /// ADL2 Function to save driver configuration so it survives a reboot - /// Handle to ADL client context. - /// Adapter Index to save state. - public delegate int ADL2_Flush_Driver_Data(IntPtr ADLContextHandle, int adapterIndex); - - /// ADL2 Function to determine if the adapter is active or not. - /// The function is used to check if the adapter associated with iAdapterIndex is active - /// Handle to ADL client context. - /// Adapter Index. - /// Status of the adapter. True: Active; False: Disabled - /// Non zero is successful - public delegate int ADL2_Adapter_Active_Get(IntPtr ADLContextHandle, int adapterIndex, ref int status); - - /// ADL2 Function to retrieve adapter capability information. - /// This function implements a DI call to retrieve adapter capability information . - /// Handle to ADL client context. - /// Adapter Index. - /// The pointer to the ADLAdapterCaps structure storing the retrieved adapter capability information. - /// return ADL Error Code - public delegate int ADL2_AdapterX2_Caps(IntPtr ADLContextHandle, int adapterIndex, out ADLAdapterCapsX2 adapterCapabilities); - - - /// ADL2 Function to retrieve all OS-known adapter information. - /// This function retrieves the adapter information of all OS-known adapters in the system. OS-known adapters can include adapters that are physically present in the system (logical adapters) as well as ones that are no longer present in the system but are still recognized by the OS. - /// Handle to ADL client context. - /// return GPU adapter information - /// the size of the GPU adapter struct - /// retrun ADL Error Code - public delegate int ADL2_Adapter_AdapterInfo_Get(IntPtr ADLContextHandle, int inputSize, out IntPtr adapterInfoArray); - - /// ADL2 function retrieves all OS-known adapter information. - /// This function retrieves the adapter information of all OS-known adapters in the system. OS-known adapters can include adapters that are physically present in the system (logical adapters) as well as ones that are no longer present in the system but are still recognized by the OS. - /// Handle to ADL client context. - /// return GPU adapter information. Is a pointer to the pointer of AdapterInfo array. Initialize to NULL before calling this API. ADL will allocate the necessary memory, using the user provided callback function. - /// retrun ADL Error Code - public delegate int ADL2_Adapter_AdapterInfoX2_Get(IntPtr ADLContextHandle, out IntPtr adapterInfoArray); - - /// ADL2 function retrieves all OS-known adapter information. - /// This function retrieves the adapter information of all OS-known adapters in the system. OS-known adapters can include adapters that are physically present in the system (logical adapters) as well as ones that are no longer present in the system but are still recognized by the OS. - /// Handle to ADL client context. - /// The ADL index handle of the desired adapter or -1 if all adapters are desired - /// Number of items in the AdapterInfo Array. Can pass NULL pointer if passign an adapter index (in which case only one AdapterInfo is returned) - /// return GPU adapter information - /// retrun ADL Error Code - public delegate int ADL2_Adapter_AdapterInfoX3_Get(IntPtr ADLContextHandle, int adapterIndex, out int numAdapters, out IntPtr adapterInfoArray); - - /// ADL2 function retrieves all OS-known adapter information. - /// This function retrieves the adapter information of all OS-known adapters in the system. OS-known adapters can include adapters that are physically present in the system (logical adapters) as well as ones that are no longer present in the system but are still recognized by the OS. - /// Handle to ADL client context. - /// The ADL index handle of the desired adapter or -1 if all adapters are desired - /// Number of items in the AdapterInfo Array. Can pass NULL pointer if passign an adapter index (in which case only one AdapterInfo is returned) - /// return GPU adapter information in adapterInfoX2 array - /// retrun ADL Error Code - public delegate int ADL2_Adapter_AdapterInfoX4_Get(IntPtr ADLContextHandle, int adapterIndex, out int numAdapters, out IntPtr adapterInfoX2Array); - - /// ADL2 Create Function to create ADL Data - /// Handle to ADL client context. - /// Adapter Index - /// Display Index - /// The ADLDDCInfo2 structure storing all DDC retrieved from the driver. - /// retrun ADL Error Code - public delegate int ADL2_Display_DDCInfo2_Get(IntPtr ADLContextHandle, int adapterIndex, int displayIndex, out ADLDDCInfo2 displayDDCInfo2); - - /// ADL2 function to get display information based on adapter index - /// Handle to ADL client context. - /// Adapter Index - /// return the total number of supported displays - /// return ADLDisplayInfo Array for supported displays' information - /// force detect or not - /// return ADL Error Code - public delegate int ADL2_Display_DisplayInfo_Get(IntPtr ADLContextHandle, int adapterIndex, ref int numDisplays, out IntPtr displayInfoArray, int forceDetect); - - /// This ADL2 function retrieves HDTV capability settings for a specified display. - /// Handle to ADL client context. - /// Adapter Index - /// Display Index - /// return ADLDisplayConfig with HDTV capability settings in it - /// return ADL Error Code - public delegate int ADL2_Display_DeviceConfig_Get(IntPtr ADLContextHandle, int adapterIndex, int displayIndex, out ADLDisplayConfig displayConfig); - - /// ADL2 function to query whether a display is HDR Supported and Enabled - /// Handle to ADL client context. - /// Adapter Index - /// DisplayID for the desired display - /// return a pointer to the int whose value is set to true if the display supports HDR - /// return a pointer to the int whose value is set to true if HDR is enabled on this display - /// return ADL Error Code - public delegate int ADL2_Display_HDRState_Get(IntPtr ADLContextHandle, int adapterIndex, ADLDisplayID displayID, out int support, out int enable); - - /// ADL2 function to retrieve the current display mode information - /// Handle to ADL client context. - /// Adapter Index - /// Display Index - /// return a pointer to the number of modes retrieved. - /// return a pointer to the array of retrieved ADLMode display modes. - /// return ADL Error Code - public delegate int ADL2_Display_Modes_Get(IntPtr ADLContextHandle, int adapterIndex, int displayIndex, out int numModes, out IntPtr modes); - - /// ADL2 function to set display mode information - /// Handle to ADL client context. - /// Adapter Index - /// Display Index - /// The number of modes to be set. - /// The pointer to the display mode information to be set. Refer to the ADLMode structure for more information. - /// return ADL Error Code - public delegate int ADL2_Display_Modes_Set(IntPtr ADLContextHandle, int adapterIndex, int displayIndex, int numModes, ref ADLMode modes); - - /// ADL2 function to retrieve the current display mode information - /// Handle to ADL client context. - /// Adapter Index - /// The pointer to the number of retrieved display maps - /// The pointer to the pointer to the display manner information. Refer to the ADLDisplayMap structure for more information. - /// The pointer to the display target sets retrieved. - /// The pointer to the pointer to the display target buffer. Refer to the ADLDisplayTarget structure for more information. - /// The function option. ADL_DISPLAY_DISPLAYMAP_OPTION_GPUINFO. - /// return ADL Error Code - public delegate int ADL2_Display_DisplayMapConfig_Get(IntPtr ADLContextHandle, int adapterIndex, out int numDisplayMap, out IntPtr displayMap, out int numDisplayTarget, out IntPtr displayTarget, int options); - - /// ADL2 function to set the current display mode information - /// Handle to ADL client context. - /// Adapter Index - /// The number of display maps to set - /// The pointer to the display manner information. Refer to the ADLDisplayMap structure for more information. - /// The number of display targets to set - /// The pointer to the display target object. Refer to the ADLDisplayTarget structure for more information. - /// return ADL Error Code - public delegate int ADL2_Display_DisplayMapConfig_Set(IntPtr ADLContextHandle, int adapterIndex, int numDisplayMap, ref ADLDisplayMap displayMap, int numDisplayTarget, ref ADLDisplayTarget displayTarget); - - /// ADL2 function to set the current display mode information - /// Handle to ADL client context. - /// Adapter Index - /// The number of possible maps to be validated. - /// The list of possible maps to be validated. Refer to the ADLPossibleMap structure for more information. - /// The pointer to the number of validated result list. - /// The pointer to the pointer to validation result list. Refer to the ADLPossibleMapResult structure for more information. - /// return ADL Error Code - public delegate int ADL2_Display_DisplayMapConfig_Validate(IntPtr ADLContextHandle, int adapterIndex, int numPossibleMap, ref ADLPossibleMap possibleMaps, out int numPossibleMapResult, ref IntPtr possibleMapResult); - - /// ADL2 function to set the current display mode information - /// Handle to ADL client context. - /// Adapter Index - /// The number of display maps to set - /// The pointer to the display manner information. Refer to the ADLDisplayMap structure for more information. - /// The number of display targets to set - /// The pointer to the display target object. Refer to the ADLDisplayTarget structure for more information. - /// The number of display targets that can be added - /// The list of display targets that can be added - /// The number of display targets that can be removed - /// The list of display targets that can be removed - /// return ADL Error Code - public delegate int ADL2_Display_DisplayMapConfig_PossibleAddAndRemove(IntPtr ADLContextHandle, int adapterIndex, int numDisplayMap, ref ADLDisplayMap displayMap, int numDisplayTarget, ref ADLDisplayTarget displayTarget, out int numPossibleAddTarget, out IntPtr possibleAddTarget, out int numPossibleRemoveTarget, out IntPtr possibleRemoveTarget); - - // ADL version of function delegates - - /// ADL Create Function to create ADL Data - /// Call back functin pointer which is ised to allocate memeory - /// If it is 1, then ADL will only retuen the physical exist adapters - /// retrun ADL Error Code - public delegate int ADL_Main_Control_Create(ADL_Main_Memory_Alloc callback, int enumConnectedAdapters); - - /// ADL Destroy Function to free up ADL Data - /// retrun ADL Error Code - public delegate int ADL_Main_Control_Destroy (); - - /// ADL Function to get the number of adapters - /// return number of adapters - /// retrun ADL Error Code - public delegate int ADL_Adapter_NumberOfAdapters_Get (ref int numAdapters); - - /// Function to determine if the adapter is active or not. - /// The function is used to check if the adapter associated with iAdapterIndex is active - /// Adapter Index. - /// Status of the adapter. True: Active; False: Disabled - /// Non zero is successful - public delegate int ADL_Adapter_Active_Get(int adapterIndex, ref int status); - - /// Function to get the unique identifier of an adapter. - /// This function retrieves the unique identifier of a specified adapter. The adapter ID is a unique value and will be used to determine what other controllers share the same adapter. The desktop will use this to find which HDCs are associated with an adapter. - /// Adapter Index. - /// The pointer to the adapter identifier. Zero means: The adapter is not AMD. - /// return ADL Error Code - public delegate int ADL_Adapter_ID_Get(int adapterIndex, ref int adapterId); - - /// Function to retrieve adapter capability information. - /// This function implements a DI call to retrieve adapter capability information . - /// Adapter Index. - /// The pointer to the ADLAdapterCaps structure storing the retrieved adapter capability information. - /// return ADL Error Code - public delegate int ADL_AdapterX2_Caps(int adapterIndex, out ADLAdapterCapsX2 adapterCapabilities); - - /// Retrieves all OS-known adapter information. - /// This function retrieves the adapter information of all OS-known adapters in the system. OS-known adapters can include adapters that are physically present in the system (logical adapters) as well as ones that are no longer present in the system but are still recognized by the OS. - /// return GPU adapter information - /// the size of the GPU adapter struct - /// retrun ADL Error Code - public delegate int ADL_Adapter_AdapterInfo_Get(out IntPtr adapterInfoArray, int inputSize); - - - /// Function to get the EDID data. - /// This function retrieves the EDID data for a specififed display. - /// Adapter Index - /// The desired display index. It can be retrieved from the ADLDisplayInfo data structure. - /// return the ADLDisplayEDIDData structure storing the retrieved EDID data. - /// return ADL Error Code - public delegate int ADL_Display_EdidData_Get(int adapterIndex, int displayIndex, ref ADLDisplayEDIDData EDIDData); - - /// Get display information based on adapter index - /// Adapter Index - /// return the total number of supported displays - /// return ADLDisplayInfo Array for supported displays' information - /// force detect or not - /// return ADL Error Code - public delegate int ADL_Display_DisplayInfo_Get(int adapterIndex, ref int numDisplays, out IntPtr displayInfoArray, int forceDetect); - - /// This function retrieves HDTV capability settings for a specified display. - /// Adapter Index - /// Display Index - /// return ADLDisplayConfig with HDTV capability settings in it - /// return ADL Error Code - public delegate int ADL_Display_DeviceConfig_Get(int adapterIndex, int displayIndex, out ADLDisplayConfig displayConfig); - - /// Function to retrieve current display map configurations. - /// This function retrieves the current display map configurations, including the controllers and adapters mapped to each display. - /// The ADL index handle of the desired adapter. A value of -1 returns all display configurations for the system across multiple GPUs. - /// Number of returned Display Maps - /// Array of ADLDisplayMap objects - /// Number of Display Targets - /// Array of ADLDisplayTarget objects - /// Options supplied - /// return ADL Error Code - public delegate int ADL_Display_DisplayMapConfig_Get(int adapterIndex, out int numDisplayMap, out IntPtr displayMap, out int numDisplayTarget, out IntPtr displayTarget, int options); - - /// Function to validate a list of display configurations. - /// This function allows the user to input a potential displays map and its targets. The function can also be used to obtain a list of display targets that can be added to this given topology and a list of display targets that can be removed from this given topology. - /// The ADL index handle of the desired adapter. Cannot be set to -1 - /// Number of Display Map - /// Number of Display Map - /// Number of Display Map - /// Number of Display Map - /// Number of Display Map - /// Number of Display Map - /// Number of Display Map - /// Number of Display Map - /// return ADL Error Code - public delegate int ADL_Display_DisplayMapConfig_PossibleAddAndRemove(int adapterIndex, int numDisplayMap, ADLDisplayMap displayMap, int numDisplayTarget, ADLDisplayTarget displayTarget, out int numPossibleAddTarget, out IntPtr possibleAddTarget, out int numPossibleRemoveTarget, out IntPtr possibleRemoveTarget); - - /// Function to retrieve an SLS configuration. - /// Adapter Index - /// Specifies the SLS map index to be queried. - /// return ADLSLSMap Array for supported displays' information - /// return number of targets in the SLS mapo - /// return ADLSLSTarget Array - /// return the number of native modes - /// return ADLSLSMode Array that contains the native modes - /// return the number of bezel modes - /// return ADLSLSMode Array that contains the bezel modes - /// return the number of transient modes - /// return ADLSLSMode Array that contains the transient modes - /// return the number of SLS offsets - /// return ADLSLSOffset Array that contains the SLS offsets - /// Specifies the layout type of SLS grid data. It is bit vector. There are two types of SLS layout:s, relative to landscape (ref \ADL_DISPLAY_SLSGRID_CAP_OPTION_RELATIVETO_LANDSCAPE) and relative to current angle (ref \ADL_DISPLAY_SLSGRID_CAP_OPTION_RELATIVETO_CURRENTANGLE). - /// return ADL Error Code - public delegate int ADL_Display_SLSMapConfig_Get(int adapterIndex, int SLSMapIndex, ref ADLSLSMap SLSMap, ref int numSLSTarget, out IntPtr SLSTargetArray, ref int numNativeMode, - out IntPtr SLSNativeMode, ref int numBezelMode, out IntPtr SLSBezelMode, ref int numTransientMode, out IntPtr SLSTransientMode, ref int numSLSOffset, out IntPtr SLSOffset, int option); - - #endregion Export Delegates - - #region Export Struct - - #region ADLMode /// ADLAdapterInfo Array [StructLayout(LayoutKind.Sequential)] - public struct ADLMode + public struct ADL_MODE : IEquatable { /// Adapter index. public int AdapterIndex; /// Display IDs. - public ADLDisplayID DisplayID; + public ADL_DISPLAY_ID DisplayID; /// Screen position X coordinate. public int XPos; /// Screen position Y coordinate. @@ -358,66 +135,159 @@ namespace ATI.ADL /// The bit mask identifying the number of bits this Mode is currently using. public int ModeMask; /// The bit mask identifying the display status. - public int ModeValue; + public int ModeValue; + + // Mode Mask settings + public bool ColourFormat565Supported => (ModeMask & 0x1) == 0x1; + public bool ColourFormat8888Supported => (ModeMask & 0x2) == 0x2; + public bool Orientation000Supported => (ModeMask & 0x4) == 0x4; + public bool Orientation090Supported => (ModeMask & 0x8) == 0x8; + public bool Orientation180Supported => (ModeMask & 0x10) == 0x10; + public bool Orientation270Supported => (ModeMask & 0x20) == 0x20; + public bool RefreshRateRoundedSupported => (ModeMask & 0x40) == 0x40; + public bool RefreshRateOnlySupported => (ModeMask & 0x80) == 0x80; + + // Mode Value settings + public bool ColourFormat565Set => (ModeValue & 0x1) == 0x1; + public bool ColourFormat8888Set => (ModeValue & 0x2) == 0x2; + public bool Orientation000Set => (ModeValue & 0x4) == 0x4; + public bool Orientation090Set => (ModeValue & 0x8) == 0x8; + public bool Orientation180Set => (ModeValue & 0x10) == 0x10; + public bool Orientation270Set => (ModeValue & 0x20) == 0x20; + public bool RefreshRateRoundedSet => (ModeValue & 0x40) == 0x40; + public bool RefreshRateOnlySet => (ModeValue & 0x80) == 0x80; + + // Mode Flag settings + public bool ProgressiveSet => ModeValue == 0x0; + public bool InterlacedSet => ModeValue == 0x2; + + public bool Equals(ADL_MODE other) + => AdapterIndex == other.AdapterIndex && + DisplayID.Equals(other.DisplayID) && + XPos == other.XPos && + YPos == other.YPos && + XRes == other.XRes && + YRes == other.YRes && + ColourDepth == other.ColourDepth && + RefreshRate == other.RefreshRate && + Orientation == other.Orientation && + ModeFlag == other.ModeFlag && + ModeMask == other.ModeMask && + ModeValue == other.ModeValue; + + public override int GetHashCode() + { + return (AdapterIndex, DisplayID, XPos, YPos, XRes, YRes, ColourDepth, RefreshRate, Orientation, ModeFlag, ModeMask, ModeValue).GetHashCode(); + } + + //public override string ToString() => $"{type.ToString("G")}"; } - public struct ConvertedDisplayModeFlags - { - /// Indicates the display supports Colour Format 565. - public bool COLOURFORMAT_565; - /// Indicates the display supports Colour Format 8888. - public bool COLOURFORMAT_8888; - /// Indicates the display supports normal vertical orientation - public bool ORIENTATION_SUPPORTED_000; - /// Indicates the display supports 90 degree orientation - public bool ORIENTATION_SUPPORTED_090; - /// Indicates the display supports 180 degree orientation - public bool ORIENTATION_SUPPORTED_180; - /// Indicates the display supports 270 degree orientation - public bool ORIENTATION_SUPPORTED_270; - /// Indicates the display supports rounded refresh rates - public bool REFRESHRATE_ROUNDED; - /// Indicates the display supports exact refresh rates - public bool REFRESHRATE_ONLY; - } - #endregion ADLMode - - #region ADLDisplayTarget /// ADLDisplayTarget [StructLayout(LayoutKind.Sequential)] - public struct ADLDisplayTarget + public struct ADL_DISPLAY_TARGET : IEquatable { /// Display IDs. - public ADLDisplayID DisplayID; + public ADL_DISPLAY_ID DisplayID; /// The display map index identify this manner and the desktop surface. public int DisplayMapIndex; /// The bit mask identifies the number of bits DisplayTarget is currently using. public int DisplayTargetMask; /// The bit mask identifies the display status. public int DisplayTargetValue; + + // DisplayTarget Mask settings + public bool DisplayTargetPreferredSupported => (DisplayTargetMask & 0x1) == 0x1; + + // DisplayTarget Value settings + public bool DisplayTargetPreferredSet => (DisplayTargetValue & 0x1) == 0x1; + + public bool Equals(ADL_DISPLAY_TARGET other) + => DisplayID.Equals(other.DisplayID) && + DisplayMapIndex == other.DisplayMapIndex && + DisplayTargetMask == other.DisplayTargetMask && + DisplayTargetValue == other.DisplayTargetValue; + + public override int GetHashCode() + { + return (DisplayID, DisplayMapIndex, DisplayTargetMask, DisplayTargetValue).GetHashCode(); + } + + //public override string ToString() => $"{type.ToString("G")}"; } - /// ADLDisplayTargetArray Array + /// ADLAdapterDisplayCap [StructLayout(LayoutKind.Sequential)] - public struct ADLDisplayTargetArray + public struct ADL_ADAPTER_DISPLAY_CAP : IEquatable { - /// ADLDisplayTarget Array - [MarshalAs(UnmanagedType.ByValArray, SizeConst = (int)ADL.ADL_MAX_DISPLAYS)] - public ADLDisplayTarget[] ADLDisplayTarget; - } - #endregion ADLDisplayTarget + /// The Persistent logical Adapter Index + public int AdapterIndex; + /// The bit mask identifies the number of bits AdapterDisplayCap is currently using. Sum all the bits defined in ADL_ADAPTER_DISPLAYCAP_XXX + public int AdapterDisplayCapMask; + /// The bit mask identifies the status. Refer to ADL_ADAPTER_DISPLAYCAP_XXX + public int AdapterDisplayCapValue; + + // AdapterDisplayCap Mask settings + public bool NotActiveSupported => (AdapterDisplayCapMask & 0x1) == 0x1; + public bool SingleSupported => (AdapterDisplayCapMask & 0x1) == 0x2; + public bool CloneSupported => (AdapterDisplayCapMask & 0x1) == 0x4; + public bool NStretch1GPUSupported => (AdapterDisplayCapMask & 0x1) == 0x8; + public bool NStretchNGPUSupported => (AdapterDisplayCapMask & 0x1) == 0x10; + public bool TwoVStretchSupported => (AdapterDisplayCapMask & 0x1) == 0x20; + public bool TwoHStretchSupported => (AdapterDisplayCapMask & 0x1) == 0x40; + public bool ExtendedSupported => (AdapterDisplayCapMask & 0x1) == 0x80; + public bool PreferDisplaySupported => (AdapterDisplayCapMask & 0x1) == 0x100; + public bool BezelSupported => (AdapterDisplayCapMask & 0x1) == 0x200; + + + // AdapterDisplayCap Value settings + public bool NotActiveSet => (AdapterDisplayCapValue & 0x1) == 0x1; + public bool SingleSet => (AdapterDisplayCapValue & 0x1) == 0x2; + public bool CloneSet => (AdapterDisplayCapValue & 0x1) == 0x4; + public bool NStretch1GPUSet => (AdapterDisplayCapValue & 0x1) == 0x8; + public bool NStretchNGPUSet => (AdapterDisplayCapValue & 0x1) == 0x10; + public bool TwoVStretchSet => (AdapterDisplayCapValue & 0x1) == 0x20; + public bool TwoHStretchSet => (AdapterDisplayCapValue & 0x1) == 0x40; + public bool ExtendedSet => (AdapterDisplayCapValue & 0x1) == 0x80; + public bool PreferDisplaySet => (AdapterDisplayCapValue & 0x1) == 0x100; + public bool BezelSet => (AdapterDisplayCapValue & 0x1) == 0x200; + + /* #define ADL_ADAPTER_DISPLAYCAP_MANNER_SUPPORTED_NOTACTIVE 0x00000001 + #define ADL_ADAPTER_DISPLAYCAP_MANNER_SUPPORTED_SINGLE 0x00000002 + #define ADL_ADAPTER_DISPLAYCAP_MANNER_SUPPORTED_CLONE 0x00000004 + #define ADL_ADAPTER_DISPLAYCAP_MANNER_SUPPORTED_NSTRETCH1GPU 0x00000008 + #define ADL_ADAPTER_DISPLAYCAP_MANNER_SUPPORTED_NSTRETCHNGPU 0x00000010 + + /// Legacy support for XP + #define ADL_ADAPTER_DISPLAYCAP_MANNER_SUPPORTED_2VSTRETCH 0x00000020 + #define ADL_ADAPTER_DISPLAYCAP_MANNER_SUPPORTED_2HSTRETCH 0x00000040 + #define ADL_ADAPTER_DISPLAYCAP_MANNER_SUPPORTED_EXTENDED 0x00000080 + + #define ADL_ADAPTER_DISPLAYCAP_PREFERDISPLAY_SUPPORTED 0x00000100 + #define ADL_ADAPTER_DISPLAYCAP_BEZEL_SUPPORTED 0x00000200*/ + public bool Equals(ADL_ADAPTER_DISPLAY_CAP other) + => AdapterIndex == other.AdapterIndex && + AdapterDisplayCapMask == other.AdapterDisplayCapMask && + AdapterDisplayCapValue == other.AdapterDisplayCapValue; + + public override int GetHashCode() + { + return (AdapterIndex, AdapterDisplayCapMask, AdapterDisplayCapValue).GetHashCode(); + } + + //public override string ToString() => $"{type.ToString("G")}"; + } - #region ADLAdapterInfo /// ADLAdapterInfo Structure [StructLayout(LayoutKind.Sequential)] - public struct ADLAdapterInfo + public struct ADL_ADAPTER_INFO : IEquatable { /// The size of the structure - int Size; + public int Size; /// Adapter Index public int AdapterIndex; /// Adapter UDID - [MarshalAs(UnmanagedType.ByValTStr, SizeConst = (int)ADL.ADL_MAX_PATH)] + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = (int)ADLImport.ADL_MAX_PATH)] public string UDID; /// Adapter Bus Number public int BusNumber; @@ -428,48 +298,63 @@ namespace ATI.ADL /// Adapter Vendor ID public int VendorID; /// Adapter Adapter name - [MarshalAs(UnmanagedType.ByValTStr, SizeConst = (int)ADL.ADL_MAX_PATH)] + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = (int)ADLImport.ADL_MAX_PATH)] public string AdapterName; /// Adapter Display name - [MarshalAs(UnmanagedType.ByValTStr, SizeConst = (int)ADL.ADL_MAX_PATH)] + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = (int)ADLImport.ADL_MAX_PATH)] public string DisplayName; /// Adapter Present status public int Present; /// Adapter Exist status public int Exist; /// Adapter Driver Path - [MarshalAs(UnmanagedType.ByValTStr, SizeConst = (int)ADL.ADL_MAX_PATH)] + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = (int)ADLImport.ADL_MAX_PATH)] public string DriverPath; /// Adapter Driver Ext Path - [MarshalAs(UnmanagedType.ByValTStr, SizeConst = (int)ADL.ADL_MAX_PATH)] + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = (int)ADLImport.ADL_MAX_PATH)] public string DriverPathExt; /// Adapter PNP String - [MarshalAs(UnmanagedType.ByValTStr, SizeConst = (int)ADL.ADL_MAX_PATH)] + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = (int)ADLImport.ADL_MAX_PATH)] public string PNPString; /// OS Display Index public int OSDisplayIndex; + + public bool Equals(ADL_ADAPTER_INFO other) + => Size == other.Size && + AdapterIndex == other.AdapterIndex && + UDID.Equals(other.UDID) && + BusNumber == other.BusNumber && + DriverNumber == other.DriverNumber && + FunctionNumber == other.FunctionNumber && + VendorID == other.VendorID && + AdapterName.Equals(other.AdapterName) && + DisplayName.Equals(other.DisplayName) && + Present == other.Present && + Exist == other.Exist && + DriverPath.Equals(other.DriverPath) && + DriverPathExt.Equals(other.DriverPathExt) && + PNPString.Equals(other.PNPString) && + OSDisplayIndex == other.OSDisplayIndex; + + public override int GetHashCode() + { + return (Size, AdapterIndex, UDID, BusNumber, DriverNumber, FunctionNumber, VendorID, AdapterName, DisplayName, Present, Exist, DriverPath, DriverPathExt, PNPString, OSDisplayIndex).GetHashCode(); + } + + //public override string ToString() => $"{type.ToString("G")}"; } - /// ADLAdapterInfo Array - [StructLayout(LayoutKind.Sequential)] - public struct ADLAdapterInfoArray - { - /// ADLAdapterInfo Array - [MarshalAs(UnmanagedType.ByValArray, SizeConst = (int)ADL.ADL_MAX_ADAPTERS)] - public ADLAdapterInfo[] ADLAdapterInfo; - } - /// ADLAdapterInfoX2 Structure [StructLayout(LayoutKind.Sequential)] - public struct ADLAdapterInfoX2 + public struct ADL_ADAPTER_INFOX2 : IEquatable { /// The size of the structure public int Size; /// Adapter Index public int AdapterIndex; /// Adapter UDID - [MarshalAs(UnmanagedType.ByValTStr, SizeConst = (int)ADL.ADL_MAX_PATH)] + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = (int)ADLImport.ADL_MAX_PATH)] public string UDID; /// Adapter Bus Number public int BusNumber; @@ -480,23 +365,23 @@ namespace ATI.ADL /// Adapter Vendor ID public int VendorID; /// Adapter Adapter name - [MarshalAs(UnmanagedType.ByValTStr, SizeConst = (int)ADL.ADL_MAX_DISPLAY_NAME)] + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = (int)ADLImport.ADL_MAX_DISPLAY_NAME)] public string AdapterName; /// Adapter Display name - [MarshalAs(UnmanagedType.ByValTStr, SizeConst = (int)ADL.ADL_MAX_DISPLAY_NAME)] + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = (int)ADLImport.ADL_MAX_DISPLAY_NAME)] public string DisplayName; /// Adapter Present status public int Present; /// Adapter Exist status public int Exist; /// Adapter Driver Path - [MarshalAs(UnmanagedType.ByValTStr, SizeConst = (int)ADL.ADL_MAX_PATH)] + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = (int)ADLImport.ADL_MAX_PATH)] public string DriverPath; /// Adapter Driver Ext Path - [MarshalAs(UnmanagedType.ByValTStr, SizeConst = (int)ADL.ADL_MAX_PATH)] + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = (int)ADLImport.ADL_MAX_PATH)] public string DriverPathExt; /// Adapter PNP String - [MarshalAs(UnmanagedType.ByValTStr, SizeConst = (int)ADL.ADL_MAX_PATH)] + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = (int)ADLImport.ADL_MAX_PATH)] public string PNPString; /// OS Display Index public int OSDisplayIndex; @@ -504,16 +389,77 @@ namespace ATI.ADL public int InfoMask; /// Display Info Value public int InfoValue; + + // Info Mask settings + public bool DisplayConnectedSupported => (InfoMask & 0x1) == 0x1; + public bool DisplayMappedSupported => (InfoMask & 0x2) == 0x2; + public bool NonLocalSupported => (InfoMask & 0x4) == 0x4; + public bool ForcibleSupported => (InfoMask & 0x8) == 0x8; + public bool GenLockSupported => (InfoMask & 0x10) == 0x10; + public bool MultiVPUSupported => (InfoMask & 0x20) == 0x20; + public bool LDADisplaySupported => (InfoMask & 0x40) == 0x40; + public bool ModeTimingOverrideSupported => (InfoMask & 0x80) == 0x80; + public bool MannerSingleSupported => (InfoMask & 0x100) == 0x100; + public bool MannerCloneSupported => (InfoMask & 0x200) == 0x200; + public bool Manner2VStretchSupported => (InfoMask & 0x400) == 0x400; + public bool Manner2HStretchSupported => (InfoMask & 0x800) == 0x800; + public bool MannerExtendedSupported => (InfoMask & 0x1000) == 0x1000; + public bool MannerNStretch1GPUSupported => (InfoMask & 0x10000) == 0x10000; + public bool MannerNStretchNGPUSupported => (InfoMask & 0x20000) == 0x20000; + public bool MannerReserved2Supported => (InfoMask & 0x40000) == 0x40000; + public bool MannerReserved3Supported => (InfoMask & 0x80000) == 0x80000; + public bool ShowTypeProjectorSupported => (InfoMask & 0x100000) == 0x100000; + + // Info Value settings + public bool DisplayConnectedSet => (InfoValue & 0x1) == 0x1; + public bool DisplayMappedSet => (InfoValue & 0x2) == 0x2; + public bool NonLocalSet => (InfoValue & 0x4) == 0x4; + public bool ForcibleSet => (InfoValue & 0x8) == 0x8; + public bool GenLockSet => (InfoValue & 0x10) == 0x10; + public bool MultiVPUSet => (InfoValue & 0x20) == 0x20; + public bool LDADisplaySet => (InfoValue & 0x40) == 0x40; + public bool ModeTimingOverrideSet => (InfoValue & 0x80) == 0x80; + public bool MannerSingleSet => (InfoValue & 0x100) == 0x100; + public bool MannerCloneSet => (InfoValue & 0x200) == 0x200; + public bool Manner2VStretchSet => (InfoValue & 0x400) == 0x400; + public bool Manner2HStretchSet => (InfoValue & 0x800) == 0x800; + public bool MannerExtendedSet => (InfoValue & 0x1000) == 0x1000; + public bool MannerNStretch1GPUSet => (InfoValue & 0x10000) == 0x10000; + public bool MannerNStretchNGPUSet => (InfoValue & 0x20000) == 0x20000; + public bool MannerReserved2Set => (InfoValue & 0x40000) == 0x40000; + public bool MannerReserved3Set => (InfoValue & 0x80000) == 0x80000; + public bool ShowTypeProjectorSet => (InfoValue & 0x100000) == 0x100000; + + public bool Equals(ADL_ADAPTER_INFOX2 other) + => Size == other.Size && + AdapterIndex == other.AdapterIndex && + UDID.Equals(other.UDID) && + BusNumber == other.BusNumber && + DeviceNumber == other.DeviceNumber && + FunctionNumber == other.FunctionNumber && + VendorID == other.VendorID && + AdapterName.Equals(other.AdapterName) && + DisplayName.Equals(other.DisplayName) && + Present == other.Present && + Exist == other.Exist && + DriverPath.Equals(other.DriverPath) && + DriverPathExt.Equals(other.DriverPathExt) && + PNPString.Equals(other.PNPString) && + OSDisplayIndex == other.OSDisplayIndex && + InfoMask == other.InfoMask && + InfoValue == other.InfoValue; + + public override int GetHashCode() + { + return (Size, AdapterIndex, UDID, BusNumber, DeviceNumber, FunctionNumber, VendorID, AdapterName, DisplayName, Present, Exist, DriverPath, DriverPathExt, PNPString, OSDisplayIndex).GetHashCode(); + } + + //public override string ToString() => $"{type.ToString("G")}"; } - #endregion ADLAdapterInfo - - - #region ADLDisplayInfo - /// ADLDisplayEDIDData Structure [StructLayout(LayoutKind.Sequential)] - public struct ADLDisplayEDIDData + public struct ADL_DISPLAY_EDID_DATA : IEquatable { /// Size public int Size; @@ -524,17 +470,31 @@ namespace ATI.ADL /// Block Index public int BlockIndex; /// EDIDData [256] - [MarshalAs(UnmanagedType.ByValTStr, SizeConst = (int)ADL.ADL_MAX_EDIDDATA_SIZE)] + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = (int)ADLImport.ADL_MAX_EDIDDATA_SIZE)] public string EDIDData; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] public int[] Reserved; + public bool Equals(ADL_DISPLAY_EDID_DATA other) + => Size == other.Size && + Flag == other.Flag && + EDIDSize == other.EDIDSize && + BlockIndex == other.BlockIndex && + EDIDData.Equals(other.EDIDData); + + public override int GetHashCode() + { + return (Size, Flag, EDIDSize, BlockIndex, EDIDData).GetHashCode(); + } + + //public override string ToString() => $"{type.ToString("G")}"; + } /// ADLDDCInfo2 Structure [StructLayout(LayoutKind.Sequential)] - public struct ADLDDCInfo2 + public struct ADL_DDC_INFO2 : IEquatable { /// Size of the structure. public int Size; @@ -545,7 +505,7 @@ namespace ATI.ADL /// Returns the product ID of the display device. Should be zeroed if this informatiadlon is not available. public int ProductID; /// Returns the name of the display device. Should be zeroed if this information is not available. - [MarshalAs(UnmanagedType.ByValTStr, SizeConst = (int)ADL.ADL_MAX_DISPLAY_NAME)] + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = (int)ADLImport.ADL_MAX_DISPLAY_NAME)] public string DisplayName; /// Returns the maximum Horizontal supported resolution. Should be zeroed if this information is not available. public int MaxHResolution; @@ -614,40 +574,112 @@ namespace ATI.ADL /// Reserved [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] public int[] Reserved; - } - public struct ConvertedDDCInfoFlag - { - /// Indicates the display is a projector . - public bool PROJECTORDEVICE; - /// Indicates the display has an EDID extension - public bool EDIDEXTENSION; - /// Indicates the display is a digital device - public bool DIGITALDEVICE; - /// Indicates the display has HDMI audio capabilities - public bool HDMIAUDIODEVICE; - /// Indicates the display supports AI - public bool SUPPORTS_AI; - /// Indicates the display supports xvYCC601 - public bool SUPPORT_xvYCC601; - /// Indicates the display supports xvYCC709 - public bool SUPPORT_xvYCC709; - } + // DDC Info Flag settings + public bool IsProjectorDevice => (DDCInfoFlag & 0x1) == 0x1; + public bool IsEDIDExtension => (DDCInfoFlag & 0x2) == 0x2; + public bool IsDigitalDevice => (DDCInfoFlag & 0x4) == 0x4; + public bool IsHDMIAudioDevice => (DDCInfoFlag & 0x8) == 0x8; + public bool SupportsAI => (DDCInfoFlag & 0x10) == 0x10; + public bool SupportsxvYCC601 => (DDCInfoFlag & 0x10) == 0x20; + public bool SupportsxvYCC709 => (DDCInfoFlag & 0x10) == 0x40; - public struct ConvertedSupportedHDR - { - /// HDR10/CEA861.3 HDR supported - public bool CEA861_3; - /// DolbyVision HDR supported - public bool DOLBYVISION; - /// FreeSync HDR supported. - public bool FREESYNC_HDR; - } + /*#define ADL_DISPLAYDDCINFOEX_FLAG_PROJECTORDEVICE (1 << 0) + #define ADL_DISPLAYDDCINFOEX_FLAG_EDIDEXTENSION (1 << 1) + #define ADL_DISPLAYDDCINFOEX_FLAG_DIGITALDEVICE (1 << 2) + #define ADL_DISPLAYDDCINFOEX_FLAG_HDMIAUDIODEVICE (1 << 3) + #define ADL_DISPLAYDDCINFOEX_FLAG_SUPPORTS_AI (1 << 4) + #define ADL_DISPLAYDDCINFOEX_FLAG_SUPPORT_xvYCC601 (1 << 5) + #define ADL_DISPLAYDDCINFOEX_FLAG_SUPPORT_xvYCC709 (1 << 6)*/ + // Panel Pixel Format settings + public bool PixelFormatUnknown => (PanelPixelFormat & 0x1) == 0x1; + public bool PixelFormatRGB => (PanelPixelFormat & 0x2) == 0x2; + public bool PixelFormatYCRCB444 => (PanelPixelFormat & 0x4) == 0x4; + public bool PixelFormatYCRCB422 => (PanelPixelFormat & 0x8) == 0x8; + public bool PixelFormatLimitedRange => (PanelPixelFormat & 0x10) == 0x10; + public bool PixelFormatYCRCB420 => (PanelPixelFormat & 0x10) == 0x20; + + // ADL_DISPLAY_ADJUSTMENT_PIXELFORMAT adjustment values + // (bit-vector) + /*#define ADL_DISPLAY_PIXELFORMAT_UNKNOWN 0 + #define ADL_DISPLAY_PIXELFORMAT_RGB (1 << 0) + #define ADL_DISPLAY_PIXELFORMAT_YCRCB444 (1 << 1) //Limited range + #define ADL_DISPLAY_PIXELFORMAT_YCRCB422 (1 << 2) //Limited range + #define ADL_DISPLAY_PIXELFORMAT_RGB_LIMITED_RANGE (1 << 3) + #define ADL_DISPLAY_PIXELFORMAT_RGB_FULL_RANGE ADL_DISPLAY_PIXELFORMAT_RGB //Full range + #define ADL_DISPLAY_PIXELFORMAT_YCRCB420 (1 << 4)*/ + + // Supported Transfer Function settings + //public bool DisplayConnectedSupported => (SupportedTransferFunction & 0x1) == 0x1; + + // Supported Color Space settings + //public bool DisplayConnectedSupported => (SupportedColorSpace & 0x1) == 0x1; + + // Supported HDR settings + public bool CEA861_3Supported => (SupportedHDR & 0x1) == 0x1; + public bool DolbyVisionSupported => (SupportedHDR & 0x2) == 0x2; + public bool FreeSyncHDRSupported => (SupportedHDR & 0x4) == 0x4; + + // Freesync Flags settings + public bool FreeSyncHDRBacklightSupported => (SupportedHDR & 0x1) == 0x1; + public bool FreeSyncHDRLocalDimmingSupported => (SupportedHDR & 0x2) == 0x2; + + public bool Equals(ADL_DDC_INFO2 other) + => Size == other.Size && + SupportsDDC == other.SupportsDDC && + ManufacturerID == other.ManufacturerID && + ProductID == other.ProductID && + DisplayName.Equals(other.DisplayName) && + MaxHResolution == other.MaxHResolution && + MaxVResolution == other.MaxVResolution && + MaxRefresh == other.MaxRefresh && + PTMCx == other.PTMCx && + PTMCy == other.PTMCy && + PTMRefreshRate == other.PTMRefreshRate && + DDCInfoFlag == other.DDCInfoFlag && + PackedPixelSupported == other.PackedPixelSupported && + PanelPixelFormat == other.PanelPixelFormat && + SerialID == other.SerialID && + MinLuminanceData == other.MinLuminanceData && + AvgLuminanceData == other.AvgLuminanceData && + MaxLuminanceData == other.MaxLuminanceData && + SupportedTransferFunction == other.SupportedTransferFunction && + SupportedColorSpace == other.SupportedColorSpace && + NativeDisplayChromaticityRedX == other.NativeDisplayChromaticityRedX && + NativeDisplayChromaticityRedY == other.NativeDisplayChromaticityRedY && + NativeDisplayChromaticityGreenX == other.NativeDisplayChromaticityGreenX && + NativeDisplayChromaticityGreenY == other.NativeDisplayChromaticityGreenY && + NativeDisplayChromaticityBlueX == other.NativeDisplayChromaticityBlueX && + NativeDisplayChromaticityBlueY == other.NativeDisplayChromaticityBlueY && + NativeDisplayChromaticityWhiteX == other.NativeDisplayChromaticityWhiteX && + NativeDisplayChromaticityWhiteY == other.NativeDisplayChromaticityWhiteY && + DiffuseScreenReflectance == other.DiffuseScreenReflectance && + SpecularScreenReflectance == other.SpecularScreenReflectance && + SupportedHDR == other.SupportedHDR && + FreesyncFlags == other.FreesyncFlags && + MinLuminanceNoDimmingData == other.MinLuminanceNoDimmingData && + MaxBacklightMaxLuminanceData == other.MaxBacklightMaxLuminanceData && + MinBacklightMaxLuminanceData == other.MinBacklightMaxLuminanceData && + MaxBacklightMinLuminanceData == other.MaxBacklightMinLuminanceData && + MinBacklightMinLuminanceData == other.MinBacklightMinLuminanceData; + + public override int GetHashCode() + { + return (Size, SupportsDDC, ManufacturerID, ProductID, DisplayName, MaxHResolution, MaxVResolution, MaxRefresh, PTMCx, PTMCy, PTMRefreshRate, DDCInfoFlag, + PackedPixelSupported, PanelPixelFormat, SerialID, MinLuminanceData, AvgLuminanceData, MaxLuminanceData, SupportedTransferFunction, SupportedColorSpace, + NativeDisplayChromaticityRedX, NativeDisplayChromaticityRedY, NativeDisplayChromaticityGreenX, NativeDisplayChromaticityGreenY, + NativeDisplayChromaticityBlueX, NativeDisplayChromaticityBlueY, NativeDisplayChromaticityWhiteX, NativeDisplayChromaticityWhiteY, + DiffuseScreenReflectance, SpecularScreenReflectance, SupportedHDR, FreesyncFlags, MinLuminanceNoDimmingData, MaxBacklightMaxLuminanceData, + MinBacklightMaxLuminanceData, MaxBacklightMinLuminanceData, MinBacklightMinLuminanceData).GetHashCode(); + } + + //public override string ToString() => $"{type.ToString("G")}"; + } /// ADLDisplayID Structure [StructLayout(LayoutKind.Sequential)] - public struct ADLDisplayID + public struct ADL_DISPLAY_ID : IEquatable { /// Display Logical Index public int DisplayLogicalIndex; @@ -657,21 +689,34 @@ namespace ATI.ADL public int DisplayLogicalAdapterIndex; /// Adapter Physical Index public int DisplayPhysicalAdapterIndex; + + public bool Equals(ADL_DISPLAY_ID other) + => DisplayLogicalIndex == other.DisplayLogicalIndex && + DisplayPhysicalIndex == other.DisplayPhysicalIndex && + DisplayLogicalAdapterIndex == other.DisplayLogicalAdapterIndex && + DisplayPhysicalAdapterIndex == other.DisplayPhysicalAdapterIndex; + + public override int GetHashCode() + { + return (DisplayLogicalIndex, DisplayPhysicalIndex, DisplayLogicalAdapterIndex, DisplayPhysicalAdapterIndex).GetHashCode(); + } + + //public override string ToString() => $"{type.ToString("G")}"; } /// ADLDisplayInfo Structure [StructLayout(LayoutKind.Sequential)] - public struct ADLDisplayInfo + public struct ADL_DISPLAY_INFO : IEquatable { /// Display Index - public ADLDisplayID DisplayID; + public ADL_DISPLAY_ID DisplayID; /// Display Controller Index public int DisplayControllerIndex; /// Display Name - [MarshalAs(UnmanagedType.ByValTStr, SizeConst = (int)ADL.ADL_MAX_PATH)] + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = (int)ADLImport.ADL_MAX_PATH)] public string DisplayName; /// Display Manufacturer Name - [MarshalAs(UnmanagedType.ByValTStr, SizeConst = (int)ADL.ADL_MAX_PATH)] + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = (int)ADLImport.ADL_MAX_PATH)] public string DisplayManufacturerName; /// Display Type : The Display type. CRT, TV,CV,DFP are some of display types, public int DisplayType; @@ -683,51 +728,145 @@ namespace ATI.ADL public int DisplayInfoMask; /// Indicating the display info value. public int DisplayInfoValue; + + // Display Type - no idea what the settings are + + // Display Output Type settings + public bool DisplayOutputTypeIsUnknown => DisplayOutputType == 0; + public bool DisplayOutputTypeIsVGA => DisplayOutputType == 1; + public bool DisplayOutputTypeIsDVI_D => DisplayOutputType == 2; + public bool DisplayOutputTypeIsDVI_I => DisplayOutputType == 3; + public bool DisplayOutputTypeIsATICVDongleNTSC => DisplayOutputType == 4; + public bool DisplayOutputTypeIsATICVDongleJPN => DisplayOutputType == 5; + public bool DisplayOutputTypeIsATICVDongleNonI2CJPN => DisplayOutputType == 6; + public bool DisplayOutputTypeIsATICVDongleNonI2CNTSC => DisplayOutputType == 7; + public bool DisplayOutputTypeIsProprietary => DisplayOutputType == 8; + public bool DisplayOutputTypeIsHDMITypeA => DisplayOutputType == 10; + public bool DisplayOutputTypeIsHDMITypeB => DisplayOutputType == 11; + public bool DisplayOutputTypeIsSVideo => DisplayOutputType == 12; + public bool DisplayOutputTypeIsComposite => DisplayOutputType == 13; + public bool DisplayOutputTypeIsRCA3Component => DisplayOutputType == 14; + public bool DisplayOutputTypeIsDisplayPort => DisplayOutputType == 15; + public bool DisplayOutputTypeIsEDP => DisplayOutputType == 16; + public bool DisplayOutputTypeIsWirelessDisplay => DisplayOutputType == 17; + public bool DisplayOutputTypeIsUSBTypeC => DisplayOutputType == 18; + + + /*#define ADL_DISPLAY_CONTYPE_UNKNOWN 0 + #define ADL_DISPLAY_CONTYPE_VGA 1 + #define ADL_DISPLAY_CONTYPE_DVI_D 2 + #define ADL_DISPLAY_CONTYPE_DVI_I 3 + #define ADL_DISPLAY_CONTYPE_ATICVDONGLE_NTSC 4 + #define ADL_DISPLAY_CONTYPE_ATICVDONGLE_JPN 5 + #define ADL_DISPLAY_CONTYPE_ATICVDONGLE_NONI2C_JPN 6 + #define ADL_DISPLAY_CONTYPE_ATICVDONGLE_NONI2C_NTSC 7 + #define ADL_DISPLAY_CONTYPE_PROPRIETARY 8 + #define ADL_DISPLAY_CONTYPE_HDMI_TYPE_A 10 + #define ADL_DISPLAY_CONTYPE_HDMI_TYPE_B 11 + #define ADL_DISPLAY_CONTYPE_SVIDEO 12 + #define ADL_DISPLAY_CONTYPE_COMPOSITE 13 + #define ADL_DISPLAY_CONTYPE_RCA_3COMPONENT 14 + #define ADL_DISPLAY_CONTYPE_DISPLAYPORT 15 + #define ADL_DISPLAY_CONTYPE_EDP 16 + #define ADL_DISPLAY_CONTYPE_WIRELESSDISPLAY 17 + #define ADL_DISPLAY_CONTYPE_USB_TYPE_C 18*/ + + // Display Connector + + public bool DisplayConnectorIsVGA => DisplayConnector == 0; + public bool DisplayConnectorIsDVI => DisplayConnector == 1; + public bool DisplayConnectorIsDVI_SL => DisplayConnector == 2; + public bool DisplayConnectorIsHDMI => DisplayConnector == 3; + public bool DisplayConnectorIsDisplayPort => DisplayConnector == 4; + public bool DisplayConnectorIsActiveDongleDP_DVI_SL => DisplayConnector == 5; + public bool DisplayConnectorIsActiveDongleDP_DVI_DL => DisplayConnector == 6; + public bool DisplayConnectorIsActiveDongleDP_HDMI => DisplayConnector == 7; + public bool DisplayConnectorIsActiveDongleDP_VGA => DisplayConnector == 8; + public bool DisplayConnectorIsPassiveDongleDP_HDMI => DisplayConnector == 9; + public bool DisplayConnectorIsPassiveDongleDP_DVI => DisplayConnector == 10; + public bool DisplayConnectorIsMST => DisplayConnector == 11; + public bool DisplayConnectorIsActiveDongle => DisplayConnector == 12; + public bool DisplayConnectorIsVirtual => DisplayConnector == 13; + + /*#define ADL_CONNECTION_TYPE_VGA 0 + #define ADL_CONNECTION_TYPE_DVI 1 + #define ADL_CONNECTION_TYPE_DVI_SL 2 + #define ADL_CONNECTION_TYPE_HDMI 3 + #define ADL_CONNECTION_TYPE_DISPLAY_PORT 4 + #define ADL_CONNECTION_TYPE_ACTIVE_DONGLE_DP_DVI_SL 5 + #define ADL_CONNECTION_TYPE_ACTIVE_DONGLE_DP_DVI_DL 6 + #define ADL_CONNECTION_TYPE_ACTIVE_DONGLE_DP_HDMI 7 + #define ADL_CONNECTION_TYPE_ACTIVE_DONGLE_DP_VGA 8 + #define ADL_CONNECTION_TYPE_PASSIVE_DONGLE_DP_HDMI 9 + #define ADL_CONNECTION_TYPE_PASSIVE_DONGLE_DP_DVI 10 + #define ADL_CONNECTION_TYPE_MST 11 + #define ADL_CONNECTION_TYPE_ACTIVE_DONGLE 12 + #define ADL_CONNECTION_TYPE_VIRTUAL 13*/ + + + // Display Info Mask settings + public bool DisplayConnectedSupported => (DisplayInfoMask & 0x1) == 0x1; + public bool DisplayMappedSupported => (DisplayInfoMask & 0x2) == 0x2; + public bool NonLocalSupported => (DisplayInfoMask & 0x4) == 0x4; + public bool ForcibleSupported => (DisplayInfoMask & 0x8) == 0x8; + public bool GenLockSupported => (DisplayInfoMask & 0x10) == 0x10; + public bool MultiVPUSupported => (DisplayInfoMask & 0x20) == 0x20; + public bool LDADisplaySupported => (DisplayInfoMask & 0x40) == 0x40; + public bool ModeTimingOverrideSupported => (DisplayInfoMask & 0x80) == 0x80; + public bool MannerSingleSupported => (DisplayInfoMask & 0x100) == 0x100; + public bool MannerCloneSupported => (DisplayInfoMask & 0x200) == 0x200; + public bool Manner2VStretchSupported => (DisplayInfoMask & 0x400) == 0x400; + public bool Manner2HStretchSupported => (DisplayInfoMask & 0x800) == 0x800; + public bool MannerExtendedSupported => (DisplayInfoMask & 0x1000) == 0x1000; + public bool MannerNStretch1GPUSupported => (DisplayInfoMask & 0x10000) == 0x10000; + public bool MannerNStretchNGPUSupported => (DisplayInfoMask & 0x20000) == 0x20000; + public bool MannerReserved2Supported => (DisplayInfoMask & 0x40000) == 0x40000; + public bool MannerReserved3Supported => (DisplayInfoMask & 0x80000) == 0x80000; + public bool ShowTypeProjectorSupported => (DisplayInfoMask & 0x100000) == 0x100000; + + // Display Info Value settings + public bool DisplayConnectedSet => (DisplayInfoValue & 0x1) == 0x1; + public bool DisplayMappedSet => (DisplayInfoValue & 0x2) == 0x2; + public bool NonLocalSet => (DisplayInfoValue & 0x4) == 0x4; + public bool ForcibleSet => (DisplayInfoValue & 0x8) == 0x8; + public bool GenLockSet => (DisplayInfoValue & 0x10) == 0x10; + public bool MultiVPUSet => (DisplayInfoValue & 0x20) == 0x20; + public bool LDADisplaySet => (DisplayInfoValue & 0x40) == 0x40; + public bool ModeTimingOverrideSet => (DisplayInfoValue & 0x80) == 0x80; + public bool MannerSingleSet => (DisplayInfoValue & 0x100) == 0x100; + public bool MannerCloneSet => (DisplayInfoValue & 0x200) == 0x200; + public bool Manner2VStretchSet => (DisplayInfoValue & 0x400) == 0x400; + public bool Manner2HStretchSet => (DisplayInfoValue & 0x800) == 0x800; + public bool MannerExtendedSet => (DisplayInfoValue & 0x1000) == 0x1000; + public bool MannerNStretch1GPUSet => (DisplayInfoValue & 0x10000) == 0x10000; + public bool MannerNStretchNGPUSet => (DisplayInfoValue & 0x20000) == 0x20000; + public bool MannerReserved2Set => (DisplayInfoValue & 0x40000) == 0x40000; + public bool MannerReserved3Set => (DisplayInfoValue & 0x80000) == 0x80000; + public bool ShowTypeProjectorSet => (DisplayInfoValue & 0x100000) == 0x100000; + + public bool Equals(ADL_DISPLAY_INFO other) + => DisplayID.Equals(other.DisplayID) && + DisplayControllerIndex == other.DisplayControllerIndex && + DisplayName.Equals(other.DisplayName) && + DisplayID.Equals(other.DisplayID) && + DisplayType == other.DisplayType && + DisplayOutputType == other.DisplayOutputType && + DisplayConnector == other.DisplayConnector && + DisplayInfoMask == other.DisplayInfoMask && + DisplayInfoValue == other.DisplayInfoValue; + + public override int GetHashCode() + { + return (DisplayID, DisplayControllerIndex, DisplayName, DisplayID, DisplayType, DisplayOutputType, DisplayConnector, DisplayInfoMask, DisplayInfoValue).GetHashCode(); + } + + //public override string ToString() => $"{type.ToString("G")}"; } - public struct ConvertedDisplayInfoValue - { - /// Indicates the display is connected . - public bool DISPLAYCONNECTED; - /// Indicates the display is mapped within OS - public bool DISPLAYMAPPED; - /// Indicates the display can be forced - public bool FORCIBLESUPPORTED; - /// Indicates the display supports genlock - public bool GENLOCKSUPPORTED; - /// Indicates the display is an LDA display. - public bool LDA_DISPLAY; - /// Indicates the display supports 2x Horizontal stretch - public bool MANNER_SUPPORTED_2HSTRETCH; - /// - public bool MANNER_SUPPORTED_2VSTRETCH; - /// Indicates the display supports cloned desktops - public bool MANNER_SUPPORTED_CLONE; - /// Indicates the display supports extended desktops - public bool MANNER_SUPPORTED_EXTENDED; - /// Indicates the display supports N Stretched on 1 GPU - public bool MANNER_SUPPORTED_NSTRETCH1GPU; - /// Indicates the display supports N Stretched on N GPUs - public bool MANNER_SUPPORTED_NSTRETCHNGPU; - /// Reserved display info flag #2 - public bool MANNER_SUPPORTED_RESERVED2; - /// Reserved display info flag #3 - public bool MANNER_SUPPORTED_RESERVED3; - /// Indicates the display supports single desktop - public bool MANNER_SUPPORTED_SINGLE; - /// Indicates the display supports overriding the mode timing - public bool MODETIMING_OVERRIDESSUPPORTED; - /// Indicates the display supports multi-vpu - public bool MULTIVPU_SUPPORTED; - /// Indicates the display is non-local to this machine - public bool NONLOCAL; - /// Indicates the display is a projector - public bool SHOWTYPE_PROJECTOR; - } /// ADLDisplayConfig Structure [StructLayout(LayoutKind.Sequential)] - public struct ADLDisplayConfig + public struct ADL_DISPLAY_CONFIG : IEquatable { /// Size of this data structure public long Size; @@ -739,17 +878,42 @@ namespace ATI.ADL public long OverriddedDeviceData; /// Reserved for future use public long Reserved; - + + // Connector Type + public bool ConnectorTypeIsUnknown => ConnectorType == 0; + public bool ConnectorTypeIsCVNonI2CJP => ConnectorType == 1; + public bool ConnectorTypeIsCVJPN => ConnectorType == 2; + public bool ConnectorTypeIsCVNA => ConnectorType == 3; + public bool ConnectorTypeIsCVNonI2CNA => ConnectorType == 4; + public bool ConnectorTypeIsVGA => ConnectorType == 5; + public bool ConnectorTypeIsDVI_D => ConnectorType == 6; + public bool ConnectorTypeIsDVI_I => ConnectorType == 7; + public bool ConnectorTypeIsHDMITypeA => ConnectorType == 8; + public bool ConnectorTypeIsHDMITypeB => ConnectorType == 9; + public bool ConnectorTypeIsDisplayPort => ConnectorType == 10; + + public bool Equals(ADL_DISPLAY_CONFIG other) + => Size == other.Size && + ConnectorType == other.ConnectorType && + DeviceData == other.DeviceData && + OverriddedDeviceData == other.OverriddedDeviceData; + + public override int GetHashCode() + { + return (Size, ConnectorType, DeviceData, OverriddedDeviceData).GetHashCode(); + } + + //public override string ToString() => $"{type.ToString("G")}"; } /// ADLDisplayMap Structure [StructLayout(LayoutKind.Sequential)] - public struct ADLDisplayMap + public struct ADL_DISPLAY_MAP : IEquatable { /// The current display map index. It is the OS desktop index. For example, if the OS index 1 is showing clone mode, the display map will be 1. public int DisplayMapIndex; /// The Display Mode for the current map. - public ADLMode DisplayMode; + public ADL_MODE DisplayMode; /// The number of display targets belongs to this map public int NumDisplayTarget; /// The first target array index in the Target array @@ -757,21 +921,47 @@ namespace ATI.ADL /// The bit mask identifies the number of bits DisplayMap is currently using. It is the sum of all the bit definitions defined in ADL_DISPLAY_DISPLAYMAP_MANNER_xxx. public int DisplayMapMask; /// The bit mask identifies the display status. The detailed definition is in ADL_DISPLAY_DISPLAYMAP_MANNER_xxx. - public int DisplayMapValue; - } + public int DisplayMapValue; - /// ADLDisplayMapArray Array - [StructLayout(LayoutKind.Sequential)] - public struct ADLDisplayMapArray - { - /// ADLAdapterInfo Array - [MarshalAs(UnmanagedType.ByValArray, SizeConst = (int)ADL.ADL_MAX_DISPLAYS)] - public ADLDisplayMap[] ADLDisplayMap; + // Display Map Mask settings + public bool DisplayMapReservedSupported => (DisplayMapMask & 0x1) == 0x1; + public bool DisplayMapNotActiveSupported => (DisplayMapMask & 0x2) == 0x2; + public bool DisplayMapSingleSupported => (DisplayMapMask & 0x4) == 0x4; + public bool DisplayMapCloneSupported => (DisplayMapMask & 0x8) == 0x8; + public bool DisplayMapReserved1Supported => (DisplayMapMask & 0x10) == 0x10; + public bool DisplayMapHStretchSupported => (DisplayMapMask & 0x20) == 0x20; + public bool DisplayMapVStretchSupported => (DisplayMapMask & 0x40) == 0x40; + public bool DisplayMapVLDSupported => (DisplayMapMask & 0x80) == 0x80; + + // Display Map Value settings + public bool DisplayMapReservedSet => (DisplayMapValue & 0x1) == 0x1; + public bool DisplayMapNotActiveSet => (DisplayMapValue & 0x2) == 0x2; + public bool DisplayMapSingleSet => (DisplayMapValue & 0x4) == 0x4; + public bool DisplayMapCloneSet => (DisplayMapValue & 0x8) == 0x8; + public bool DisplayMapReserved1Set => (DisplayMapValue & 0x10) == 0x10; + public bool DisplayMapHStretchSet => (DisplayMapValue & 0x20) == 0x20; + public bool DisplayMapVStretchSet => (DisplayMapValue & 0x40) == 0x40; + public bool DisplayMapVLDSet => (DisplayMapValue & 0x80) == 0x80; + + public bool Equals(ADL_DISPLAY_MAP other) + => DisplayMapIndex == other.DisplayMapIndex && + DisplayMode.Equals(other.DisplayMode) && + NumDisplayTarget == other.NumDisplayTarget && + FirstDisplayTargetArrayIndex == other.FirstDisplayTargetArrayIndex && + DisplayMapMask == other.DisplayMapMask && + DisplayMapValue == other.DisplayMapValue; + + public override int GetHashCode() + { + return (DisplayMapIndex, DisplayMode, NumDisplayTarget, FirstDisplayTargetArrayIndex, DisplayMapMask, DisplayMapValue).GetHashCode(); + } + + //public override string ToString() => $"{type.ToString("G")}"; } /// ADLAdapterCaps Structure [StructLayout(LayoutKind.Sequential)] - public struct ADLAdapterCapsX2 + public struct ADL_ADAPTER_CAPSX2 : IEquatable { /// AdapterID for this adapter public int AdapterID; @@ -789,12 +979,53 @@ namespace ATI.ADL public int CapsValue; /// Number of Connectors for this adapter. public int NumConnectors; + + // Caps Mask settings + public bool CapNotActiveSupported => (CapsMask & 0x1) == 0x1; + public bool CapSingleSupported => (CapsMask & 0x2) == 0x2; + public bool CapCloneSupported => (CapsMask & 0x4) == 0x4; + public bool CapNStretch1GPUSupported => (CapsMask & 0x8) == 0x8; + public bool CapNStretchNGPUSupported => (CapsMask & 0x10) == 0x10; + public bool Cap2VStretchSupported => (CapsMask & 0x20) == 0x20; + public bool Cap2HStretchSupported => (CapsMask & 0x40) == 0x40; + public bool CapExtendedSupported => (CapsMask & 0x80) == 0x80; + public bool CapPreferredDisplaySupported => (CapsMask & 0x100) == 0x100; + public bool CapBezelSupported => (CapsMask & 0x200) == 0x200; + + // Caps Value settings + public bool CapNotActiveSet => (CapsValue & 0x1) == 0x1; + public bool CapSingleSet => (CapsValue & 0x2) == 0x2; + public bool CapCloneSet => (CapsValue & 0x4) == 0x4; + public bool CapNStretch1GPUSet => (CapsValue & 0x8) == 0x8; + public bool CapNStretchNGPUSet => (CapsValue & 0x10) == 0x10; + public bool Cap2VStretchSet => (CapsValue & 0x20) == 0x20; + public bool Cap2HStretchSet => (CapsValue & 0x40) == 0x40; + public bool CapExtendedSet => (CapsValue & 0x80) == 0x80; + public bool CapPreferredDisplaySet => (CapsValue & 0x100) == 0x100; + public bool CapBezelSet => (CapsValue & 0x200) == 0x200; + + public bool Equals(ADL_ADAPTER_CAPSX2 other) + => AdapterID == other.AdapterID && + NumControllers == other.NumControllers && + NumDisplays == other.NumDisplays && + NumOverlays == other.NumOverlays && + NumOfGLSyncConnectors == other.NumOfGLSyncConnectors && + CapsMask == other.CapsMask && + CapsValue == other.CapsValue && + NumConnectors == other.NumConnectors; + + public override int GetHashCode() + { + return (AdapterID, NumControllers, NumDisplays, NumOverlays, NumOfGLSyncConnectors, CapsMask, CapsValue, NumConnectors).GetHashCode(); + } + + //public override string ToString() => $"{type.ToString("G")}"; } /// ADLPossibleMap Structure [StructLayout(LayoutKind.Sequential)] - public struct ADLPossibleMap - { + public struct ADL_POSSIBLE_MAP : IEquatable + { /// Index public int Index; /// Adapter Index. @@ -802,16 +1033,31 @@ namespace ATI.ADL /// Display Map Number public int NumDisplayMap; /// The DisplayMaps being tested - public ADLDisplayMap DisplayMaps; + public ADL_DISPLAY_MAP DisplayMaps; /// Number of Display Targets public int NumDisplayTarget; /// The DisplayTargets being tested - public ADLDisplayTarget DisplayTargets; + public ADL_DISPLAY_TARGET DisplayTargets; + + public bool Equals(ADL_POSSIBLE_MAP other) + => Index == other.Index && + AdapterIndex == other.AdapterIndex && + NumDisplayMap == other.NumDisplayMap && + DisplayMaps.Equals(other.DisplayMaps) && + NumDisplayTarget == other.NumDisplayTarget && + DisplayTargets.Equals(other.DisplayTargets); + + public override int GetHashCode() + { + return (Index, AdapterIndex, NumDisplayMap, DisplayMaps, NumDisplayTarget, DisplayTargets).GetHashCode(); + } + + //public override string ToString() => $"{type.ToString("G")}"; } /// ADLPossibleMapping Structure [StructLayout(LayoutKind.Sequential)] - public struct ADLPossibleMapping + public struct ADL_POSSIBLE_MAPPING : IEquatable { /// Display Index public int DisplayIndex; @@ -819,11 +1065,45 @@ namespace ATI.ADL public int DisplayControllerIndex; /// The display manner options supported public int DisplayMannerSupported; + + // Display Manner Supported settings + public bool MapReservedSupported => (DisplayMannerSupported & 0x1) == 0x1; + public bool MapNotActiveSupported => (DisplayMannerSupported & 0x2) == 0x2; + public bool MapSingleSupported => (DisplayMannerSupported & 0x4) == 0x4; + public bool MapCloneSupported => (DisplayMannerSupported & 0x8) == 0x8; + public bool MapReserved1Supported => (DisplayMannerSupported & 0x10) == 0x10; + public bool MapHStretchSupported => (DisplayMannerSupported & 0x20) == 0x20; + public bool MapVStretchSupported => (DisplayMannerSupported & 0x40) == 0x40; + public bool MapVLDSupported => (DisplayMannerSupported & 0x80) == 0x80; + + // ADL_DISPLAY_DISPLAYMAP_MANNER_ Definitions + // for ADLDisplayMap.iDisplayMapMask and ADLDisplayMap.iDisplayMapValue + // (bit-vector) + /*#define ADL_DISPLAY_DISPLAYMAP_MANNER_RESERVED 0x00000001 + #define ADL_DISPLAY_DISPLAYMAP_MANNER_NOTACTIVE 0x00000002 + #define ADL_DISPLAY_DISPLAYMAP_MANNER_SINGLE 0x00000004 + #define ADL_DISPLAY_DISPLAYMAP_MANNER_CLONE 0x00000008 + #define ADL_DISPLAY_DISPLAYMAP_MANNER_RESERVED1 0x00000010 // Removed NSTRETCH + #define ADL_DISPLAY_DISPLAYMAP_MANNER_HSTRETCH 0x00000020 + #define ADL_DISPLAY_DISPLAYMAP_MANNER_VSTRETCH 0x00000040 + #define ADL_DISPLAY_DISPLAYMAP_MANNER_VLD 0x00000080*/ + + public bool Equals(ADL_POSSIBLE_MAPPING other) + => DisplayIndex == other.DisplayIndex && + DisplayControllerIndex == other.DisplayControllerIndex && + DisplayMannerSupported == other.DisplayMannerSupported; + + public override int GetHashCode() + { + return (DisplayIndex, DisplayControllerIndex, DisplayMannerSupported).GetHashCode(); + } + + //public override string ToString() => $"{type.ToString("G")}"; } /// ADLPossibleMapResult Structure [StructLayout(LayoutKind.Sequential)] - public struct ADLPossibleMapResult + public struct ADL_POSSIBLE_MAP_RESULT : IEquatable { /// Index public int Index; @@ -831,16 +1111,42 @@ namespace ATI.ADL /// Display Controller Index public int PossibleMapResultMask; /// The display manner options supported - public int PossibleMapResulValue; + public int PossibleMapResultValue; + + // Possible Map Result Mask settings + public bool MapResultValidSupported => (PossibleMapResultMask & 0x1) == 0x1; + public bool MapNotActiveSupported => (PossibleMapResultMask & 0x2) == 0x2; + public bool MapSingleSupported => (PossibleMapResultMask & 0x4) == 0x4; + + // Possible Map Result Mask settings + public bool MapResultValidSet => (PossibleMapResultValue & 0x1) == 0x1; + public bool MapNotActiveSet => (PossibleMapResultValue & 0x2) == 0x2; + public bool MapSingleSet => (PossibleMapResultValue & 0x4) == 0x4; + + + // ADL_DISPLAY_POSSIBLEMAPRESULT_VALID Definitions + // for ADLPossibleMapResult.iPossibleMapResultMask and ADLPossibleMapResult.iPossibleMapResultValue + // (bit-vector) + /*#define ADL_DISPLAY_POSSIBLEMAPRESULT_VALID 0x00000001 + #define ADL_DISPLAY_POSSIBLEMAPRESULT_BEZELSUPPORTED 0x00000002 + #define ADL_DISPLAY_POSSIBLEMAPRESULT_OVERLAPSUPPORTED 0x00000004*/ + + public bool Equals(ADL_POSSIBLE_MAP_RESULT other) + => Index == other.Index && + PossibleMapResultMask == other.PossibleMapResultMask && + PossibleMapResultValue == other.PossibleMapResultValue; + + public override int GetHashCode() + { + return (Index, PossibleMapResultMask, PossibleMapResultValue).GetHashCode(); + } + + //public override string ToString() => $"{type.ToString("G")}"; } - #endregion ADLDisplayInfo - - #region ADLSLS - /// ADLSLSGrid Structure [StructLayout(LayoutKind.Sequential)] - public struct ADLSLSGrid + public struct ADL_SLS_GRID : IEquatable { /// The Adapter index public int AdapterIndex; @@ -854,18 +1160,63 @@ namespace ATI.ADL public int SLSGridMask; /// The grid bit value identifies the display status. public int SLSGridValue; + + // SLS Grid Mask settings + public bool SLSGridRelativeToLandscapeSupported => (SLSGridMask & 0x1) == 0x1; + public bool SLSGridRelativeToCurrentAngleSupported => (SLSGridMask & 0x2) == 0x2; + public bool SLSGridPortraitModeSupported => (SLSGridMask & 0x4) == 0x4; + public bool SLSGridKeepTargetRotationSupported => (SLSGridMask & 0x8) == 0x8; + public bool SLSGridSameModeSLSSupported => (SLSGridMask & 0x10) == 0x10; + public bool SLSGridMixModeSLSSupported => (SLSGridMask & 0x20) == 0x20; + public bool SLSGridDisplayRotationSupported => (SLSGridMask & 0x40) == 0x40; + public bool SLSGridDesktopRotationSupported => (SLSGridMask & 0x80) == 0x80; + + // SLS Grid Value settings + public bool SLSGridRelativeToLandscapeSet => (SLSGridValue & 0x1) == 0x1; + public bool SLSGridRelativeToCurrentAngleSet => (SLSGridValue & 0x2) == 0x2; + public bool SLSGridPortraitModeSet => (SLSGridValue & 0x4) == 0x4; + public bool SLSGridKeepTargetRotationSet => (SLSGridValue & 0x8) == 0x8; + public bool SLSGridSameModeSLSSet => (SLSGridValue & 0x10) == 0x10; + public bool SLSGridMixModeSLSSet => (SLSGridValue & 0x20) == 0x20; + public bool SLSGridDisplayRotationSet => (SLSGridValue & 0x40) == 0x40; + public bool SLSGridDesktopRotationSet => (SLSGridValue & 0x80) == 0x80; + + /*#define ADL_DISPLAY_SLSGRID_CAP_OPTION_RELATIVETO_LANDSCAPE 0x00000001 + #define ADL_DISPLAY_SLSGRID_CAP_OPTION_RELATIVETO_CURRENTANGLE 0x00000002 + #define ADL_DISPLAY_SLSGRID_PORTAIT_MODE 0x00000004 + #define ADL_DISPLAY_SLSGRID_KEEPTARGETROTATION 0x00000080 + + #define ADL_DISPLAY_SLSGRID_SAMEMODESLS_SUPPORT 0x00000010 + #define ADL_DISPLAY_SLSGRID_MIXMODESLS_SUPPORT 0x00000020 + #define ADL_DISPLAY_SLSGRID_DISPLAYROTATION_SUPPORT 0x00000040 + #define ADL_DISPLAY_SLSGRID_DESKTOPROTATION_SUPPORT 0x00000080*/ + + public bool Equals(ADL_SLS_GRID other) + => AdapterIndex == other.AdapterIndex && + SLSGridIndex == other.SLSGridIndex && + SLSGridRow == other.SLSGridRow && + SLSGridColumn == other.SLSGridColumn && + SLSGridMask == other.SLSGridMask && + SLSGridValue == other.SLSGridValue; + + public override int GetHashCode() + { + return (AdapterIndex, SLSGridIndex, SLSGridRow, SLSGridColumn, SLSGridMask, SLSGridValue).GetHashCode(); + } + + //public override string ToString() => $"{type.ToString("G")}"; } /// ADLSLSMap Structure [StructLayout(LayoutKind.Sequential)] - public struct ADLSLSMap + public struct ADL_SLS_MAP : IEquatable { /// The Adapter Index public int AdapterIndex; /// The current display map index. It is the OS Desktop index. public int SLSMapIndex; /// The current grid - public ADLSLSGrid Grid; + public ADL_SLS_GRID Grid; /// OS Surface Index public int SurfaceMapIndex; /// Screen orientation. E.g., 0, 90, 180, 270. @@ -890,43 +1241,126 @@ namespace ATI.ADL public int SLSMapMask; /// Bitmask identifies display map status public int SLSMapValue; - + + // SLS Orientation settings + /*public bool Orientation000 => (Orientation & 0x1) == 0x1; + public bool Orientation090 => (Orientation & 0x2) == 0x2; + public bool Orientation180 => (Orientation & 0x4) == 0x4; + public bool Orientation270 => (Orientation & 0x8) == 0x8; + + *//*#define ADL_DISPLAY_SLSGRID_ORIENTATION_000 0x00000001 + #define ADL_DISPLAY_SLSGRID_ORIENTATION_090 0x00000002 + #define ADL_DISPLAY_SLSGRID_ORIENTATION_180 0x00000004 + #define ADL_DISPLAY_SLSGRID_ORIENTATION_270 0x00000008*//* + + // SLS Map Mask settings + public bool SLSMapDisplayArrangedSupported => (SLSMapMask & 0x2) == 0x2; + public bool SLSMapCurrentConfigSupported => (SLSMapMask & 0x4) == 0x4; + public bool SLSMapBezelModeSupported => (SLSMapMask & 0x10) == 0x10; + public bool SLSMapLayoutModeFitSupported => (SLSMapMask & 0x100) == 0x100; + public bool SLSMapLayoutModeFillSupported => (SLSMapMask & 0x200) == 0x200; + public bool SLSMapLayoutModeExpandSupported => (SLSMapMask & 0x400) == 0x400; + public bool SLSMapIsSLSSupported => (SLSMapMask & 0x1000) == 0x1000; + public bool SLSMapIsSLSBuilderSupported => (SLSMapMask & 0x2000) == 0x2000; + public bool SLSMapIsCloneVTSupported => (SLSMapMask & 0x4000) == 0x4000; + + // SLS Map Value settings + public bool SLSMapDisplayArrangedSet => (SLSMapValue & 0x2) == 0x2; + public bool SLSMapCurrentConfigSet => (SLSMapValue & 0x4) == 0x4; + public bool SLSMapBezelModeSet => (SLSMapValue & 0x10) == 0x10; + public bool SLSMapLayoutModeFitSet => (SLSMapValue & 0x100) == 0x100; + public bool SLSMapLayoutModeFillSet => (SLSMapValue & 0x200) == 0x200; + public bool SLSMapLayoutModeExpandSet => (SLSMapValue & 0x400) == 0x400; + public bool SLSMapIsSLSSet => (SLSMapValue & 0x1000) == 0x1000; + public bool SLSMapIsSLSBuilderSet => (SLSMapValue & 0x2000) == 0x2000; + public bool SLSMapIsCloneVTSet => (SLSMapValue & 0x4000) == 0x4000; + +*/ + /*#define ADL_DISPLAY_SLSMAP_DISPLAYARRANGED 0x0002 + #define ADL_DISPLAY_SLSMAP_CURRENTCONFIG 0x0004 + #define ADL_DISPLAY_SLSMAP_BEZELMODE 0x0010 + #define ADL_DISPLAY_SLSMAP_SLSLAYOUTMODE_FIT 0x0100 + #define ADL_DISPLAY_SLSMAP_SLSLAYOUTMODE_FILL 0x0200 + #define ADL_DISPLAY_SLSMAP_SLSLAYOUTMODE_EXPAND 0x0400 + #define ADL_DISPLAY_SLSMAP_IS_SLS 0x1000 + #define ADL_DISPLAY_SLSMAP_IS_SLSBUILDER 0x2000 + #define ADL_DISPLAY_SLSMAP_IS_CLONEVT 0x4000*/ + + public bool Equals(ADL_SLS_MAP other) + => AdapterIndex == other.AdapterIndex && + SLSMapIndex == other.SLSMapIndex && + Grid.Equals(other.Grid) && + SurfaceMapIndex == other.SurfaceMapIndex && + Orientation == other.Orientation && + NumSLSTarget == other.NumSLSTarget && + FirstSLSTargetArrayIndex == other.FirstSLSTargetArrayIndex && + NumNativeMode == other.NumNativeMode && + FirstNativeModeArrayIndex == other.FirstNativeModeArrayIndex && + NumBezelMode == other.NumBezelMode && + FirstBezelModeArrayIndex == other.FirstBezelModeArrayIndex && + NumBezelOffset == other.NumBezelOffset && + FirstBezelOffsetArrayIndex == other.FirstBezelOffsetArrayIndex && + SLSMapMask == other.SLSMapMask && + SLSMapValue == other.SLSMapValue; + + public override int GetHashCode() + { + return (AdapterIndex, SLSMapIndex, Grid, SurfaceMapIndex, Orientation, NumSLSTarget, FirstSLSTargetArrayIndex, NumNativeMode, FirstNativeModeArrayIndex, NumBezelMode, FirstBezelModeArrayIndex, + NumBezelOffset, FirstBezelOffsetArrayIndex, SLSMapMask, SLSMapValue).GetHashCode(); + } + + //public override string ToString() => $"{type.ToString("G")}"; } /// ADLSLSTarget Structure [StructLayout(LayoutKind.Sequential)] - public struct ADLSLSTarget + public struct ADL_SLS_TARGET : IEquatable { /// The Adapter Index public int AdapterIndex; /// The SLS map index. public int SLSMapIndex; /// The target ID. - public ADLDisplayTarget DisplayTarget; + public ADL_DISPLAY_TARGET DisplayTarget; /// Target postion X in SLS grid public int SLSGridPositionX; /// Target postion Y in SLS grid public int SLSGridPositionY; /// The view size width, height and rotation angle per SLS Target. - public ADLMode ViewSize; - /// The bit mask identifies the bits in iSLSTargetValue are currently used. + public ADL_MODE ViewSize; + /// The bit mask identifies the bits in iSLSTargetValue are currently used. Should be set to 1 unless you are using SLS Builder. public int SLSTargetMask; - /// The bit mask identifies status info. - public int SLSTargetValue; - } + /// The bit mask identifies status info. Should be set to 1 unless you are using SLS Builder. + public int SLSTargetValue; - /// ADLSLSTarget Array - [StructLayout(LayoutKind.Sequential)] - public struct ADLSLSTargetArray - { - /// ADLAdapterInfo Array - [MarshalAs(UnmanagedType.ByValArray, SizeConst = (int)ADL.ADL_MAX_ADAPTERS)] - public ADLSLSTarget[] ADLSLSTarget; + + // SLSTargetMask settings + public bool SLSTargetNotSLSBuilderSupported => (SLSTargetMask & 0x1) == 0x1; + + // SLSTargetValue settings + public bool SLSTargetNotSLSBuilderSet => (SLSTargetValue & 0x1) == 0x1; + + public bool Equals(ADL_SLS_TARGET other) + => AdapterIndex == other.AdapterIndex && + SLSMapIndex == other.SLSMapIndex && + DisplayTarget.Equals(other.DisplayTarget) && + SLSGridPositionX == other.SLSGridPositionX && + SLSGridPositionY == other.SLSGridPositionY && + ViewSize.Equals(other.ViewSize) && + SLSTargetMask == other.SLSTargetMask && + SLSTargetValue == other.SLSTargetValue; + + public override int GetHashCode() + { + return (AdapterIndex, SLSMapIndex, DisplayTarget, SLSGridPositionX, SLSGridPositionY, ViewSize, SLSTargetMask, SLSTargetValue).GetHashCode(); + } + + //public override string ToString() => $"{type.ToString("G")}"; } /// ADLSLSMode Structure [StructLayout(LayoutKind.Sequential)] - public struct ADLSLSMode + public struct ADL_SLS_MODE : IEquatable { /// The Adapter Index public int AdapterIndex; @@ -935,17 +1369,31 @@ namespace ATI.ADL /// The mode index. public int SLSModeIndex; /// The target ID. - public ADLMode DisplayMode; + public ADL_MODE DisplayMode; /// The bit mask identifies the number of bits Mode is currently using. public int SLSNativeModeMask; /// The bit mask identifies the display status. public int SLSNativeModeValue; + public bool Equals(ADL_SLS_MODE other) + => AdapterIndex == other.AdapterIndex && + SLSMapIndex == other.SLSMapIndex && + SLSModeIndex == other.SLSModeIndex && + DisplayMode.Equals(other.DisplayMode) && + SLSNativeModeMask == other.SLSNativeModeMask && + SLSNativeModeValue == other.SLSNativeModeValue; + + public override int GetHashCode() + { + return (AdapterIndex, SLSMapIndex, SLSModeIndex, DisplayMode, SLSNativeModeMask, SLSNativeModeValue).GetHashCode(); + } + + //public override string ToString() => $"{type.ToString("G")}"; } /// ADLBezelTransientMode Structure [StructLayout(LayoutKind.Sequential)] - public struct ADLBezelTransientMode + public struct ADL_BEZEL_TRANSIENT_MODE : IEquatable { /// The Adapter Index public int AdapterIndex; @@ -954,7 +1402,7 @@ namespace ATI.ADL /// SLS Mode Index. public int SLSModeIndex; /// The target ID. - public ADLMode DisplayMode; + public ADL_MODE DisplayMode; /// The number of bezel offsets belongs to this map. public int NumBezelOffset; /// The first bezel offset array index in the native mode array. @@ -963,19 +1411,66 @@ namespace ATI.ADL public int SLSBezelTransientModeMask; /// The bit mask identifies the display status. public int SLSBezelTransientModeValue; - + + public bool Equals(ADL_BEZEL_TRANSIENT_MODE other) + => AdapterIndex == other.AdapterIndex && + SLSMapIndex == other.SLSMapIndex && + SLSModeIndex == other.SLSModeIndex && + DisplayMode.Equals(other.DisplayMode) && + NumBezelOffset == other.NumBezelOffset && + FirstBezelOffsetArrayIndex == other.FirstBezelOffsetArrayIndex && + SLSBezelTransientModeMask == other.SLSBezelTransientModeMask && + SLSBezelTransientModeValue == other.SLSBezelTransientModeValue; + + public override int GetHashCode() + { + return (AdapterIndex, SLSMapIndex, SLSModeIndex, DisplayMode, NumBezelOffset, FirstBezelOffsetArrayIndex, SLSBezelTransientModeMask, SLSBezelTransientModeValue).GetHashCode(); + } + + //public override string ToString() => $"{type.ToString("G")}"; } + /// ADLPossibleSLSMap Structure + [StructLayout(LayoutKind.Sequential)] + public struct ADL_POSSIBLE_SLS_MAP : IEquatable + { + /// SLS Map Index. + public int SLSMapIndex; + /// Num SLS Map. + public int NumSLSMap; + /// The SLS Map List. + public ADL_SLS_MAP[] SLSMaps; // Not quite sure this is right + /// The number of SLS Targets + public int NumSLSTarget; + /// The SLS Target List. + public ADL_SLS_TARGET[] SLSTargets; // Not quite sure this is right + + public bool Equals(ADL_POSSIBLE_SLS_MAP other) + => SLSMapIndex == other.SLSMapIndex && + NumSLSMap == other.NumSLSMap && + SLSMaps.Equals(other.SLSMaps) && + NumSLSTarget == other.NumSLSTarget && + SLSTargets.Equals(other.SLSTargets); + + public override int GetHashCode() + { + return (SLSMapIndex, NumSLSMap, SLSMaps, NumSLSTarget, SLSTargets).GetHashCode(); + } + + //public override string ToString() => $"{type.ToString("G")}"; + } + + /// ADLSLSOffset Structure [StructLayout(LayoutKind.Sequential)] - public struct ADLSLSOffset + public struct ADL_SLS_OFFSET : IEquatable { /// The Adapter Index public int AdapterIndex; /// The current display map index. It is the OS Desktop index. public int SLSMapIndex; /// The target ID. - public ADLDisplayID DisplayID; + public ADL_DISPLAY_ID DisplayID; /// SLS Bezel Mode Index. public int BezelModeIndex; /// SLS Bezel Offset X. @@ -990,19 +1485,51 @@ namespace ATI.ADL public int BezelOffsetMask; /// The bit mask identifies the display status. public int BezelOffsetValue; + + // BezelOffsetMask settings + public bool SLSBezelOffsetStepByStepSupported => (BezelOffsetMask & 0x4) == 0x4; + public bool SLSBezelOffsetCommitSupported => (BezelOffsetMask & 0x8) == 0x8; + + // BezelOffsetValue settings + public bool SLSBezelOffsetStepByStepSet => (BezelOffsetValue & 0x4) == 0x4; + public bool SLSBezelOffsetCommitSet => (BezelOffsetValue & 0x8) == 0x8; + + /*#define ADL_DISPLAY_BEZELOFFSET_STEPBYSTEPSET 0x00000004 + #define ADL_DISPLAY_BEZELOFFSET_COMMIT 0x00000008*/ + + public bool Equals(ADL_SLS_OFFSET other) + => AdapterIndex == other.AdapterIndex && + SLSMapIndex == other.SLSMapIndex && + DisplayID.Equals(other.DisplayID) && + BezelModeIndex == other.BezelModeIndex && + BezelOffsetX == other.BezelOffsetX && + BezelOffsetY == other.BezelOffsetY && + DisplayWidth == other.DisplayWidth && + DisplayHeight == other.DisplayHeight && + BezelOffsetMask == other.BezelOffsetMask && + BezelOffsetValue == other.BezelOffsetValue; + + public override int GetHashCode() + { + return (AdapterIndex, SLSMapIndex, DisplayID, BezelModeIndex, BezelOffsetX, BezelOffsetY, DisplayWidth, DisplayHeight, BezelOffsetMask, BezelOffsetValue).GetHashCode(); + } + + //public override string ToString() => $"{type.ToString("G")}"; } - #endregion ADLSLS - #endregion Export Struct - - #region ADL Class - /// ADL Class - public static class ADL + class ADLImport { - #region Internal Constant + + /// Define false + public const int ADL_FALSE = 0; + /// Define true + public const int ADL_TRUE = 1; + /// Selects all adapters instead of aparticular single adapter public const int ADL_ADAPTER_INDEX_ALL = -1; + /// Defines APIs with iOption none + public const int ADL_MAIN_API_OPTION_NONE = 0; /// Define the maximum char public const int ADL_MAX_CHAR = 4096; /// Define the maximum path @@ -1018,45 +1545,7 @@ namespace ATI.ADL /// Define the maximum display names public const int ADL_MAX_DISPLAY_NAME = 256; - // Result Codes - /// ADL function completed successfully. - public const int ADL_OK = 0; - /// Generic Error.Most likely one or more of the Escape calls to the driver failed! - public const int ADL_ERR = -1; - /// Call can't be made due to disabled adapter. - public const int ADL_ERR_DISABLED_ADAPTER = -10; - /// Invalid ADL index passed. - public const int ADL_ERR_INVALID_ADL_IDX = -5; - /// Invalid Callback. - public const int ADL_ERR_INVALID_CALLBACK = -11; - /// Invalid controller index passed. - public const int ADL_ERR_INVALID_CONTROLLER_IDX = -6; - /// Invalid display index passed. - public const int ADL_ERR_INVALID_DISPLAY_IDX = -7; - /// One of the parameter passed is invalid. - public const int ADL_ERR_INVALID_PARAM = -3; - /// One of the parameter size is invalid. - public const int ADL_ERR_INVALID_PARAM_SIZE = -4; - /// There's no Linux XDisplay in Linux Console environment. - public const int ADL_ERR_NO_XDISPLAY = -21; - /// ADL not initialized. - public const int ADL_ERR_NOT_INIT = -2; - /// Function not supported by the driver. - public const int ADL_ERR_NOT_SUPPORTED = -8; - /// Null Pointer error. - public const int ADL_ERR_NULL_POINTER = -9; - /// Display Resource conflict. - public const int ADL_ERR_RESOURCE_CONFLICT = -12; - /// Err Set incomplete - public const int ADL_ERR_SET_INCOMPLETE = -20; - /// All OK but need mode change. - public const int ADL_OK_MODE_CHANGE = 2; - /// All OK, but need restart. - public const int ADL_OK_RESTART = 3; - /// All OK, but need to wait - public const int ADL_OK_WAIT = 4; - /// All OK, but with warning. - public const int ADL_OK_WARNING = 1; + /// Define the driver ok @@ -1067,10 +1556,6 @@ namespace ATI.ADL public const int ADL_MAX_GLSYNC_PORT_LEDS = 8; /// Maximum number of ADLModes for the adapter public const int ADL_MAX_NUM_DISPLAYMODES = 1024; - /// Define true - public const int ADL_TRUE = 1; - /// Maximum number of ADLModes for the adapter - public const int ADL_FALSE = 0; /// Indicates the active dongle, all types public const int ADL_CONNECTION_TYPE_ACTIVE_DONGLE = 12; /// Indicates the Active dongle DP->DVI(double link) connection type is valid. @@ -1214,7 +1699,7 @@ namespace ATI.ADL /// Indicates the display colour format is 565 public const int ADL_DISPLAY_MODE_COLOURFORMAT_565 = 0x00000001; /// Indicates the display colour format is 8888 - public const int ADL_DISPLAY_MODE_COLOURFORMAT_8888 = 0x00000002; + public const int ADL_DISPLAY_MODE_COLOURFORMAT_8888 = 0x00000002; // /// Indicates the display orientation is normal position public const int ADL_DISPLAY_MODE_ORIENTATION_SUPPORTED_000 = 0x00000004; /// Indicates the display is in the 90 degree position @@ -1298,1286 +1783,310 @@ namespace ATI.ADL /// Indicates the display map result supports overlap public const int ADL_DISPLAY_POSSIBLEMAPRESULT_OVERLAPSUPPORTED = 0x00000004; + + //#define ADL_DISPLAY_SLSMAPINDEXLIST_OPTION_ACTIVE 0x00000001 + public const int ADL_DISPLAY_SLSMAPINDEXLIST_OPTION_ACTIVE = 0x00000001; + + + // ADL_DISPLAY_SLSGRID_CAP_OPTION_RELATIVETO_LANDSCAPE Definitions + // for ADL_SLS_MAP.iOption + // (bit-vector) + // Bit vector, specifies the layout type of SLS grid data and portrait flag. + // There are two types of SLS layouts: relative to landscape (ref \ADL_DISPLAY_SLSGRID_CAP_OPTION_RELATIVETO_LANDSCAPE) and relative to current angle(ref \ADL_DISPLAY_SLSGRID_CAP_OPTION_RELATIVETO_CURRENTANGLE). + // If the current desktop associated with the input adapter is rotated to 90 or 270 degree, set bit ref \ADL_DISPLAY_SLSGRID_PORTAIT_MODE to 1 + public const int ADL_DISPLAY_SLSGRID_CAP_OPTION_RELATIVETO_LANDSCAPE = 0x00000001; + public const int ADL_DISPLAY_SLSGRID_CAP_OPTION_RELATIVETO_CURRENTANGLE = 0x00000002; + public const int ADL_DISPLAY_SLSGRID_PORTAIT_MODE = 0x00000004; + public const int ADL_DISPLAY_SLSGRID_KEEPTARGETROTATION = 0x00000080; + + + public const int ADL_DISPLAY_SLSMAPCONFIG_GET_OPTION_RELATIVETO_LANDSCAPE = 0x00000001; + public const int ADL_DISPLAY_SLSMAPCONFIG_GET_OPTION_RELATIVETO_CURRENTANGLE = 0x00000002; + + + public const int ADL_DISPLAY_SLSMAP_SLSLAYOUTMODE_FIT = 0x0100; + public const int ADL_DISPLAY_SLSMAP_SLSLAYOUTMODE_FILL = 0x0200; + public const int ADL_DISPLAY_SLSMAP_SLSLAYOUTMODE_EXPAND = 0x0400; + + public const int ADL_DISPLAY_SLSMAP_IS_SLS = 0x1000; + public const int ADL_DISPLAY_SLSMAP_IS_SLSBUILDER = 0x2000; + public const int ADL_DISPLAY_SLSMAP_IS_CLONEVT = 0x4000; + + + #region Internal Constant + /// Atiadlxx_FileName + public const string ATI_ADL_DLL = "atiadlxx.dll"; + /// Kernel32_FileName + public const string Kernel32_FileName = "kernel32.dll"; #endregion Internal Constant - #region Internal Enums + #region DLLImport + [DllImport(Kernel32_FileName)] + public static extern HMODULE GetModuleHandle(string moduleName); - public enum ADLConnectionType - { - VGA = 0, - DVI = 1, - DVI_SL = 2, - HDMI = 4, - DisplayPort = 4, - ActiveDongleDPToDVI_SL = 5, - ActiveDongleDPToDVI_DL = 6, - ActiveDongleDPToHDMI = 7, - ActiveDongleDPToVGA = 8, - PassiveDongleDPToHDMI = 9, - PassiveDongleDPToDVI = 10, - MST = 11, - ActiveDongle = 12, - Virtual = 13 - } + [DllImport(ATI_ADL_DLL, CallingConvention = CallingConvention.Cdecl)] + public static extern ADL_STATUS ADL2_Main_Control_Create(ADL_Main_Memory_Alloc_Delegate callback, int enumConnectedAdapters, out IntPtr contextHandle); - public enum ADLDisplayConnectionType - { - Unknown = 0, - VGA = 1, - DVI_D = 2, - DVI_I = 3, - HDMI = 4, - ATICV_NTSC_Dongle = 4, - ATICV_JPN_Dongle = 5, - ATICV_NONI2C_NTSC_Dongle = 6, - ATICV_NONI2C_JPN_Dongle = 7, - Proprietary = 8, - HDMITypeA = 10, - HTMITypeB = 11, - SVideo = 12, - Composite = 13, - RCA_3Component = 14, - DisplayPort = 15, - EDP = 16, - WirelessDisplay = 17, - USBTypeC = 18 - } + //typedef int (* ADL2_MAIN_CONTROLX2_CREATE) (ADL_MAIN_MALLOC_CALLBACK, int iEnumConnectedAdapter_, ADL_CONTEXT_HANDLE* context_, ADLThreadingModel); - public enum ADLDisplayModeFlag - { - ColourFormat565 = 1, - ColourFormat8888 = 2, - Degrees0 = 4, - Degrees90 = 8, - Degrees180 = 10, - Degrees270 = 20, - ExactRefreshRate = 80, - RoundedRefreshRate = 40 - } - public enum ADLDisplayModeInterlacing - { - Progressive = 0, - Interlaced = 2 - } - #endregion Internal Enums + //typedef int (* ADL2_MAIN_CONTROL_DESTROY) (ADL_CONTEXT_HANDLE); + [DllImport(ATI_ADL_DLL, CallingConvention = CallingConvention.Cdecl)] + public static extern ADL_STATUS ADL2_Main_Control_Destroy(IntPtr contextHandle); - #region Class ADLImport - /// ADLImport class - private static class ADLImport - { - #region Internal Constant - /// Atiadlxx_FileName - public const string Atiadlxx_FileName = "atiadlxx.dll"; - /// Kernel32_FileName - public const string Kernel32_FileName = "kernel32.dll"; - #endregion Internal Constant - - #region DLLImport - [DllImport(Kernel32_FileName)] - public static extern HMODULE GetModuleHandle (string moduleName); - - [DllImport(Atiadlxx_FileName)] - public static extern int ADL2_Main_Control_Create(ADL_Main_Memory_Alloc callback, int enumConnectedAdapters, out IntPtr contextHandle); - - [DllImport(Atiadlxx_FileName)] - public static extern int ADL2_Main_Control_Destroy(IntPtr contextHandle); - - [DllImport(Atiadlxx_FileName)] - public static extern int ADL2_Flush_Driver_Data(IntPtr ADLContextHandle, int adapterIndex); + // This is used to set the display settings permanently + [DllImport(ATI_ADL_DLL, CallingConvention = CallingConvention.Cdecl)] + public static extern ADL_STATUS ADL2_Flush_Driver_Data(IntPtr ADLContextHandle, int adapterIndex); - [DllImport(Atiadlxx_FileName)] - public static extern int ADL2_Adapter_NumberOfAdapters_Get(IntPtr contextHandle, ref int numAdapters); + // adapter functions + //typedef int (* ADL2_DISPLAY_POSSIBLEMODE_GET) (ADL_CONTEXT_HANDLE, int, int*, ADLMode**); + // This function retrieves the OS possible modes list for a specified input adapter. + [DllImport(ATI_ADL_DLL, CallingConvention = CallingConvention.Cdecl)] + public static extern ADL_STATUS ADL2_Display_PossibleMode_Get(IntPtr ADLContextHandle, int adapterIndex, out int numModes, out IntPtr modes); - [DllImport(Atiadlxx_FileName)] - public static extern int ADL2_Adapter_Active_Get(IntPtr ADLContextHandle, int adapterIndex, ref int status); + //typedef int (* ADL2_ADAPTER_PRIMARY_SET) (ADL_CONTEXT_HANDLE, int); + // This function sets the adapter index for a specified primary display adapter. + [DllImport(ATI_ADL_DLL, CallingConvention = CallingConvention.Cdecl)] + public static extern ADL_STATUS ADL2_Adapter_Primary_Set(IntPtr ADLContextHandle, int primaryAdapterIndex); - [DllImport(Atiadlxx_FileName)] - public static extern int ADL2_AdapterX2_Caps(IntPtr ADLContextHandle, int adapterIndex, out ADLAdapterCapsX2 adapterCapabilities); + //typedef int (* ADL2_ADAPTER_PRIMARY_GET) (ADL_CONTEXT_HANDLE, int*); + // This function retrieves the adapter index for the primary display adapter. + [DllImport(ATI_ADL_DLL, CallingConvention = CallingConvention.Cdecl)] + public static extern ADL_STATUS ADL2_Adapter_Primary_Get(IntPtr ADLContextHandle, out int primaryAdapterIndex); - [DllImport(Atiadlxx_FileName)] - public static extern int ADL2_Adapter_AdapterInfo_Get(IntPtr ADLContextHandle, int inputSize, out IntPtr AdapterInfoArray); - - [DllImport(Atiadlxx_FileName)] - public static extern int ADL2_Adapter_AdapterInfoX2_Get(IntPtr ADLContextHandle, out IntPtr AdapterInfoArray); - - [DllImport(Atiadlxx_FileName)] - public static extern int ADL2_Adapter_AdapterInfoX3_Get(IntPtr ADLContextHandle, int adapterIndex, out int numAdapters, out IntPtr AdapterInfoArray); - - [DllImport(Atiadlxx_FileName)] - public static extern int ADL2_Adapter_AdapterInfoX4_Get(IntPtr ADLContextHandle, int adapterIndex, out int numAdapters, out IntPtr AdapterInfoX2Array); - - [DllImport(Atiadlxx_FileName)] - public static extern int ADL2_Display_DDCInfo2_Get(IntPtr contextHandle, int adapterIndex, int displayIndex, out ADLDDCInfo2 DDCInfo); - - [DllImport(Atiadlxx_FileName)] - public static extern int ADL2_Display_DisplayInfo_Get(IntPtr ADLContextHandle, int adapterIndex, ref int numDisplays, out IntPtr displayInfoArray, int forceDetect); - - [DllImport(Atiadlxx_FileName)] - public static extern int ADL2_Display_DeviceConfig_Get(IntPtr ADLContextHandle, int adapterIndex, int displayIndex, out ADLDisplayConfig displayConfig); - - [DllImport(Atiadlxx_FileName)] - public static extern int ADL2_Display_HDRState_Get(IntPtr ADLContextHandle, int adapterIndex, ADLDisplayID displayID, out int support, out int enable); - - [DllImport(Atiadlxx_FileName)] - public static extern int ADL2_Display_Modes_Get(IntPtr ADLContextHandle, int adapterIndex, int displayIndex, out int numModes, out IntPtr modes); - - [DllImport(Atiadlxx_FileName)] - public static extern int ADL2_Display_Modes_Set(IntPtr ADLContextHandle, int adapterIndex, int displayIndex, int numModes, ref ADLMode modes); - - [DllImport(Atiadlxx_FileName)] - public static extern int ADL2_Display_DisplayMapConfig_Get(IntPtr ADLContextHandle, int adapterIndex, out int numDisplayMap, out IntPtr displayMap, out int numDisplayTarget, out IntPtr displayTarget, int options); - - [DllImport(Atiadlxx_FileName)] - public static extern int ADL2_Display_DisplayMapConfig_Set(IntPtr ADLContextHandle, int adapterIndex, int numDisplayMap, ref ADLDisplayMap displayMap, int numDisplayTarget, ref ADLDisplayTarget displayTarget); - - [DllImport(Atiadlxx_FileName)] - public static extern int ADL2_Display_DisplayMapConfig_Validate(IntPtr ADLContextHandle, int adapterIndex, int numPossibleMap, ref ADLPossibleMap possibleMaps, out int numPossibleMapResult, ref IntPtr possibleMapResult); - - [DllImport(Atiadlxx_FileName)] - public static extern int ADL2_Display_DisplayMapConfig_PossibleAddAndRemove(IntPtr ADLContextHandle, int adapterIndex, int numDisplayMap, ref ADLDisplayMap displayMap, int numDisplayTarget, ref ADLDisplayTarget displayTarget, out int numPossibleAddTarget, out IntPtr possibleAddTarget, out int numPossibleRemoveTarget, out IntPtr possibleRemoveTarget); + //typedef int (* ADL2_ADAPTER_ACTIVE_SET) (ADL_CONTEXT_HANDLE, int, int, int*); + // This function enables or disables extended desktop mode for a specified display. + [DllImport(ATI_ADL_DLL, CallingConvention = CallingConvention.Cdecl)] + public static extern ADL_STATUS ADL2_Adapter_Active_Set(IntPtr ADLContextHandle, int primaryAdapterIndex, int desiredStatus, out int newlyActivated); - // ====================================== + [DllImport(ATI_ADL_DLL, CallingConvention = CallingConvention.Cdecl)] + public static extern ADL_STATUS ADL2_Adapter_NumberOfAdapters_Get(IntPtr contextHandle, out int numAdapters); + + [DllImport(ATI_ADL_DLL, CallingConvention = CallingConvention.Cdecl)] + public static extern ADL_STATUS ADL2_Adapter_Active_Get(IntPtr ADLContextHandle, int adapterIndex, out int status); + + [DllImport(ATI_ADL_DLL, CallingConvention = CallingConvention.Cdecl)] + public static extern ADL_STATUS ADL2_AdapterX2_Caps(IntPtr ADLContextHandle, int adapterIndex, out ADL_ADAPTER_CAPSX2 adapterCapabilities); + + [DllImport(ATI_ADL_DLL, CallingConvention = CallingConvention.Cdecl)] + public static extern ADL_STATUS ADL2_Adapter_AdapterInfo_Get(IntPtr ADLContextHandle, int inputSize, out IntPtr AdapterInfoArray); + + [DllImport(ATI_ADL_DLL, CallingConvention = CallingConvention.Cdecl)] + public static extern ADL_STATUS ADL2_Adapter_AdapterInfoX2_Get(IntPtr ADLContextHandle, out IntPtr AdapterInfoArray); + + //typedef int (* ADL2_ADAPTER_ADAPTERINFOX3_GET) (ADL_CONTEXT_HANDLE context, int iAdapterIndex, int* numAdapters, AdapterInfo** lppAdapterInfo); + [DllImport(ATI_ADL_DLL, CallingConvention = CallingConvention.Cdecl)] + public static extern ADL_STATUS ADL2_Adapter_AdapterInfoX3_Get(IntPtr ADLContextHandle, int adapterIndex, out int numAdapters, out IntPtr AdapterInfoArray); + + [DllImport(ATI_ADL_DLL, CallingConvention = CallingConvention.Cdecl)] + public static extern ADL_STATUS ADL2_Adapter_AdapterInfoX4_Get(IntPtr ADLContextHandle, int adapterIndex, out int numAdapters, out IntPtr AdapterInfoX2Array); + + [DllImport(ATI_ADL_DLL, CallingConvention = CallingConvention.Cdecl)] + public static extern ADL_STATUS ADL2_Display_DDCInfo2_Get(IntPtr contextHandle, int adapterIndex, int displayIndex, out ADL_DDC_INFO2 DDCInfo); + + //typedef int (* ADL2_DISPLAY_DISPLAYINFO_GET) (ADL_CONTEXT_HANDLE context, int iAdapterIndex, int* lpNumDisplays, ADLDisplayInfo** lppInfo, int iForceDetect); + [DllImport(ATI_ADL_DLL, CallingConvention = CallingConvention.Cdecl)] + public static extern ADL_STATUS ADL2_Display_DisplayInfo_Get(IntPtr ADLContextHandle, int adapterIndex, out int numDisplays, out IntPtr displayInfoArray, int forceDetect); + + [DllImport(ATI_ADL_DLL, CallingConvention = CallingConvention.Cdecl)] + public static extern ADL_STATUS ADL2_Display_DeviceConfig_Get(IntPtr ADLContextHandle, int adapterIndex, int displayIndex, out ADL_DISPLAY_CONFIG displayConfig); + + [DllImport(ATI_ADL_DLL, CallingConvention = CallingConvention.Cdecl)] + public static extern ADL_STATUS ADL2_Display_HDRState_Get(IntPtr ADLContextHandle, int adapterIndex, ADL_DISPLAY_ID displayID, out int support, out int enable); + + [DllImport(ATI_ADL_DLL, CallingConvention = CallingConvention.Cdecl)] + public static extern ADL_STATUS ADL2_Display_DisplayMapConfig_PossibleAddAndRemove(IntPtr ADLContextHandle, int adapterIndex, int numDisplayMap, in ADL_DISPLAY_MAP displayMap, int numDisplayTarget, in ADL_DISPLAY_TARGET displayTarget, out int numPossibleAddTarget, out IntPtr possibleAddTarget, out int numPossibleRemoveTarget, out IntPtr possibleRemoveTarget); + + [DllImport(ATI_ADL_DLL, CallingConvention = CallingConvention.Cdecl)] + public static extern ADL_STATUS ADL2_Adapter_Desktop_Caps(IntPtr ADLContextHandle, int adapterIndex, out int DesktopCapsValue, out int DesktopCapsMask); + + // Function to retrieve active desktop supported SLS grid size. + [DllImport(ATI_ADL_DLL, CallingConvention = CallingConvention.Cdecl)] + public static extern ADL_STATUS ADL2_Adapter_Desktop_SupportedSLSGridTypes_Get(IntPtr ADLContextHandle, int adapterIndex, int numDisplayTargetToUse, ref ADL_DISPLAY_TARGET displayTargetToUse, out int numSLSGrid, out ADL_DISPLAY_TARGET SLSGrid, out int option); + + // Function to get the current supported SLS grid patterns (MxN) for a GPU. + // This function gets a list of supported SLS grids for a specified input adapter based on display devices currently connected to the GPU. + [DllImport(ATI_ADL_DLL, CallingConvention = CallingConvention.Cdecl)] + public static extern ADL_STATUS ADL2_Display_SLSGrid_Caps(IntPtr ADLContextHandle, int adapterIndex, ref int NumSLSGrid, out IntPtr SLSGrid, int option); + + // Function to get the active SLS map index list for a given GPU. + // This function retrieves a list of active SLS map indexes for a specified input GPU. + [DllImport(ATI_ADL_DLL, CallingConvention = CallingConvention.Cdecl)] + public static extern ADL_STATUS ADL2_Display_SLSMapIndexList_Get(IntPtr ADLContextHandle, int adapterIndex, ref int numSLSMapIndexList, out IntPtr SLSMapIndexList, int option); + + // Definitions of the used function pointers. Add more if you use other ADL APIs + // SLS functions + //typedef int (* ADL2_DISPLAY_SLSMAPCONFIG_VALID) (ADL_CONTEXT_HANDLE context, int iAdapterIndex, ADLSLSMap slsMap, int iNumDisplayTarget, ADLSLSTarget* lpSLSTarget, int* lpSupportedSLSLayoutImageMode, int* lpReasonForNotSupportSLS, int iOption); + // Function to Set SLS configuration for each display index the controller and the adapter is being mapped to. + [DllImport(ATI_ADL_DLL, CallingConvention = CallingConvention.Cdecl)] + public static extern ADL_STATUS ADL2_Display_SLSMapConfig_Valid(IntPtr ADLContextHandle, int adapterIndex, ADL_SLS_MAP SLSMap, int numDisplayTarget, ADL_DISPLAY_TARGET[] displayTarget, out int supportedSLSLayoutImageMode, out int reasonForNotSupportingSLS, int option); + + //typedef int (* ADL2_DISPLAY_SLSMAPINDEX_GET) (ADL_CONTEXT_HANDLE, int, int, ADLDisplayTarget*, int*); + // Function to get a SLS map index based on a group of displays that are connected in the given adapter. The driver only searches the active SLS grid database. + [DllImport(ATI_ADL_DLL, CallingConvention = CallingConvention.Cdecl)] + public static extern ADL_STATUS ADL2_Display_SLSMapIndex_Get(IntPtr ADLContextHandle, int adapterIndex, int numDisplayTarget, ADL_DISPLAY_TARGET[] displayTarget, out int SLSMapIndex); + + //typedef int (* ADL2_DISPLAY_SLSMAPCONFIG_GET) (ADL_CONTEXT_HANDLE, int, int, ADLSLSMap*, int*, ADLSLSTarget**, int*, ADLSLSMode**, int*, ADLBezelTransientMode**, int*, ADLBezelTransientMode**, int*, ADLSLSOffset**, int); + // This function retrieves an SLS configuration, which includes the, SLS map, SLS targets, SLS standard modes, bezel modes or a transient mode, and offsets. + [DllImport(ATI_ADL_DLL, CallingConvention = CallingConvention.Cdecl)] + public static extern ADL_STATUS ADL2_Display_SLSMapConfig_Get(IntPtr ADLContextHandle, int adapterIndex, int SLSMapIndex, out ADL_SLS_MAP SLSMap, out int NumSLSTarget, out IntPtr SLSTargetArray, out int lpNumNativeMode, out IntPtr NativeMode, out int NumBezelMode, out IntPtr BezelMode, out int NumTransientMode, out IntPtr TransientMode, out int NumSLSOffset, out IntPtr SLSOffset, int iOption); + + // typedef int ADL2_Display_SLSMapConfigX2_Get(ADL_CONTEXT_HANDLE context, int iAdapterIndex, int iSLSMapIndex, ADLSLSMap* lpSLSMap, int* lpNumSLSTarget, ADLSLSTarget** lppSLSTarget, int* lpNumNativeMode, ADLSLSMode** lppNativeMode, int* lpNumNativeModeOffsets, ADLSLSOffset** lppNativeModeOffsets, int* lpNumBezelMode, ADLBezelTransientMode** lppBezelMode, int* lpNumTransientMode, ADLBezelTransientMode** lppTransientMode, int* lpNumSLSOffset, ADLSLSOffset** lppSLSOffset, int iOption) + [DllImport(ATI_ADL_DLL, CallingConvention = CallingConvention.Cdecl)] + public static extern ADL_STATUS ADL2_Display_SLSMapConfigX2_Get(IntPtr ADLContextHandle, int adapterIndex, int SLSMapIndex, out ADL_SLS_MAP SLSMap, out int NumSLSTarget, out IntPtr SLSTargetArray, out int lpNumNativeMode, out IntPtr NativeMode, out int NumNativeModeOffsets, out IntPtr NativeModeOffsets, out int NumBezelMode, out IntPtr BezelMode, out int NumTransientMode, out IntPtr TransientMode, out int NumSLSOffset, out IntPtr SLSOffset, int option); + + //typedef int (* ADL2_DISPLAY_SLSMAPCONFIG_DELETE) (ADL_CONTEXT_HANDLE context, int iAdapterIndex, int iSLSMapIndex); + // This function deletes an SLS map from the driver database based on the input SLS map index. + [DllImport(ATI_ADL_DLL, CallingConvention = CallingConvention.Cdecl)] + public static extern ADL_STATUS ADL_Display_SLSMapConfig_Delete(IntPtr ADLContextHandle, int adapterIndex, int SLSMapIndex); - [DllImport(Atiadlxx_FileName)] - public static extern int ADL_Main_Control_Create (ADL_Main_Memory_Alloc callback, int enumConnectedAdapters); + //typedef int (* ADL2_DISPLAY_SLSMAPCONFIG_CREATE) (ADL_CONTEXT_HANDLE context, int iAdapterIndex, ADLSLSMap SLSMap, int iNumTarget, ADLSLSTarget* lpSLSTarget, int iBezelModePercent, int* lpSLSMapIndex, int iOption); + // This function creates an SLS configuration with a given grid, targets, and bezel mode percent. It will output an SLS map index if the SLS map is successfully created. + [DllImport(ATI_ADL_DLL, CallingConvention = CallingConvention.Cdecl)] + public static extern ADL_STATUS ADL2_Display_SLSMapConfig_Create(IntPtr ADLContextHandle, int adapterIndex, ADL_SLS_MAP[] SLSMap, int numDisplayTarget, ref ADL_DISPLAY_TARGET[] displayTarget, int bezelModePercent, out int SLSMapIndex, int option); - [DllImport(Atiadlxx_FileName)] - public static extern int ADL_Main_Control_Destroy (); - - - [DllImport(Atiadlxx_FileName)] - public static extern int ADL_Main_Control_IsFunctionValid (HMODULE module, string procName); + //typedef int (* ADL2_DISPLAY_SLSMAPCONFIG_REARRANGE) (ADL_CONTEXT_HANDLE, int, int, int, ADLSLSTarget*, ADLSLSMap, int); + [DllImport(ATI_ADL_DLL, CallingConvention = CallingConvention.Cdecl)] + public static extern ADL_STATUS ADL2_Display_SLSMapConfig_Rearrange(IntPtr ADLContextHandle, int adapterIndex, int SLSMapIndex, int numDisplayTarget, ref ADL_DISPLAY_TARGET[] displayTarget, ADL_SLS_MAP[] SLSMap, int option); - [DllImport(Atiadlxx_FileName)] - public static extern FARPROC ADL_Main_Control_GetProcAddress (HMODULE module, string procName); + //typedef int (* ADL2_DISPLAY_SLSMAPCONFIG_SETSTATE) (ADL_CONTEXT_HANDLE, int, int, int); + // This is used to set the SLS Grid we want from the SLSMap by selecting the one we want and supplying that as an index. + [DllImport(ATI_ADL_DLL, CallingConvention = CallingConvention.Cdecl)] + public static extern ADL_STATUS ADL2_Display_SLSMapConfig_SetState(IntPtr ADLContextHandle, int adapterIndex, int SLSMapIndex, int State); - [DllImport(Atiadlxx_FileName)] - public static extern int ADL_Adapter_NumberOfAdapters_Get (ref int numAdapters); - [DllImport(Atiadlxx_FileName)] - public static extern int ADL_Adapter_AdapterInfo_Get (out IntPtr info, int inputSize); + //typedef int ADL2_Display_SLSRecords_Get (ADL_CONTEXT_HANDLE context, int iAdapterIndex, ADLDisplayID displayID, int *lpNumOfRecords, int **lppGridIDList) + // This is used to set the SLS Grid we want from the SLSMap by selecting the one we want and supplying that as an index. + [DllImport(ATI_ADL_DLL, CallingConvention = CallingConvention.Cdecl)] + public static extern ADL_STATUS ADL2_Display_SLSRecords_Get(IntPtr ADLContextHandle, int adapterIndex, ADL_DISPLAY_ID displayID, out int numOfRecords, out IntPtr gridIDList); - [DllImport(Atiadlxx_FileName)] - public static extern int ADL_Adapter_Active_Get(int adapterIndex, ref int status); + //typedef int (* ADL2_DISPLAY_SLSMAPINDEXLIST_GET) (ADL_CONTEXT_HANDLE, int, int*, int**, int); + // This function retrieves a list of active SLS map indexes for a specified input GPU. + [DllImport(ATI_ADL_DLL, CallingConvention = CallingConvention.Cdecl)] + public static extern ADL_STATUS ADL2_Display_SLSMapIndexList_Get(IntPtr ADLContextHandle, int AdapterIndex, out int numSLSMapIndexList, IntPtr SLSMapIndexList, int option); - [DllImport(Atiadlxx_FileName)] - public static extern int ADL_Adapter_ID_Get(int adapterIndex, ref int adapterId); - - [DllImport(Atiadlxx_FileName)] - public static extern int ADL_AdapterX2_Caps(int adapterIndex, out ADLAdapterCapsX2 adapterCapabilities); + //typedef int (* ADL2_DISPLAY_MODES_GET) (ADL_CONTEXT_HANDLE, int, int, int*, ADLMode**); + // This function retrieves the current display mode information. + [DllImport(ATI_ADL_DLL, CallingConvention = CallingConvention.Cdecl)] + public static extern ADL_STATUS ADL2_Display_Modes_Get(IntPtr ADLContextHandle, int adapterIndex, int displayIndex, out int numModes, out IntPtr modes); - [DllImport(Atiadlxx_FileName)] - public static extern int ADL_Display_DisplayInfo_Get(int adapterIndex, ref int numDisplays, out IntPtr displayInfoArray, int forceDetect); - [DllImport(Atiadlxx_FileName)] - public static extern int ADL_Display_DeviceConfig_Get(int adapterIndex, int displayIndex, out ADLDisplayConfig displayConfig); + //typedef int (* ADL2_DISPLAY_MODES_SET) (ADL_CONTEXT_HANDLE, int, int, int, ADLMode*); + // This function sets the current display mode information. + [DllImport(ATI_ADL_DLL, CallingConvention = CallingConvention.Cdecl)] + public static extern ADL_STATUS ADL2_Display_Modes_Set(IntPtr ADLContextHandle, int adapterIndex, int displayIndex, int numModes, ref ADL_MODE modes); - [DllImport(Atiadlxx_FileName)] - public static extern int ADL_Display_EdidData_Get(int adapterIndex, int displayIndex, ref ADLDisplayEDIDData EDIDData); + //typedef int (* ADL2_DISPLAY_BEZELOFFSET_SET) (ADL_CONTEXT_HANDLE, int, int, int, LPADLSLSOffset, ADLSLSMap, int); + [DllImport(ATI_ADL_DLL, CallingConvention = CallingConvention.Cdecl)] + public static extern ADL_STATUS ADL2_Display_BezelOffset_Set(IntPtr ADLContextHandle, int adapterIndex, int SLSMapIndex, int numBezelOffset, ref ADL_SLS_OFFSET displayTargetToUse, ADL_SLS_MAP SLSMap, int option); - [DllImport(Atiadlxx_FileName)] - public static extern int ADL_Display_DisplayMapConfig_Get(int adapterIndex, out int numDisplayMap, out IntPtr displayMap, out int numDisplayTarget, out IntPtr displayTarget, int options); + //display map functions + //typedef int (* ADL2_DISPLAY_DISPLAYMAPCONFIG_GET) (ADL_CONTEXT_HANDLE context, int iAdapterIndex, int* lpNumDisplayMap, ADLDisplayMap** lppDisplayMap, int* lpNumDisplayTarget, ADLDisplayTarget** lppDisplayTarget, int iOptions); + // This function retrieves the current display map configurations, including the controllers and adapters mapped to each display. + [DllImport(ATI_ADL_DLL, CallingConvention = CallingConvention.Cdecl)] + public static extern ADL_STATUS ADL2_Display_DisplayMapConfig_Get(IntPtr ADLContextHandle, int adapterIndex, out int numDisplayMap, out IntPtr displayMap, out int numDisplayTarget, out IntPtr displayTarget, int options); - [DllImport(Atiadlxx_FileName)] - public static extern int ADL_Display_DisplayMapConfig_PossibleAddAndRemove(int adapterIndex, int numDisplayMap, ADLDisplayMap displayMap, int numDisplayTarget, ADLDisplayTarget displayTarget, out int numPossibleAddTarget, out IntPtr possibleAddTarget, out int numPossibleRemoveTarget, out IntPtr possibleRemoveTarget); + //typedef int (* ADL2_DISPLAY_DISPLAYMAPCONFIG_SET) (ADL_CONTEXT_HANDLE, int, int, ADLDisplayMap*, int, ADLDisplayTarget*); + // This function sets the current display configurations for each display, including the controller and adapter mapped to each display. + // Possible display configurations are single, clone, extended desktop, and stretch mode. + // If clone mode is desired and the current display configuration is extended desktop mode, the function disables extended desktop mode in order to enable clone mode. + // If extended display mode is desired and the current display configuration is single mode, this function enables extended desktop. + [DllImport(ATI_ADL_DLL, CallingConvention = CallingConvention.Cdecl)] + public static extern ADL_STATUS ADL2_Display_DisplayMapConfig_Set(IntPtr ADLContextHandle, int adapterIndex, int numDisplayMap, ADL_DISPLAY_MAP[] displayMap, int numDisplayTarget, ADL_DISPLAY_TARGET[] displayTarget); - [DllImport(Atiadlxx_FileName)] - public static extern int ADL_Display_SLSMapConfig_Get(int adapterIndex, int SLSMapIndex, ref ADLSLSMap SLSMap, ref int NumSLSTarget, out IntPtr SLSTargetArray, ref int lpNumNativeMode, out IntPtr NativeMode, ref int NumBezelMode, out IntPtr BezelMode, ref int NumTransientMode, out IntPtr TransientMode, ref int NumSLSOffset, out IntPtr SLSOffset, int iOption); + // This function validate the list of the display configurations for a specified input adapter. This function is applicable to all OS platforms. + [DllImport(ATI_ADL_DLL, CallingConvention = CallingConvention.Cdecl)] + public static extern ADL_STATUS ADL2_Display_DisplayMapConfig_Validate(IntPtr ADLContextHandle, int adapterIndex, int numPossibleMap, ref ADL_POSSIBLE_MAP possibleMaps, out int numPossibleMapResult, out IntPtr possibleMapResult); - // This is used to set the SLS Grid we want from the SLSMap by selecting the one we want and supplying that as an index. - [DllImport(Atiadlxx_FileName)] - public static extern int ADL_Display_SLSMapConfig_SetState(int AdapterIndex, int SLSMapIndex, int State); - // Function to get the current supported SLS grid patterns (MxN) for a GPU. - // This function gets a list of supported SLS grids for a specified input adapter based on display devices currently connected to the GPU. - [DllImport(Atiadlxx_FileName)] - public static extern int ADL_Display_SLSGrid_Caps(int adapterIndex, ref int NumSLSGrid, out IntPtr SLSGrid, int option); + // ====================================== - // Function to get the active SLS map index list for a given GPU. - // This function retrieves a list of active SLS map indexes for a specified input GPU. - [DllImport(Atiadlxx_FileName)] - public static extern int ADL_Display_SLSMapIndexList_Get(int adapterIndex, ref int numSLSMapIndexList, out IntPtr SLSMapIndexList, int options); - // Function to get the active SLS map index list for a given GPU. - // This function retrieves a list of active SLS map indexes for a specified input GPU. - [DllImport(Atiadlxx_FileName)] - public static extern int ADL_Display_SLSMapIndex_Get(int adapterIndex, int ADLNumDisplayTarget, ref ADLDisplayTarget displayTarget, ref int SLSMapIndex); + [DllImport(ATI_ADL_DLL, CallingConvention = CallingConvention.Cdecl)] + public static extern ADL_STATUS ADL_Main_Control_Create(ADL_Main_Memory_Alloc_Delegate callback, int enumConnectedAdapters); - #endregion DLLImport - } - #endregion Class ADLImport + [DllImport(ATI_ADL_DLL, CallingConvention = CallingConvention.Cdecl)] + public static extern ADL_STATUS ADL_Main_Control_Destroy(); - #region Class ADLCheckLibrary - /// ADLCheckLibrary class - private class ADLCheckLibrary - { - #region Private Members - private HMODULE ADLLibrary = System.IntPtr.Zero; - #endregion Private Members - #region Static Members - /// new a private instance - private static ADLCheckLibrary ADLCheckLibrary_ = new ADLCheckLibrary(); - #endregion Static Members + [DllImport(ATI_ADL_DLL, CallingConvention = CallingConvention.Cdecl)] + public static extern ADL_STATUS ADL_Main_Control_IsFunctionValid(HMODULE module, string procName); - #region Constructor - /// Constructor - private ADLCheckLibrary () - { - try - { - if (1 == ADLImport.ADL_Main_Control_IsFunctionValid(IntPtr.Zero, "ADL_Main_Control_Create")) - { - ADLLibrary = ADLImport.GetModuleHandle(ADLImport.Atiadlxx_FileName); - } - } - catch (DllNotFoundException) { } - catch (EntryPointNotFoundException) { } - catch (Exception) { } - } - #endregion Constructor + [DllImport(ATI_ADL_DLL, CallingConvention = CallingConvention.Cdecl)] + public static extern FARPROC ADL_Main_Control_GetProcAddress(HMODULE module, string procName); - #region Destructor - /// Destructor to force calling ADL Destroy function before free up the ADL library - ~ADLCheckLibrary () - { - if (System.IntPtr.Zero != ADLCheckLibrary_.ADLLibrary) - { - ADLImport.ADL_Main_Control_Destroy(); - } - } - #endregion Destructor + [DllImport(ATI_ADL_DLL, CallingConvention = CallingConvention.Cdecl)] + public static extern ADL_STATUS ADL_Adapter_NumberOfAdapters_Get(ref int numAdapters); - #region Static IsFunctionValid - /// Check the import function to see it exists or not - /// function name - /// return true, if function exists - public static bool IsFunctionValid (string functionName) - { - bool result = false; - if (System.IntPtr.Zero != ADLCheckLibrary_.ADLLibrary) - { - if (1 == ADLImport.ADL_Main_Control_IsFunctionValid(ADLCheckLibrary_.ADLLibrary, functionName)) - { - result = true; - } - } - return result; - } - #endregion Static IsFunctionValid + [DllImport(ATI_ADL_DLL, CallingConvention = CallingConvention.Cdecl)] + public static extern ADL_STATUS ADL_Adapter_AdapterInfo_Get(out IntPtr info, int inputSize); - #region Static GetProcAddress - /// Get the unmanaged function pointer - /// function name - /// return function pointer, if function exists - public static FARPROC GetProcAddress (string functionName) - { - FARPROC result = System.IntPtr.Zero; - if (System.IntPtr.Zero != ADLCheckLibrary_.ADLLibrary) - { - result = ADLImport.ADL_Main_Control_GetProcAddress(ADLCheckLibrary_.ADLLibrary, functionName); - } - return result; - } - #endregion Static GetProcAddress - } - #endregion Class ADLCheckLibrary + [DllImport(ATI_ADL_DLL, CallingConvention = CallingConvention.Cdecl)] + public static extern ADL_STATUS ADL_Adapter_Active_Get(int adapterIndex, ref int status); - #region Export Functions + [DllImport(ATI_ADL_DLL, CallingConvention = CallingConvention.Cdecl)] + public static extern ADL_STATUS ADL_Adapter_ID_Get(int adapterIndex, ref int adapterId); - #region ADL_Main_Memory_Alloc - /// Build in memory allocation function - public static ADL_Main_Memory_Alloc ADL_Main_Memory_Alloc = ADL_Main_Memory_Alloc_; + [DllImport(ATI_ADL_DLL, CallingConvention = CallingConvention.Cdecl)] + public static extern ADL_STATUS ADL_AdapterX2_Caps(int adapterIndex, out ADL_ADAPTER_CAPSX2 adapterCapabilities); + + [DllImport(ATI_ADL_DLL, CallingConvention = CallingConvention.Cdecl)] + public static extern ADL_STATUS ADL_Display_DisplayInfo_Get(int adapterIndex, ref int numDisplays, out IntPtr displayInfoArray, int forceDetect); + + [DllImport(ATI_ADL_DLL, CallingConvention = CallingConvention.Cdecl)] + public static extern ADL_STATUS ADL_Display_DeviceConfig_Get(int adapterIndex, int displayIndex, out ADL_DISPLAY_CONFIG displayConfig); + + [DllImport(ATI_ADL_DLL, CallingConvention = CallingConvention.Cdecl)] + public static extern ADL_STATUS ADL_Display_EdidData_Get(int adapterIndex, int displayIndex, ref ADL_DISPLAY_EDID_DATA EDIDData); + + [DllImport(ATI_ADL_DLL, CallingConvention = CallingConvention.Cdecl)] + public static extern ADL_STATUS ADL_Display_DisplayMapConfig_Get(int adapterIndex, out int numDisplayMap, out IntPtr displayMap, out int numDisplayTarget, out IntPtr displayTarget, int options); + + [DllImport(ATI_ADL_DLL, CallingConvention = CallingConvention.Cdecl)] + public static extern ADL_STATUS ADL_Display_DisplayMapConfig_PossibleAddAndRemove(int adapterIndex, int numDisplayMap, ADL_DISPLAY_MAP displayMap, int numDisplayTarget, ADL_DISPLAY_TARGET displayTarget, out int numPossibleAddTarget, out IntPtr possibleAddTarget, out int numPossibleRemoveTarget, out IntPtr possibleRemoveTarget); + + //typedef int (* ADL2_DISPLAY_SLSMAPCONFIG_GET) (ADL_CONTEXT_HANDLE, int, int, ADLSLSMap*, int*, ADLSLSTarget**, int*, ADLSLSMode**, int*, ADLBezelTransientMode**, int*, ADLBezelTransientMode**, int*, ADLSLSOffset**, int); + // This function retrieves an SLS configuration, which includes the, SLS map, SLS targets, SLS standard modes, bezel modes or a transient mode, and offsets. + [DllImport(ATI_ADL_DLL, CallingConvention = CallingConvention.Cdecl)] + public static extern ADL_STATUS ADL_Display_SLSMapConfig_Get(int adapterIndex, int SLSMapIndex, out ADL_SLS_MAP SLSMap, out int NumSLSTarget, out IntPtr SLSTargetArray, out int lpNumNativeMode, out IntPtr NativeMode, out int NumBezelMode, out IntPtr BezelMode, out int NumTransientMode, out IntPtr TransientMode, out int NumSLSOffset, out IntPtr SLSOffset, int iOption); + + // typedef int ADL2_Display_SLSMapConfigX2_Get(ADL_CONTEXT_HANDLE context, int iAdapterIndex, int iSLSMapIndex, ADLSLSMap* lpSLSMap, int* lpNumSLSTarget, ADLSLSTarget** lppSLSTarget, int* lpNumNativeMode, ADLSLSMode** lppNativeMode, int* lpNumNativeModeOffsets, ADLSLSOffset** lppNativeModeOffsets, int* lpNumBezelMode, ADLBezelTransientMode** lppBezelMode, int* lpNumTransientMode, ADLBezelTransientMode** lppTransientMode, int* lpNumSLSOffset, ADLSLSOffset** lppSLSOffset, int iOption) + [DllImport(ATI_ADL_DLL, CallingConvention = CallingConvention.Cdecl)] + public static extern ADL_STATUS ADL_Display_SLSMapConfigX2_Get(int adapterIndex, int SLSMapIndex, out ADL_SLS_MAP SLSMap, out int NumSLSTarget, out IntPtr SLSTargetArray, out int lpNumNativeMode, out IntPtr NativeMode, out int NumNativeModeOffsets, out IntPtr NativeModeOffsets, out int NumBezelMode, out IntPtr BezelMode, out int NumTransientMode, out IntPtr TransientMode, out int NumSLSOffset, out IntPtr SLSOffset, int option); + + // This is used to set the SLS Grid we want from the SLSMap by selecting the one we want and supplying that as an index. + [DllImport(ATI_ADL_DLL, CallingConvention = CallingConvention.Cdecl)] + public static extern ADL_STATUS ADL_Display_SLSMapConfig_SetState(int AdapterIndex, int SLSMapIndex, int State); + + // Function to get the current supported SLS grid patterns (MxN) for a GPU. + // This function gets a list of supported SLS grids for a specified input adapter based on display devices currently connected to the GPU. + [DllImport(ATI_ADL_DLL, CallingConvention = CallingConvention.Cdecl)] + public static extern ADL_STATUS ADL_Display_SLSGrid_Caps(int adapterIndex, ref int NumSLSGrid, out IntPtr SLSGrid, int option); + + // Function to get the active SLS map index list for a given GPU. + // This function retrieves a list of active SLS map indexes for a specified input GPU. + [DllImport(ATI_ADL_DLL, CallingConvention = CallingConvention.Cdecl)] + public static extern ADL_STATUS ADL_Display_SLSMapIndexList_Get(int adapterIndex, ref int numSLSMapIndexList, out IntPtr SLSMapIndexList, int options); + + // Function to get the active SLS map index list for a given GPU. + // This function retrieves a list of active SLS map indexes for a specified input GPU. + [DllImport(ATI_ADL_DLL, CallingConvention = CallingConvention.Cdecl)] + public static extern ADL_STATUS ADL_Display_SLSMapIndex_Get(int adapterIndex, int ADLNumDisplayTarget, ref ADL_DISPLAY_TARGET displayTarget, ref int SLSMapIndex); + + #endregion DLLImport + + public static ADL_Main_Memory_Alloc_Delegate ADL_Main_Memory_Alloc = ADL_Main_Memory_Alloc_Function; /// Build in memory allocation function /// input size /// return the memory buffer - private static IntPtr ADL_Main_Memory_Alloc_ (int size) + public static IntPtr ADL_Main_Memory_Alloc_Function(int size) { + //Console.WriteLine($"\nCallback called with param: {size}"); IntPtr result = Marshal.AllocCoTaskMem(size); return result; } - #endregion ADL_Main_Memory_Alloc - - #region ADL_Main_Memory_Free - /// Build in memory free function - /// input buffer - public static void ADL_Main_Memory_Free (IntPtr buffer) - { - if (IntPtr.Zero != buffer) - { - Marshal.FreeCoTaskMem(buffer); - } - } - #endregion ADL_Main_Memory_Free - - #region ADL2_Main_Control_Create - /// ADL2_Main_Control_Create Delegates - public static ADL2_Main_Control_Create ADL2_Main_Control_Create - { - get - { - if (!ADL2_Main_Control_Create_Check && null == ADL2_Main_Control_Create_) - { - ADL2_Main_Control_Create_Check = true; - if (ADLCheckLibrary.IsFunctionValid("ADL2_Main_Control_Create")) - { - ADL2_Main_Control_Create_ = ADLImport.ADL2_Main_Control_Create; - } - } - return ADL2_Main_Control_Create_; - } - } - /// Private Delegate - private static ADL2_Main_Control_Create ADL2_Main_Control_Create_ = null; - /// check flag to indicate the delegate has been checked - private static bool ADL2_Main_Control_Create_Check = false; - #endregion ADL2_Main_Control_Create - - #region ADL2_Main_Control_Destroy - /// ADL2_Main_Control_Destroy Delegates - public static ADL2_Main_Control_Destroy ADL2_Main_Control_Destroy - { - get - { - if (!ADL2_Main_Control_Destroy_Check && null == ADL2_Main_Control_Destroy_) - { - ADL2_Main_Control_Destroy_Check = true; - if (ADLCheckLibrary.IsFunctionValid("ADL2_Main_Control_Destroy")) - { - ADL2_Main_Control_Destroy_ = ADLImport.ADL2_Main_Control_Destroy; - } - } - return ADL2_Main_Control_Destroy_; - } - } - /// Private Delegate - private static ADL2_Main_Control_Destroy ADL2_Main_Control_Destroy_ = null; - /// check flag to indicate the delegate has been checked - private static bool ADL2_Main_Control_Destroy_Check = false; - #endregion ADL2_Main_Control_Destroy - - #region ADL2_Flush_Driver_Data - /// ADL2_Flush_Driver_Data Delegates - public static ADL2_Flush_Driver_Data ADL2_Flush_Driver_Data - { - get - { - if (!ADL2_Flush_Driver_Data_Check && null == ADL2_Flush_Driver_Data_) - { - ADL2_Flush_Driver_Data_Check = true; - if (ADLCheckLibrary.IsFunctionValid("ADL2_Flush_Driver_Data")) - { - ADL2_Flush_Driver_Data_ = ADLImport.ADL2_Flush_Driver_Data; - } - } - return ADL2_Flush_Driver_Data_; - } - } - /// Private Delegate - private static ADL2_Flush_Driver_Data ADL2_Flush_Driver_Data_ = null; - /// check flag to indicate the delegate has been checked - private static bool ADL2_Flush_Driver_Data_Check = false; - #endregion ADL2_Flush_Driver_Data - - - #region ADL2_Adapter_NumberOfAdapters_Get - /// ADL2_Adapter_NumberOfAdapters_Get Delegates - public static ADL2_Adapter_NumberOfAdapters_Get ADL2_Adapter_NumberOfAdapters_Get - { - get - { - if (!ADL2_Adapter_NumberOfAdapters_Get_Check && null == ADL2_Adapter_NumberOfAdapters_Get_) - { - ADL2_Adapter_NumberOfAdapters_Get_Check = true; - if (ADLCheckLibrary.IsFunctionValid("ADL2_Adapter_NumberOfAdapters_Get")) - { - ADL2_Adapter_NumberOfAdapters_Get_ = ADLImport.ADL2_Adapter_NumberOfAdapters_Get; - } - } - return ADL2_Adapter_NumberOfAdapters_Get_; - } - } - /// Private Delegate - private static ADL2_Adapter_NumberOfAdapters_Get ADL2_Adapter_NumberOfAdapters_Get_ = null; - /// check flag to indicate the delegate has been checked - private static bool ADL2_Adapter_NumberOfAdapters_Get_Check = false; - #endregion ADL2_Adapter_NumberOfAdapters_Get - - #region ADL2_Adapter_Active_Get - /// ADL2_Adapter_Active_Get Delegates - public static ADL2_Adapter_Active_Get ADL2_Adapter_Active_Get - { - get - { - if (!ADL2_Adapter_Active_Get_Check && null == ADL2_Adapter_Active_Get_) - { - ADL2_Adapter_Active_Get_Check = true; - if (ADLCheckLibrary.IsFunctionValid("ADL2_Adapter_Active_Get")) - { - ADL2_Adapter_Active_Get_ = ADLImport.ADL2_Adapter_Active_Get; - } - } - return ADL2_Adapter_Active_Get_; - } - } - /// Private Delegate - private static ADL2_Adapter_Active_Get ADL2_Adapter_Active_Get_ = null; - /// check flag to indicate the delegate has been checked - private static bool ADL2_Adapter_Active_Get_Check = false; - #endregion ADL2_Adapter_Active_Get - - #region ADL2_AdapterX2_Caps - /// ADL2_AdapterX2_Caps Delegates - public static ADL2_AdapterX2_Caps ADL2_AdapterX2_Caps - { - get - { - if (!ADL2_AdapterX2_Caps_Check && null == ADL2_AdapterX2_Caps_) - { - ADL2_AdapterX2_Caps_Check = true; - if (ADLCheckLibrary.IsFunctionValid("ADL2_AdapterX2_Caps")) - { - ADL2_AdapterX2_Caps_ = ADLImport.ADL2_AdapterX2_Caps; - } - } - return ADL2_AdapterX2_Caps_; - } - } - /// Private Delegate - private static ADL2_AdapterX2_Caps ADL2_AdapterX2_Caps_ = null; - /// check flag to indicate the delegate has been checked - private static bool ADL2_AdapterX2_Caps_Check = false; - #endregion ADL2_AdapterX2_Caps - - - #region ADL2_Adapter_AdapterInfo_Get - /// ADL2_Adapter_AdapterInfo_Get Delegates - public static ADL2_Adapter_AdapterInfo_Get ADL2_Adapter_AdapterInfo_Get - { - get - { - if (!ADL2_Adapter_AdapterInfo_Get_Check && null == ADL2_Adapter_AdapterInfo_Get_) - { - ADL2_Adapter_AdapterInfo_Get_Check = true; - if (ADLCheckLibrary.IsFunctionValid("ADL2_Adapter_AdapterInfo_Get")) - { - ADL2_Adapter_AdapterInfo_Get_ = ADLImport.ADL2_Adapter_AdapterInfo_Get; - } - } - return ADL2_Adapter_AdapterInfo_Get_; - } - } - /// Private Delegate - private static ADL2_Adapter_AdapterInfo_Get ADL2_Adapter_AdapterInfo_Get_ = null; - /// check flag to indicate the delegate has been checked - private static bool ADL2_Adapter_AdapterInfo_Get_Check = false; - #endregion ADL2_Adapter_AdapterInfo_Get - - #region ADL2_Adapter_AdapterInfoX2_Get - /// ADL2_Adapter_AdapterInfoX2_Get Delegates - public static ADL2_Adapter_AdapterInfoX2_Get ADL2_Adapter_AdapterInfoX2_Get - { - get - { - if (!ADL2_Adapter_AdapterInfoX2_Get_Check && null == ADL2_Adapter_AdapterInfoX2_Get_) - { - ADL2_Adapter_AdapterInfoX2_Get_Check = true; - if (ADLCheckLibrary.IsFunctionValid("ADL2_Adapter_AdapterInfoX2_Get")) - { - ADL2_Adapter_AdapterInfoX2_Get_ = ADLImport.ADL2_Adapter_AdapterInfoX2_Get; - } - } - return ADL2_Adapter_AdapterInfoX2_Get_; - } - } - /// Private Delegate - private static ADL2_Adapter_AdapterInfoX2_Get ADL2_Adapter_AdapterInfoX2_Get_ = null; - /// check flag to indicate the delegate has been checked - private static bool ADL2_Adapter_AdapterInfoX2_Get_Check = false; - #endregion ADL2_Adapter_AdapterInfoX2_Get - - #region ADL2_Adapter_AdapterInfoX3_Get - /// ADL2_Adapter_AdapterInfoX3_Get Delegates - public static ADL2_Adapter_AdapterInfoX3_Get ADL2_Adapter_AdapterInfoX3_Get - { - get - { - if (!ADL2_Adapter_AdapterInfoX3_Get_Check && null == ADL2_Adapter_AdapterInfoX3_Get_) - { - ADL2_Adapter_AdapterInfoX3_Get_Check = true; - if (ADLCheckLibrary.IsFunctionValid("ADL2_Adapter_AdapterInfoX3_Get")) - { - ADL2_Adapter_AdapterInfoX3_Get_ = ADLImport.ADL2_Adapter_AdapterInfoX3_Get; - } - } - return ADL2_Adapter_AdapterInfoX3_Get_; - } - } - /// Private Delegate - private static ADL2_Adapter_AdapterInfoX3_Get ADL2_Adapter_AdapterInfoX3_Get_ = null; - /// check flag to indicate the delegate has been checked - private static bool ADL2_Adapter_AdapterInfoX3_Get_Check = false; - #endregion ADL2_Adapter_AdapterInfoX3_Get - - #region ADL2_Adapter_AdapterInfoX4_Get - /// ADL2_Adapter_AdapterInfoX4_Get Delegates - public static ADL2_Adapter_AdapterInfoX4_Get ADL2_Adapter_AdapterInfoX4_Get - { - get - { - if (!ADL2_Adapter_AdapterInfoX4_Get_Check && null == ADL2_Adapter_AdapterInfoX4_Get_) - { - ADL2_Adapter_AdapterInfoX4_Get_Check = true; - if (ADLCheckLibrary.IsFunctionValid("ADL2_Adapter_AdapterInfoX4_Get")) - { - ADL2_Adapter_AdapterInfoX4_Get_ = ADLImport.ADL2_Adapter_AdapterInfoX4_Get; - } - } - return ADL2_Adapter_AdapterInfoX4_Get_; - } - } - /// Private Delegate - private static ADL2_Adapter_AdapterInfoX4_Get ADL2_Adapter_AdapterInfoX4_Get_ = null; - /// check flag to indicate the delegate has been checked - private static bool ADL2_Adapter_AdapterInfoX4_Get_Check = false; - #endregion ADL2_Adapter_AdapterInfoX4_Get - - #region ADL2_Display_DDCInfo2_Get - /// ADL2_Display_DDCInfo2_Get Delegates - public static ADL2_Display_DDCInfo2_Get ADL2_Display_DDCInfo2_Get - { - get - { - if (!ADL2_Display_DDCInfo2_Get_Check && null == ADL2_Display_DDCInfo2_Get_) - { - ADL2_Display_DDCInfo2_Get_Check = true; - if (ADLCheckLibrary.IsFunctionValid("ADL2_Display_DDCInfo2_Get")) - { - ADL2_Display_DDCInfo2_Get_ = ADLImport.ADL2_Display_DDCInfo2_Get; - } - } - return ADL2_Display_DDCInfo2_Get_; - } - } - /// Private Delegate - private static ADL2_Display_DDCInfo2_Get ADL2_Display_DDCInfo2_Get_ = null; - /// check flag to indicate the delegate has been checked - private static bool ADL2_Display_DDCInfo2_Get_Check = false; - #endregion ADL2_Display_DDCInfo2_Get - - #region ADL2_Display_DisplayInfo_Get - /// ADL2_Display_DisplayInfo_Get Delegates - public static ADL2_Display_DisplayInfo_Get ADL2_Display_DisplayInfo_Get - { - get - { - if (!ADL2_Display_DisplayInfo_Get_Check && null == ADL2_Display_DisplayInfo_Get_) - { - ADL2_Display_DisplayInfo_Get_Check = true; - if (ADLCheckLibrary.IsFunctionValid("ADL2_Display_DisplayInfo_Get")) - { - ADL2_Display_DisplayInfo_Get_ = ADLImport.ADL2_Display_DisplayInfo_Get; - } - } - return ADL2_Display_DisplayInfo_Get_; - } - } - /// Private Delegate - private static ADL2_Display_DisplayInfo_Get ADL2_Display_DisplayInfo_Get_ = null; - /// check flag to indicate the delegate has been checked - private static bool ADL2_Display_DisplayInfo_Get_Check = false; - #endregion ADL2_Display_DisplayInfo_Get - - #region ADL2_Display_DeviceConfig_Get - /// ADL2_Display_DeviceConfig_Get Delegates - public static ADL2_Display_DeviceConfig_Get ADL2_Display_DeviceConfig_Get - { - get - { - if (!ADL2_Display_DeviceConfig_Get_Check && null == ADL2_Display_DeviceConfig_Get_) - { - ADL2_Display_DeviceConfig_Get_Check = true; - if (ADLCheckLibrary.IsFunctionValid("ADL2_Display_DeviceConfig_Get")) - { - ADL2_Display_DeviceConfig_Get_ = ADLImport.ADL2_Display_DeviceConfig_Get; - } - } - return ADL2_Display_DeviceConfig_Get_; - } - } - /// Private Delegate - private static ADL2_Display_DeviceConfig_Get ADL2_Display_DeviceConfig_Get_ = null; - /// check flag to indicate the delegate has been checked - private static bool ADL2_Display_DeviceConfig_Get_Check = false; - #endregion ADL2_Display_DeviceConfig_Get - - #region ADL2_Display_HDRState_Get - /// ADL2_Display_HDRState_Get Delegates - public static ADL2_Display_HDRState_Get ADL2_Display_HDRState_Get - { - get - { - if (!ADL2_Display_HDRState_Get_Check && null == ADL2_Display_HDRState_Get_) - { - ADL2_Display_HDRState_Get_Check = true; - if (ADLCheckLibrary.IsFunctionValid("ADL2_Display_HDRState_Get")) - { - ADL2_Display_HDRState_Get_ = ADLImport.ADL2_Display_HDRState_Get; - } - } - return ADL2_Display_HDRState_Get_; - } - } - /// Private Delegate - private static ADL2_Display_HDRState_Get ADL2_Display_HDRState_Get_ = null; - /// check flag to indicate the delegate has been checked - private static bool ADL2_Display_HDRState_Get_Check = false; - #endregion ADL2_Display_HDRState_Get - - #region ADL2_Display_Modes_Get - /// ADL2_Display_Modes_Get Delegates - public static ADL2_Display_Modes_Get ADL2_Display_Modes_Get - { - get - { - if (!ADL2_Display_Modes_Get_Check && null == ADL2_Display_Modes_Get_) - { - ADL2_Display_Modes_Get_Check = true; - if (ADLCheckLibrary.IsFunctionValid("ADL2_Display_Modes_Get")) - { - ADL2_Display_Modes_Get_ = ADLImport.ADL2_Display_Modes_Get; - } - } - return ADL2_Display_Modes_Get_; - } - } - /// Private Delegate - private static ADL2_Display_Modes_Get ADL2_Display_Modes_Get_ = null; - /// check flag to indicate the delegate has been checked - private static bool ADL2_Display_Modes_Get_Check = false; - #endregion ADL2_Display_Modes_Get - - #region ADL2_Display_Modes_Set - /// ADL2_Display_Modes_Set Delegates - public static ADL2_Display_Modes_Set ADL2_Display_Modes_Set - { - get - { - if (!ADL2_Display_Modes_Set_Check && null == ADL2_Display_Modes_Set_) - { - ADL2_Display_Modes_Set_Check = true; - if (ADLCheckLibrary.IsFunctionValid("ADL2_Display_Modes_Set")) - { - ADL2_Display_Modes_Set_ = ADLImport.ADL2_Display_Modes_Set; - } - } - return ADL2_Display_Modes_Set_; - } - } - /// Private Delegate - private static ADL2_Display_Modes_Set ADL2_Display_Modes_Set_ = null; - /// check flag to indicate the delegate has been checked - private static bool ADL2_Display_Modes_Set_Check = false; - #endregion ADL2_Display_Modes_Set - - #region ADL2_Display_DisplayMapConfig_Get - public static ADL2_Display_DisplayMapConfig_Get ADL2_Display_DisplayMapConfig_Get - { - get - { - if (!ADL2_Display_DisplayMapConfig_Get_Check && null == ADL2_Display_DisplayMapConfig_Get_) - { - ADL2_Display_DisplayMapConfig_Get_Check = true; - if (ADLCheckLibrary.IsFunctionValid("ADL2_Display_DisplayMapConfig_Get")) - { - ADL2_Display_DisplayMapConfig_Get_ = ADLImport.ADL2_Display_DisplayMapConfig_Get; - } - } - return ADL2_Display_DisplayMapConfig_Get_; - } - } - /// Private Delegate - private static ADL2_Display_DisplayMapConfig_Get ADL2_Display_DisplayMapConfig_Get_ = null; - /// check flag to indicate the delegate has been checked - private static bool ADL2_Display_DisplayMapConfig_Get_Check = false; - #endregion ADL2_Display_DisplayMapConfig_Get - - #region ADL2_Display_DisplayMapConfig_Set - /// ADL2_Display_DisplayMapConfig_Set Delegates - public static ADL2_Display_DisplayMapConfig_Set ADL2_Display_DisplayMapConfig_Set - { - get - { - if (!ADL2_Display_DisplayMapConfig_Set_Check && null == ADL2_Display_DisplayMapConfig_Set_) - { - ADL2_Display_DisplayMapConfig_Set_Check = true; - if (ADLCheckLibrary.IsFunctionValid("ADL2_Display_DisplayMapConfig_Set")) - { - ADL2_Display_DisplayMapConfig_Set_ = ADLImport.ADL2_Display_DisplayMapConfig_Set; - } - } - return ADL2_Display_DisplayMapConfig_Set_; - } - } - /// Private Delegate - private static ADL2_Display_DisplayMapConfig_Set ADL2_Display_DisplayMapConfig_Set_ = null; - /// check flag to indicate the delegate has been checked - private static bool ADL2_Display_DisplayMapConfig_Set_Check = false; - #endregion ADL2_Display_DisplayMapConfig_Set - - #region ADL2_Display_DisplayMapConfig_Validate - /// ADL2_Display_DisplayMapConfig_Validate Delegates - public static ADL2_Display_DisplayMapConfig_Validate ADL2_Display_DisplayMapConfig_Validate - { - get - { - if (!ADL2_Display_DisplayMapConfig_Validate_Check && null == ADL2_Display_DisplayMapConfig_Validate_) - { - ADL2_Display_DisplayMapConfig_Validate_Check = true; - if (ADLCheckLibrary.IsFunctionValid("ADL2_Display_DisplayMapConfig_Validate")) - { - ADL2_Display_DisplayMapConfig_Validate_ = ADLImport.ADL2_Display_DisplayMapConfig_Validate; - } - } - return ADL2_Display_DisplayMapConfig_Validate_; - } - } - /// Private Delegate - private static ADL2_Display_DisplayMapConfig_Validate ADL2_Display_DisplayMapConfig_Validate_ = null; - /// check flag to indicate the delegate has been checked - private static bool ADL2_Display_DisplayMapConfig_Validate_Check = false; - #endregion ADL2_Display_DisplayMapConfig_Validate - - #region ADL2_Display_DisplayMapConfig_PossibleAddAndRemove - /// ADL2_Display_DisplayMapConfig_PossibleAddAndRemove Delegates - public static ADL2_Display_DisplayMapConfig_PossibleAddAndRemove ADL2_Display_DisplayMapConfig_PossibleAddAndRemove - { - get - { - if (!ADL2_Display_DisplayMapConfig_PossibleAddAndRemove_Check && null == ADL2_Display_DisplayMapConfig_PossibleAddAndRemove_) - { - ADL2_Display_DisplayMapConfig_PossibleAddAndRemove_Check = true; - if (ADLCheckLibrary.IsFunctionValid("ADL2_Display_DisplayMapConfig_PossibleAddAndRemove")) - { - ADL2_Display_DisplayMapConfig_PossibleAddAndRemove_ = ADLImport.ADL2_Display_DisplayMapConfig_PossibleAddAndRemove; - } - } - return ADL2_Display_DisplayMapConfig_PossibleAddAndRemove_; - } - } - /// Private Delegate - private static ADL2_Display_DisplayMapConfig_PossibleAddAndRemove ADL2_Display_DisplayMapConfig_PossibleAddAndRemove_ = null; - /// check flag to indicate the delegate has been checked - private static bool ADL2_Display_DisplayMapConfig_PossibleAddAndRemove_Check = false; - #endregion ADL2_Display_DisplayMapConfig_PossibleAddAndRemove - - // ================================ - - #region ADL_Main_Control_Create - /// ADL_Main_Control_Create Delegates - public static ADL_Main_Control_Create ADL_Main_Control_Create - { - get - { - if (!ADL_Main_Control_Create_Check && null == ADL_Main_Control_Create_) - { - ADL_Main_Control_Create_Check = true; - if (ADLCheckLibrary.IsFunctionValid("ADL_Main_Control_Create")) - { - ADL_Main_Control_Create_ = ADLImport.ADL_Main_Control_Create; - } - } - return ADL_Main_Control_Create_; - } - } - /// Private Delegate - private static ADL_Main_Control_Create ADL_Main_Control_Create_ = null; - /// check flag to indicate the delegate has been checked - private static bool ADL_Main_Control_Create_Check = false; - #endregion ADL_Main_Control_Create - - #region ADL_Main_Control_Destroy - /// ADL_Main_Control_Destroy Delegates - public static ADL_Main_Control_Destroy ADL_Main_Control_Destroy - { - get - { - if (!ADL_Main_Control_Destroy_Check && null == ADL_Main_Control_Destroy_) - { - ADL_Main_Control_Destroy_Check = true; - if (ADLCheckLibrary.IsFunctionValid("ADL_Main_Control_Destroy")) - { - ADL_Main_Control_Destroy_ = ADLImport.ADL_Main_Control_Destroy; - } - } - return ADL_Main_Control_Destroy_; - } - } - /// Private Delegate - private static ADL_Main_Control_Destroy ADL_Main_Control_Destroy_ = null; - /// check flag to indicate the delegate has been checked - private static bool ADL_Main_Control_Destroy_Check = false; - #endregion ADL_Main_Control_Destroy - - #region ADL_Adapter_NumberOfAdapters_Get - /// ADL_Adapter_NumberOfAdapters_Get Delegates - public static ADL_Adapter_NumberOfAdapters_Get ADL_Adapter_NumberOfAdapters_Get - { - get - { - if (!ADL_Adapter_NumberOfAdapters_Get_Check && null == ADL_Adapter_NumberOfAdapters_Get_) - { - ADL_Adapter_NumberOfAdapters_Get_Check = true; - if (ADLCheckLibrary.IsFunctionValid("ADL_Adapter_NumberOfAdapters_Get")) - { - ADL_Adapter_NumberOfAdapters_Get_ = ADLImport.ADL_Adapter_NumberOfAdapters_Get; - } - } - return ADL_Adapter_NumberOfAdapters_Get_; - } - } - /// Private Delegate - private static ADL_Adapter_NumberOfAdapters_Get ADL_Adapter_NumberOfAdapters_Get_ = null; - /// check flag to indicate the delegate has been checked - private static bool ADL_Adapter_NumberOfAdapters_Get_Check = false; - #endregion ADL_Adapter_NumberOfAdapters_Get - - #region ADL_Adapter_ID_Get - - /// ADL_Adapter_Active_Get Delegates - public static ADL_Adapter_ID_Get ADL_Adapter_ID_Get - { - get - { - if (!ADL_Adapter_ID_Get_Check && null == ADL_Adapter_ID_Get_) - { - ADL_Adapter_ID_Get_Check = true; - if (ADLCheckLibrary.IsFunctionValid("ADL_Adapter_ID_Get")) - { - ADL_Adapter_ID_Get_ = ADLImport.ADL_Adapter_ID_Get; - } - } - return ADL_Adapter_ID_Get_; - } - } - /// Private Delegate - private static ADL_Adapter_ID_Get ADL_Adapter_ID_Get_ = null; - /// check flag to indicate the delegate has been checked - private static bool ADL_Adapter_ID_Get_Check = false; - #endregion ADL_Adapter_ID_Get - - #region ADL_AdapterX2_Caps - /// ADL_AdapterX2_Caps Delegates - public static ADL_AdapterX2_Caps ADL_AdapterX2_Caps - { - get - { - if (!ADL_AdapterX2_Caps_Check && null == ADL_AdapterX2_Caps_) - { - ADL_AdapterX2_Caps_Check = true; - if (ADLCheckLibrary.IsFunctionValid("ADL_AdapterX2_Caps")) - { - ADL_AdapterX2_Caps_ = ADLImport.ADL_AdapterX2_Caps; - } - } - return ADL_AdapterX2_Caps_; - } - } - /// Private Delegate - private static ADL_AdapterX2_Caps ADL_AdapterX2_Caps_ = null; - /// check flag to indicate the delegate has been checked - private static bool ADL_AdapterX2_Caps_Check = false; - #endregion ADL_AdapterX2_Caps - - #region ADL_Adapter_AdapterInfo_Get - /// ADL_Adapter_AdapterInfo_Get Delegates - public static ADL_Adapter_AdapterInfo_Get ADL_Adapter_AdapterInfo_Get - { - get - { - if (!ADL_Adapter_AdapterInfo_Get_Check && null == ADL_Adapter_AdapterInfo_Get_) - { - ADL_Adapter_AdapterInfo_Get_Check = true; - if (ADLCheckLibrary.IsFunctionValid("ADL_Adapter_AdapterInfo_Get")) - { - ADL_Adapter_AdapterInfo_Get_ = ADLImport.ADL_Adapter_AdapterInfo_Get; - } - } - return ADL_Adapter_AdapterInfo_Get_; - } - } - /// Private Delegate - private static ADL_Adapter_AdapterInfo_Get ADL_Adapter_AdapterInfo_Get_ = null; - /// check flag to indicate the delegate has been checked - private static bool ADL_Adapter_AdapterInfo_Get_Check = false; - #endregion ADL_Adapter_AdapterInfo_Get - - #region ADL_Adapter_Active_Get - /// ADL_Adapter_Active_Get Delegates - public static ADL_Adapter_Active_Get ADL_Adapter_Active_Get - { - get - { - if (!ADL_Adapter_Active_Get_Check && null == ADL_Adapter_Active_Get_) - { - ADL_Adapter_Active_Get_Check = true; - if (ADLCheckLibrary.IsFunctionValid("ADL_Adapter_Active_Get")) - { - ADL_Adapter_Active_Get_ = ADLImport.ADL_Adapter_Active_Get; - } - } - return ADL_Adapter_Active_Get_; - } - } - /// Private Delegate - private static ADL_Adapter_Active_Get ADL_Adapter_Active_Get_ = null; - /// check flag to indicate the delegate has been checked - private static bool ADL_Adapter_Active_Get_Check = false; - #endregion ADL_Adapter_Active_Get - - #region ADL_Display_DeviceConfig_Get - /// ADL_Display_DeviceConfig_Get Delegates - public static ADL_Display_DeviceConfig_Get ADL_Display_DeviceConfig_Get - { - get - { - if (!ADL_Display_DeviceConfig_Get_Check && null == ADL_Display_DeviceConfig_Get_) - { - ADL_Display_DeviceConfig_Get_Check = true; - if (ADLCheckLibrary.IsFunctionValid("ADL_Display_DeviceConfig_Get")) - { - ADL_Display_DeviceConfig_Get_ = ADLImport.ADL_Display_DeviceConfig_Get; - } - } - return ADL_Display_DeviceConfig_Get_; - } - } - /// Private Delegate - private static ADL_Display_DeviceConfig_Get ADL_Display_DeviceConfig_Get_ = null; - /// check flag to indicate the delegate has been checked - private static bool ADL_Display_DeviceConfig_Get_Check = false; - #endregion ADL_Display_DeviceConfig_Get - - #region ADL_Display_DisplayMapConfig_Get - /// ADL_Display_DisplayMapConfig_Get Delegates - public static ADL_Display_DisplayMapConfig_Get ADL_Display_DisplayMapConfig_Get - { - get - { - if (!ADL_Display_DisplayMapConfig_Get_Check && null == ADL_Display_DisplayMapConfig_Get_) - { - ADL_Display_DisplayMapConfig_Get_Check = true; - if (ADLCheckLibrary.IsFunctionValid("ADL_Display_DisplayMapConfig_Get")) - { - ADL_Display_DisplayMapConfig_Get_ = ADLImport.ADL_Display_DisplayMapConfig_Get; - } - } - return ADL_Display_DisplayMapConfig_Get_; - } - } - /// Private Delegate - private static ADL_Display_DisplayMapConfig_Get ADL_Display_DisplayMapConfig_Get_ = null; - /// check flag to indicate the delegate has been checked - private static bool ADL_Display_DisplayMapConfig_Get_Check = false; - #endregion ADL_Display_DisplayMapConfig_Get - - #region ADL_Display_DisplayMapConfig_PossibleAddAndRemove - /// ADL_Display_DisplayMapConfig_PossibleAddAndRemove Delegates - public static ADL_Display_DisplayMapConfig_PossibleAddAndRemove ADL_Display_DisplayMapConfig_PossibleAddAndRemove - { - get - { - if (!ADL_Display_DisplayMapConfig_PossibleAddAndRemove_Check && null == ADL_Display_DisplayMapConfig_PossibleAddAndRemove_) - { - ADL_Display_DisplayMapConfig_PossibleAddAndRemove_Check = true; - if (ADLCheckLibrary.IsFunctionValid("ADL_Display_DisplayMapConfig_PossibleAddAndRemove")) - { - ADL_Display_DisplayMapConfig_PossibleAddAndRemove_ = ADLImport.ADL_Display_DisplayMapConfig_PossibleAddAndRemove; - } - } - return ADL_Display_DisplayMapConfig_PossibleAddAndRemove_; - } - } - /// Private Delegate - private static ADL_Display_DisplayMapConfig_PossibleAddAndRemove ADL_Display_DisplayMapConfig_PossibleAddAndRemove_ = null; - /// check flag to indicate the delegate has been checked - private static bool ADL_Display_DisplayMapConfig_PossibleAddAndRemove_Check = false; - #endregion ADL_Display_DisplayMapConfig_PossibleAddAndRemove - - - #region ADL_Display_EdidData_Get - /// ADL_Display_EdidData_Get Delegates - public static ADL_Display_EdidData_Get ADL_Display_EdidData_Get - { - get - { - if (!ADL_Display_EdidData_Get_Check && null == ADL_Display_EdidData_Get_) - { - ADL_Display_EdidData_Get_Check = true; - if (ADLCheckLibrary.IsFunctionValid("ADL_Display_EdidData_Get")) - { - ADL_Display_EdidData_Get_ = ADLImport.ADL_Display_EdidData_Get; - } - } - return ADL_Display_EdidData_Get_; - } - } - /// Private Delegate - private static ADL_Display_EdidData_Get ADL_Display_EdidData_Get_ = null; - /// check flag to indicate the delegate has been checked - private static bool ADL_Display_EdidData_Get_Check = false; - #endregion ADL_Display_EdidData_Get - - - #region ADL_Display_DisplayInfo_Get - /// ADL_Display_DisplayInfo_Get Delegates - public static ADL_Display_DisplayInfo_Get ADL_Display_DisplayInfo_Get - { - get - { - if (!ADL_Display_DisplayInfo_Get_Check && null == ADL_Display_DisplayInfo_Get_) - { - ADL_Display_DisplayInfo_Get_Check = true; - if (ADLCheckLibrary.IsFunctionValid("ADL_Display_DisplayInfo_Get")) - { - ADL_Display_DisplayInfo_Get_ = ADLImport.ADL_Display_DisplayInfo_Get; - } - } - return ADL_Display_DisplayInfo_Get_; - } - } - /// Private Delegate - private static ADL_Display_DisplayInfo_Get ADL_Display_DisplayInfo_Get_ = null; - /// check flag to indicate the delegate has been checked - private static bool ADL_Display_DisplayInfo_Get_Check = false; - #endregion ADL_Display_DisplayInfo_Get - - - #region ADL_Display_SLSMapConfig_Get - /// ADL_Display_SLSMapConfig_Get Delegates - public static ADL_Display_SLSMapConfig_Get ADL_Display_SLSMapConfig_Get - { - get - { - if (!ADL_Display_SLSMapConfig_Get_Check && null == ADL_Display_SLSMapConfig_Get_) - { - ADL_Display_SLSMapConfig_Get_Check = true; - if (ADLCheckLibrary.IsFunctionValid("ADL_Display_SLSMapConfig_Get")) - { - ADL_Display_SLSMapConfig_Get_ = ADLImport.ADL_Display_SLSMapConfig_Get; - } - } - return ADL_Display_SLSMapConfig_Get_; - } - } - /// Private Delegate - private static ADL_Display_SLSMapConfig_Get ADL_Display_SLSMapConfig_Get_ = null; - /// check flag to indicate the delegate has been checked - private static bool ADL_Display_SLSMapConfig_Get_Check = false; - #endregion ADL_Display_SLSMapConfig_Get - - - #endregion Export Functions - - #region ADL Helper Functions - - public static ConvertedDDCInfoFlag ConvertDDCInfoFlag(int DDCInfoValue) - { - ConvertedDDCInfoFlag expandedDDCInfoValue = new ConvertedDDCInfoFlag(); - - // Indicates the display is a digital device - if ((DDCInfoValue & ADL.ADL_DISPLAYDDCINFOEX_FLAG_DIGITALDEVICE) == ADL.ADL_DISPLAYDDCINFOEX_FLAG_DIGITALDEVICE) - expandedDDCInfoValue.DIGITALDEVICE = true; - // Indicates the display supports EDID queries - if ((DDCInfoValue & ADL.ADL_DISPLAYDDCINFOEX_FLAG_EDIDEXTENSION) == ADL.ADL_DISPLAYDDCINFOEX_FLAG_EDIDEXTENSION) - expandedDDCInfoValue.EDIDEXTENSION = true; - // Indicates the display suports HDMI Audio - if ((DDCInfoValue & ADL.ADL_DISPLAYDDCINFOEX_FLAG_HDMIAUDIODEVICE) == ADL.ADL_DISPLAYDDCINFOEX_FLAG_HDMIAUDIODEVICE) - expandedDDCInfoValue.HDMIAUDIODEVICE = true; - // Indicates the display is a projector - if ((DDCInfoValue & ADL.ADL_DISPLAYDDCINFOEX_FLAG_PROJECTORDEVICE) == ADL.ADL_DISPLAYDDCINFOEX_FLAG_PROJECTORDEVICE) - expandedDDCInfoValue.PROJECTORDEVICE = true; - // Indicates the display supports AI - if ((DDCInfoValue & ADL.ADL_DISPLAYDDCINFOEX_FLAG_SUPPORTS_AI) == ADL.ADL_DISPLAYDDCINFOEX_FLAG_SUPPORTS_AI) - expandedDDCInfoValue.SUPPORTS_AI = true; - // Indicates the display supports YCC601 - if ((DDCInfoValue & ADL.ADL_DISPLAYDDCINFOEX_FLAG_SUPPORT_xvYCC601) == ADL.ADL_DISPLAYDDCINFOEX_FLAG_SUPPORT_xvYCC601) - expandedDDCInfoValue.SUPPORT_xvYCC601 = true; - // Indicates the display supports YCC709 - if ((DDCInfoValue & ADL.ADL_DISPLAYDDCINFOEX_FLAG_SUPPORT_xvYCC709) == ADL.ADL_DISPLAYDDCINFOEX_FLAG_SUPPORT_xvYCC709) - expandedDDCInfoValue.SUPPORT_xvYCC709 = true; - - return expandedDDCInfoValue; - - } - - public static ConvertedSupportedHDR ConvertSupportedHDR(int supportedHDR) - { - ConvertedSupportedHDR expandedSupportedHDR = new ConvertedSupportedHDR(); - - // Indicates the display is a digital device - if ((supportedHDR & ADL.ADL_HDR_CEA861_3) == ADL.ADL_HDR_CEA861_3) - expandedSupportedHDR.CEA861_3 = true; - // Indicates the display supports EDID queries - if ((supportedHDR & ADL.ADL_HDR_DOLBYVISION) == ADL.ADL_HDR_DOLBYVISION) - expandedSupportedHDR.DOLBYVISION = true; - // Indicates the display suports HDMI Audio - if ((supportedHDR & ADL.ADL_HDR_FREESYNC_HDR) == ADL.ADL_HDR_FREESYNC_HDR) - expandedSupportedHDR.FREESYNC_HDR = true; - - return expandedSupportedHDR; - - } - - public static ConvertedDisplayInfoValue ConvertDisplayInfoValue(int displayInfoValue) - { - ConvertedDisplayInfoValue expandedDisplayInfoValue = new ConvertedDisplayInfoValue(); - - // Indicates the display is connected - if ((displayInfoValue & ADL.ADL_DISPLAY_DISPLAYINFO_DISPLAYCONNECTED) == ADL.ADL_DISPLAY_DISPLAYINFO_DISPLAYCONNECTED) - expandedDisplayInfoValue.DISPLAYCONNECTED = true; - // Indicates the display is mapped within OS - if ((displayInfoValue & ADL.ADL_DISPLAY_DISPLAYINFO_DISPLAYMAPPED) == ADL.ADL_DISPLAY_DISPLAYINFO_DISPLAYMAPPED) - expandedDisplayInfoValue.DISPLAYMAPPED = true; - // Indicates the display can be forced - if ((displayInfoValue & ADL.ADL_DISPLAY_DISPLAYINFO_FORCIBLESUPPORTED) == ADL.ADL_DISPLAY_DISPLAYINFO_FORCIBLESUPPORTED) - expandedDisplayInfoValue.FORCIBLESUPPORTED = true; - // Indicates the display supports genlock - if ((displayInfoValue & ADL.ADL_DISPLAY_DISPLAYINFO_GENLOCKSUPPORTED) == ADL.ADL_DISPLAY_DISPLAYINFO_GENLOCKSUPPORTED) - expandedDisplayInfoValue.GENLOCKSUPPORTED = true; - // Indicates the display is an LDA display. - if ((displayInfoValue & ADL.ADL_DISPLAY_DISPLAYINFO_LDA_DISPLAY) == ADL.ADL_DISPLAY_DISPLAYINFO_LDA_DISPLAY) - expandedDisplayInfoValue.LDA_DISPLAY = true; - // Indicates the display supports 2x Horizontal stretch - if ((displayInfoValue & ADL.ADL_DISPLAY_DISPLAYINFO_MANNER_SUPPORTED_2HSTRETCH) == ADL.ADL_DISPLAY_DISPLAYINFO_MANNER_SUPPORTED_2HSTRETCH) - expandedDisplayInfoValue.MANNER_SUPPORTED_2HSTRETCH = true; - // Indicates the display supports 2x Vertical stretch - if ((displayInfoValue & ADL.ADL_DISPLAY_DISPLAYINFO_MANNER_SUPPORTED_2VSTRETCH) == ADL.ADL_DISPLAY_DISPLAYINFO_MANNER_SUPPORTED_2VSTRETCH) - expandedDisplayInfoValue.MANNER_SUPPORTED_2VSTRETCH = true; - // Indicates the display supports cloned desktops - if ((displayInfoValue & ADL.ADL_DISPLAY_DISPLAYINFO_MANNER_SUPPORTED_CLONE) == ADL.ADL_DISPLAY_DISPLAYINFO_MANNER_SUPPORTED_CLONE) - expandedDisplayInfoValue.MANNER_SUPPORTED_CLONE = true; - // Indicates the display supports extended desktops - if ((displayInfoValue & ADL.ADL_DISPLAY_DISPLAYINFO_MANNER_SUPPORTED_EXTENDED) == ADL.ADL_DISPLAY_DISPLAYINFO_MANNER_SUPPORTED_EXTENDED) - expandedDisplayInfoValue.MANNER_SUPPORTED_EXTENDED = true; - // Indicates the display supports N Stretched on 1 GPU - if ((displayInfoValue & ADL.ADL_DISPLAY_DISPLAYINFO_MANNER_SUPPORTED_NSTRETCH1GPU) == ADL.ADL_DISPLAY_DISPLAYINFO_MANNER_SUPPORTED_NSTRETCH1GPU) - expandedDisplayInfoValue.MANNER_SUPPORTED_NSTRETCH1GPU = true; - // Indicates the display supports N Stretched on N GPUs - if ((displayInfoValue & ADL.ADL_DISPLAY_DISPLAYINFO_MANNER_SUPPORTED_NSTRETCHNGPU) == ADL.ADL_DISPLAY_DISPLAYINFO_MANNER_SUPPORTED_NSTRETCHNGPU) - expandedDisplayInfoValue.MANNER_SUPPORTED_NSTRETCHNGPU = true; - // Reserved display info flag #2 - if ((displayInfoValue & ADL.ADL_DISPLAY_DISPLAYINFO_MANNER_SUPPORTED_RESERVED2) == ADL.ADL_DISPLAY_DISPLAYINFO_MANNER_SUPPORTED_RESERVED2) - expandedDisplayInfoValue.MANNER_SUPPORTED_RESERVED2 = true; - // Reserved display info flag #3 - if ((displayInfoValue & ADL.ADL_DISPLAY_DISPLAYINFO_MANNER_SUPPORTED_RESERVED3) == ADL.ADL_DISPLAY_DISPLAYINFO_MANNER_SUPPORTED_RESERVED3) - expandedDisplayInfoValue.MANNER_SUPPORTED_RESERVED3 = true; - // Indicates the display supports single desktop - if ((displayInfoValue & ADL.ADL_DISPLAY_DISPLAYINFO_MANNER_SUPPORTED_SINGLE) == ADL.ADL_DISPLAY_DISPLAYINFO_MANNER_SUPPORTED_SINGLE) - expandedDisplayInfoValue.MANNER_SUPPORTED_SINGLE = true; - // Indicates the display supports overriding the mode timing - if ((displayInfoValue & ADL.ADL_DISPLAY_DISPLAYINFO_MODETIMING_OVERRIDESSUPPORTED) == ADL.ADL_DISPLAY_DISPLAYINFO_MODETIMING_OVERRIDESSUPPORTED) - expandedDisplayInfoValue.MODETIMING_OVERRIDESSUPPORTED = true; - // Indicates the display supports multi-vpu - if ((displayInfoValue & ADL.ADL_DISPLAY_DISPLAYINFO_MULTIVPU_SUPPORTED) == ADL.ADL_DISPLAY_DISPLAYINFO_MULTIVPU_SUPPORTED) - expandedDisplayInfoValue.MULTIVPU_SUPPORTED = true; - // Indicates the display is non-local to this machine - if ((displayInfoValue & ADL.ADL_DISPLAY_DISPLAYINFO_NONLOCAL) == ADL.ADL_DISPLAY_DISPLAYINFO_NONLOCAL) - expandedDisplayInfoValue.NONLOCAL = true; - // Indicates the display is a projector - if ((displayInfoValue & ADL.ADL_DISPLAY_DISPLAYINFO_SHOWTYPE_PROJECTOR) == ADL.ADL_DISPLAY_DISPLAYINFO_SHOWTYPE_PROJECTOR) - expandedDisplayInfoValue.SHOWTYPE_PROJECTOR = true; - - return expandedDisplayInfoValue; - - } - - public static ConvertedDisplayModeFlags ConvertDisplayModeFlags(int displayModeFlag) - { - ConvertedDisplayModeFlags expandedDisplayModeFlags = new ConvertedDisplayModeFlags(); - - // Indicates the display is a digital device - if ((displayModeFlag & ADL.ADL_DISPLAY_MODE_COLOURFORMAT_565) == ADL.ADL_DISPLAY_MODE_COLOURFORMAT_565) - expandedDisplayModeFlags.COLOURFORMAT_565 = true; - // Indicates the display supports EDID queries - if ((displayModeFlag & ADL.ADL_DISPLAY_MODE_COLOURFORMAT_8888) == ADL.ADL_DISPLAY_MODE_COLOURFORMAT_8888) - expandedDisplayModeFlags.COLOURFORMAT_8888 = true; - // Indicates the display supports normal vertical orientation - if ((displayModeFlag & ADL.ADL_DISPLAY_MODE_ORIENTATION_SUPPORTED_000) == ADL.ADL_DISPLAY_MODE_ORIENTATION_SUPPORTED_000) - expandedDisplayModeFlags.ORIENTATION_SUPPORTED_000 = true; - // Indicates the display supports normal vertical orientation - if ((displayModeFlag & ADL.ADL_DISPLAY_MODE_ORIENTATION_SUPPORTED_090) == ADL.ADL_DISPLAY_MODE_ORIENTATION_SUPPORTED_090) - expandedDisplayModeFlags.ORIENTATION_SUPPORTED_090 = true; - // Indicates the display supports normal vertical orientation - if ((displayModeFlag & ADL.ADL_DISPLAY_MODE_ORIENTATION_SUPPORTED_180) == ADL.ADL_DISPLAY_MODE_ORIENTATION_SUPPORTED_180) - expandedDisplayModeFlags.ORIENTATION_SUPPORTED_180 = true; - // Indicates the display supports normal vertical orientation - if ((displayModeFlag & ADL.ADL_DISPLAY_MODE_ORIENTATION_SUPPORTED_270) == ADL.ADL_DISPLAY_MODE_ORIENTATION_SUPPORTED_270) - expandedDisplayModeFlags.ORIENTATION_SUPPORTED_270 = true; - // Indicates the display supports normal vertical orientation - if ((displayModeFlag & ADL.ADL_DISPLAY_MODE_REFRESHRATE_ROUNDED) == ADL.ADL_DISPLAY_MODE_REFRESHRATE_ROUNDED) - expandedDisplayModeFlags.REFRESHRATE_ROUNDED = true; - // Indicates the display supports normal vertical orientation - if ((displayModeFlag & ADL.ADL_DISPLAY_MODE_REFRESHRATE_ONLY) == ADL.ADL_DISPLAY_MODE_REFRESHRATE_ONLY) - expandedDisplayModeFlags.REFRESHRATE_ONLY = true; - - return expandedDisplayModeFlags; - - } - - - public static string ConvertADLReturnValueIntoWords(int adlReturnValue) - { - if (adlReturnValue == ADL.ADL_OK) - return "Success. Function worked as intended."; - if (adlReturnValue == ADL.ADL_ERR) - return "Generic Error.Most likely one or more of the Escape calls to the driver failed!"; - if (adlReturnValue == ADL.ADL_ERR_DISABLED_ADAPTER) - return "Call can't be made due to disabled adapter."; - if (adlReturnValue == ADL.ADL_ERR_INVALID_ADL_IDX) - return "Invalid ADL index passed."; - if (adlReturnValue == ADL.ADL_ERR_INVALID_CALLBACK) - return "Invalid Callback passed."; - if (adlReturnValue == ADL.ADL_ERR_INVALID_CONTROLLER_IDX) - return "Invalid controller index passed."; - if (adlReturnValue == ADL.ADL_ERR_INVALID_DISPLAY_IDX) - return "Invalid display index passed."; - if (adlReturnValue == ADL.ADL_ERR_INVALID_PARAM) - return "One of the parameter passed is invalid."; - if (adlReturnValue == ADL.ADL_ERR_INVALID_PARAM_SIZE) - return "One of the parameter size is invalid."; - if (adlReturnValue == ADL.ADL_ERR_NO_XDISPLAY) - return "There's no Linux XDisplay in Linux Console environment."; - if (adlReturnValue == ADL.ADL_ERR_NOT_INIT) - return "ADL not initialized. You need to run ADL_Main_Control_Create."; - if (adlReturnValue == ADL.ADL_ERR_NOT_SUPPORTED) - return "Function not supported by the driver."; - if (adlReturnValue == ADL.ADL_ERR_NULL_POINTER) - return "Null Pointer error."; - if (adlReturnValue == ADL.ADL_ERR_RESOURCE_CONFLICT) - return "Display Resource conflict."; - if (adlReturnValue == ADL.ADL_ERR_SET_INCOMPLETE) - return "Err Set incomplete"; - if (adlReturnValue == ADL.ADL_OK_MODE_CHANGE) - return "All OK but need mode change."; - if (adlReturnValue == ADL.ADL_OK_RESTART) - return "All OK, but need to restart."; - if (adlReturnValue == ADL.ADL_OK_WAIT) - return "All OK, but need to wait."; - if (adlReturnValue == ADL.ADL_OK_WARNING) - return "All OK, but with warning.."; - // If we get here, then we've got an ADL Return value that we don't understand! - return "ADL Return value not recognised. Your driver is likely newer than this code can understand."; - } - - - #endregion ADL Helper Functions } - #endregion ADL Class -} - -#endregion ATI.ADL \ No newline at end of file +} \ No newline at end of file diff --git a/DisplayMagicianShared/AMD/AMDLibrary.cs b/DisplayMagicianShared/AMD/AMDLibrary.cs index f6acbb0..ac416c1 100644 --- a/DisplayMagicianShared/AMD/AMDLibrary.cs +++ b/DisplayMagicianShared/AMD/AMDLibrary.cs @@ -1,18 +1,76 @@ using System; using System.Collections.Generic; +using System.Linq; using System.Runtime.InteropServices; -using ATI.ADL; +using System.Text; using Microsoft.Win32.SafeHandles; +using DisplayMagicianShared; +using System.ComponentModel; +using DisplayMagicianShared.Windows; namespace DisplayMagicianShared.AMD { - public class AMDLibrary : IDisposable + [StructLayout(LayoutKind.Sequential)] + public struct AMD_ADAPTER_CONFIG : IEquatable { + public int AdapterDeviceNumber; + public int AdapterBusNumber; + public int AdapterIndex; + public bool IsPrimaryAdapter; + //public ADL_DISPLAY_MAP[] DisplayMaps; + //public ADL_DISPLAY_TARGET[] DisplayTargets; + public int SLSMapIndex; + public bool IsSLSEnabled; + //public ADL_SLS_MAP[] SLSMap; + + public bool Equals(AMD_ADAPTER_CONFIG other) + => AdapterIndex == other.AdapterIndex && + AdapterBusNumber == other.AdapterBusNumber && + AdapterDeviceNumber == other.AdapterDeviceNumber && + IsPrimaryAdapter == other.IsPrimaryAdapter && + //DisplayMaps.SequenceEqual(other.DisplayMaps) && + //DisplayTargets.SequenceEqual(other.DisplayTargets); + SLSMapIndex == other.SLSMapIndex && + IsSLSEnabled == other.IsSLSEnabled; + + public override int GetHashCode() + { + return (AdapterIndex, AdapterBusNumber, AdapterDeviceNumber, IsPrimaryAdapter, SLSMapIndex, IsSLSEnabled).GetHashCode(); + } + } + + [StructLayout(LayoutKind.Sequential)] + public struct AMD_DISPLAY_CONFIG : IEquatable + { + //public Dictionary DisplayAdapters; + public List AdapterConfigs; + //public DISPLAYCONFIG_MODE_INFO[] DisplayConfigModes; + //public ADVANCED_HDR_INFO_PER_PATH[] DisplayHDRStates; + public WINDOWS_DISPLAY_CONFIG WindowsDisplayConfig; + + public bool Equals(AMD_DISPLAY_CONFIG other) + => AdapterConfigs.SequenceEqual(other.AdapterConfigs) && + //DisplayConfigPaths.SequenceEqual(other.DisplayConfigPaths) && + //DisplayConfigModes.SequenceEqual(other.DisplayConfigModes) && + //DisplayHDRStates.SequenceEqual(other.DisplayHDRStates) && + WindowsDisplayConfig.Equals(other.WindowsDisplayConfig); + + public override int GetHashCode() + { + return (AdapterConfigs, WindowsDisplayConfig).GetHashCode(); + } + } + + public class AMDLibrary : IDisposable + { + // Static members are 'eagerly initialized', that is, // immediately when class is loaded for the first time. // .NET guarantees thread safety for static initialization private static AMDLibrary _instance = new AMDLibrary(); + private static WinLibrary _winLibrary = new WinLibrary(); + private bool _initialised = false; // To detect redundant calls @@ -21,45 +79,64 @@ namespace DisplayMagicianShared.AMD // Instantiate a SafeHandle instance. private SafeHandle _safeHandle = new SafeFileHandle(IntPtr.Zero, true); private IntPtr _adlContextHandle = IntPtr.Zero; - + static AMDLibrary() { } public AMDLibrary() { - int ADLRet = ADL.ADL_ERR; - SharedLogger.logger.Trace("AMDLibrary/AMDLibrary: Intialising ADL2 library interface"); try { - if (ADL.ADL2_Main_Control_Create != null) + SharedLogger.logger.Trace($"AMDLibrary/AMDLibrary: Attempting to load the AMD ADL DLL {ADLImport.ATI_ADL_DLL}"); + // Attempt to prelink all of the NVAPI functions + Marshal.PrelinkAll(typeof(ADLImport)); + + SharedLogger.logger.Trace("AMDLibrary/AMDLibrary: Intialising AMD ADL2 library interface"); + // Second parameter is 1 so that we only the get connected adapters in use now + try { - // Second parameter is 1: Get only the present adapters - ADLRet = ADL.ADL2_Main_Control_Create(ADL.ADL_Main_Memory_Alloc, 1, out _adlContextHandle); + ADL_STATUS ADLRet; + ADLRet = ADLImport.ADL2_Main_Control_Create(ADLImport.ADL_Main_Memory_Alloc, ADLImport.ADL_TRUE, out _adlContextHandle); + if (ADLRet == ADL_STATUS.ADL_OK) + { + _initialised = true; + SharedLogger.logger.Trace($"AMDLibrary/AMDLibrary: AMD ADL2 library was initialised successfully"); + } + else + { + SharedLogger.logger.Trace($"AMDLibrary/AMDLibrary: Error intialising AMD ADL2 library. ADL2_Main_Control_Create() returned error code {ADLRet}"); + } + } + catch (Exception ex) + { + SharedLogger.logger.Trace(ex, $"AMDLibrary/AMDLibrary: Exception intialising AMD ADL2 library. ADL2_Main_Control_Create() caused an exception."); } - if (ADLRet == ADL.ADL_OK) - { - _initialised = true; - SharedLogger.logger.Trace("AMDLibrary/AMDLibrary: ADL2 library was initialised successfully"); - } - else - { - SharedLogger.logger.Error("AMDLibrary/AMDLibrary: Error intialising ADL2 library. ADL2_Main_Control_Create() returned error code " + ADL.ConvertADLReturnValueIntoWords(ADLRet)); - } + _winLibrary = WinLibrary.GetLibrary(); } - catch (Exception ex) + catch (DllNotFoundException ex) { - SharedLogger.logger.Error(ex, "AMDLibrary/AMDLibrary: Exception intialising ADL2 library. ADL2_Main_Control_Create() caused an exception"); + // If we get here then the AMD ADL DLL wasn't found. We can't continue to use it, so we log the error and exit + SharedLogger.logger.Info(ex, $"AMDLibrary/AMDLibrary: Exception trying to load the AMD ADL DLL {ADLImport.ATI_ADL_DLL}. This generally means you don't have the AMD ADL driver installed."); } } ~AMDLibrary() { + SharedLogger.logger.Trace("AMDLibrary/~AMDLibrary: Destroying AMD ADL2 library interface"); // If the ADL2 library was initialised, then we need to free it up. if (_initialised) { - if (null != ADL.ADL2_Main_Control_Destroy) - ADL.ADL2_Main_Control_Destroy(_adlContextHandle); + try + { + ADLImport.ADL2_Main_Control_Destroy(_adlContextHandle); + SharedLogger.logger.Trace($"AMDLibrary/AMDLibrary: AMD ADL2 library was destroyed successfully"); + } + catch (Exception ex) + { + SharedLogger.logger.Trace(ex, $"AMDLibrary/AMDLibrary: Exception destroying AMD ADL2 library. ADL2_Main_Control_Destroy() caused an exception."); + } + } } @@ -76,8 +153,8 @@ namespace DisplayMagicianShared.AMD if (disposing) { - if (null != ADL.ADL_Main_Control_Destroy) - ADL.ADL_Main_Control_Destroy(); + + //ADLImport.ADL_Main_Control_Destroy(); // Dispose managed state (managed objects). _safeHandle?.Dispose(); @@ -89,7 +166,10 @@ namespace DisplayMagicianShared.AMD public bool IsInstalled { - get { return _initialised; } + get + { + return _initialised; + } } public static AMDLibrary GetLibrary() @@ -97,1659 +177,1127 @@ namespace DisplayMagicianShared.AMD return _instance; } - public List GenerateProfileDisplayIdentifiers() + + + public AMD_DISPLAY_CONFIG GetActiveConfig() { - SharedLogger.logger.Trace($"AMDLibrary/GenerateProfileDisplayIdentifiers: Getting AMD active adapter count"); + SharedLogger.logger.Trace($"AMDLibrary/GetActiveConfig: Getting the currently active config"); + bool allDisplays = true; + return GetAMDDisplayConfig(allDisplays); + } - int ADLRet = ADL.ADL_ERR; - int NumberOfAdapters = 0; + private AMD_DISPLAY_CONFIG GetAMDDisplayConfig(bool allDisplays = false) + { + AMD_DISPLAY_CONFIG myDisplayConfig = new AMD_DISPLAY_CONFIG(); + myDisplayConfig.AdapterConfigs = new List(); - List displayIdentifiers = new List(); - - if (null != ADL.ADL2_Adapter_NumberOfAdapters_Get) + if (_initialised) { - ADL.ADL2_Adapter_NumberOfAdapters_Get(_adlContextHandle, ref NumberOfAdapters); - SharedLogger.logger.Trace($"AMDLibrary/GenerateProfileDisplayIdentifiers: Number Of Adapters: {NumberOfAdapters.ToString()} "); - } - - if (NumberOfAdapters > 0) - { - - IntPtr AdapterBuffer = IntPtr.Zero; - if (ADL.ADL2_Adapter_AdapterInfoX4_Get != null) + // Get the number of AMD adapters that the OS knows about + int numAdapters = 0; + ADL_STATUS ADLRet = ADLImport.ADL2_Adapter_NumberOfAdapters_Get(_adlContextHandle, out numAdapters); + if (ADLRet == ADL_STATUS.ADL_OK) { - SharedLogger.logger.Trace($"AMDLibrary/GenerateProfileDisplayIdentifiers: ADL2_Adapter_AdapterInfoX4_Get DLL function exists."); + SharedLogger.logger.Trace($"AMDLibrary/GetAMDDisplayConfig: ADL2_Adapter_NumberOfAdapters_Get returned the number of AMD Adapters the OS knows about ({numAdapters})."); + } + else + { + SharedLogger.logger.Error($"AMDLibrary/GetAMDDisplayConfig: ERROR - ADL2_Adapter_NumberOfAdapters_Get returned ADL_STATUS {ADLRet} when trying to get number of AMD adapters in the computer."); + throw new AMDLibraryException($"ADL2_Adapter_NumberOfAdapters_Get returned ADL_STATUS {ADLRet} when trying to get number of AMD adapters in the computer"); + } - // Get the Adapter info and put it in the AdapterBuffer - SharedLogger.logger.Trace($"AMDLibrary/GenerateProfileDisplayIdentifiers: Running ADL2_Adapter_AdapterInfoX4_Get to find all known AMD adapters."); - //ADLRet = ADL.ADL2_Adapter_AdapterInfoX4_Get(_adlContextHandle, AdapterBuffer, size); - int numAdapters = 0; - ADLRet = ADL.ADL2_Adapter_AdapterInfoX4_Get(_adlContextHandle, ADL.ADL_ADAPTER_INDEX_ALL, out numAdapters, out AdapterBuffer); - if (ADLRet == ADL.ADL_OK) - { + // Figure out primary adapter + int primaryAdapterIndex = 0; + ADLRet = ADLImport.ADL2_Adapter_Primary_Get(_adlContextHandle, out primaryAdapterIndex); + if (ADLRet == ADL_STATUS.ADL_OK) + { + SharedLogger.logger.Trace($"AMDLibrary/ADL2_Adapter_Primary_Get: The primary adapter has index {primaryAdapterIndex}."); + } + else + { + SharedLogger.logger.Error($"AMDLibrary/ADL2_Adapter_Primary_Get: ERROR - ADL2_Adapter_Primary_Get returned ADL_STATUS {ADLRet} when trying to get the primary adapter info from all the AMD adapters in the computer."); + throw new AMDLibraryException($"ADL2_Adapter_Primary_Get returned ADL_STATUS {ADLRet} when trying to get the adapter info from all the AMD adapters in the computer"); + } - int IsActive = ADL.ADL_TRUE; // We only want to search for active adapters - - SharedLogger.logger.Trace($"AMDLibrary/GenerateProfileDisplayIdentifiers: Successfully run ADL2_Adapter_AdapterInfoX4_Get to find information about all known AMD adapters."); - - ADLAdapterInfoX2 oneAdapter = new ADLAdapterInfoX2(); - // Go through each adapter - for (int adapterLoop = 0; adapterLoop < numAdapters; adapterLoop++) + // Now go through each adapter and get the information we need from it + for (int adapterIndex = 0; adapterIndex < numAdapters; adapterIndex++) + { + // Skip this adapter if it isn't active + int adapterActiveStatus = ADLImport.ADL_FALSE; + ADLRet = ADLImport.ADL2_Adapter_Active_Get(_adlContextHandle, adapterIndex, out adapterActiveStatus); + if (ADLRet == ADL_STATUS.ADL_OK) + { + if (adapterActiveStatus == ADLImport.ADL_TRUE) { - oneAdapter = (ADLAdapterInfoX2)Marshal.PtrToStructure(new IntPtr(AdapterBuffer.ToInt64() + (adapterLoop * Marshal.SizeOf(oneAdapter))), oneAdapter.GetType()); - - if (oneAdapter.Exist != 1) - { - SharedLogger.logger.Trace($"AMDLibrary/GenerateProfileDisplayIdentifiers: AMD Adapter #{oneAdapter.AdapterIndex.ToString()} doesn't exist at present so skipping detection for this adapter."); - continue; - } - - if (oneAdapter.Present != 1) - { - SharedLogger.logger.Trace($"AMDLibrary/GenerateProfileDisplayIdentifiers: AMD Adapter #{oneAdapter.AdapterIndex.ToString()} isn't enabled at present so skipping detection for this adapter."); - continue; - } - - // Check if the adapter is active - if (ADL.ADL2_Adapter_Active_Get != null) - ADLRet = ADL.ADL2_Adapter_Active_Get(_adlContextHandle, oneAdapter.AdapterIndex, ref IsActive); - - if (ADLRet == ADL.ADL_OK) - { - // Only continue if the adapter is enabled - if (IsActive != ADL.ADL_TRUE) - { - SharedLogger.logger.Trace($"AMDLibrary/GenerateProfileDisplayIdentifiers: AMD Adapter #{oneAdapter.AdapterIndex.ToString()} isn't active ({oneAdapter.AdapterName})."); - continue; - } - - // Only continue if the adapter index is > 0 - if (oneAdapter.AdapterIndex < 0) - { - SharedLogger.logger.Trace($"AMDLibrary/GenerateProfileDisplayIdentifiers: AMD Adapter has an adapter index of {oneAdapter.AdapterIndex.ToString()} which indicates it is not a real adapter."); - continue; - } - - SharedLogger.logger.Trace($"AMDLibrary/GenerateProfileDisplayIdentifiers: AMD Adapter #{oneAdapter.AdapterIndex.ToString()} is active! ({oneAdapter.AdapterName})."); - - SharedLogger.logger.Trace($"AMDLibrary/GenerateProfileDisplayIdentifiers: ### Adapter Info for Adapter #{oneAdapter.AdapterIndex} ###"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateProfileDisplayIdentifiers: Adapter AdapterIndex = {oneAdapter.AdapterIndex}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateProfileDisplayIdentifiers: Adapter AdapterName = {oneAdapter.AdapterName}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateProfileDisplayIdentifiers: Adapter BusNumber = {oneAdapter.BusNumber}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateProfileDisplayIdentifiers: Adapter DeviceNumber = {oneAdapter.DeviceNumber}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateProfileDisplayIdentifiers: Adapter DisplayName = {oneAdapter.DisplayName}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateProfileDisplayIdentifiers: Adapter DriverPath = {oneAdapter.DriverPath}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateProfileDisplayIdentifiers: Adapter DriverPathExt = {oneAdapter.DriverPathExt}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateProfileDisplayIdentifiers: Adapter Exist = {oneAdapter.Exist}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateProfileDisplayIdentifiers: Adapter FunctionNumber = {oneAdapter.FunctionNumber}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateProfileDisplayIdentifiers: Adapter InfoMask = {oneAdapter.InfoMask}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateProfileDisplayIdentifiers: Adapter InfoValue = {oneAdapter.InfoValue}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateProfileDisplayIdentifiers: Adapter OSDisplayIndex = {oneAdapter.OSDisplayIndex}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateProfileDisplayIdentifiers: Adapter PNPString = {oneAdapter.PNPString}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateProfileDisplayIdentifiers: Adapter Present = {oneAdapter.Present}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateProfileDisplayIdentifiers: Adapter Size = {oneAdapter.Size}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateProfileDisplayIdentifiers: Adapter UDID = {oneAdapter.UDID}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateProfileDisplayIdentifiers: Adapter VendorID = {oneAdapter.VendorID}"); - - // Get the Adapter Capabilities - ADLAdapterCapsX2 AdapterCapabilities = new ADLAdapterCapsX2(); - if (ADL.ADL2_AdapterX2_Caps != null) - { - ADLRet = ADL.ADL2_AdapterX2_Caps(_adlContextHandle, oneAdapter.AdapterIndex, out AdapterCapabilities); - } - - SharedLogger.logger.Trace($"AMDLibrary/GenerateProfileDisplayIdentifiers: ### Adapter Capabilities for Adapter #{oneAdapter.AdapterIndex} ###"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateProfileDisplayIdentifiers: Adapter ID = {AdapterCapabilities.AdapterID}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateProfileDisplayIdentifiers: Adapter Capabilities Mask = {AdapterCapabilities.CapsMask}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateProfileDisplayIdentifiers: Adapter Capabilities Value = {AdapterCapabilities.CapsValue}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateProfileDisplayIdentifiers: Adapter Num of Connectors = {AdapterCapabilities.NumConnectors}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateProfileDisplayIdentifiers: Adapter Num of Controllers = {AdapterCapabilities.NumControllers}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateProfileDisplayIdentifiers: Adapter Num of Displays = {AdapterCapabilities.NumDisplays}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateProfileDisplayIdentifiers: Adapter Num of GL Sync Connectors = {AdapterCapabilities.NumOfGLSyncConnectors}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateProfileDisplayIdentifiers: Adapter Num of Overlays = {AdapterCapabilities.NumOverlays}"); - - // Obtain information about displays - //ADLDisplayInfoArray displayInfoArray = new ADLDisplayInfoArray(); - - if (ADL.ADL2_Display_DisplayInfo_Get != null) - { - IntPtr DisplayBuffer = IntPtr.Zero; - int numDisplays = 0; - // Force the display detection and get the Display Info. Use 0 as last parameter to NOT force detection - ADLRet = ADL.ADL2_Display_DisplayInfo_Get(_adlContextHandle, oneAdapter.AdapterIndex, ref numDisplays, out DisplayBuffer, 0); - if (ADLRet == ADL.ADL_OK) - { - - try - { - ADLDisplayInfo oneDisplayInfo = new ADLDisplayInfo(); - - for (int displayLoop = 0; displayLoop < numDisplays; displayLoop++) - { - oneDisplayInfo = (ADLDisplayInfo)Marshal.PtrToStructure(new IntPtr(DisplayBuffer.ToInt64() + (displayLoop * Marshal.SizeOf(oneDisplayInfo))), oneDisplayInfo.GetType()); - - // Is the display mapped to this adapter? If not we skip it! - if (oneDisplayInfo.DisplayID.DisplayLogicalAdapterIndex != oneAdapter.AdapterIndex) - { - SharedLogger.logger.Trace($"AMDLibrary/GenerateProfileDisplayIdentifiers: AMD Adapter #{oneAdapter.AdapterIndex.ToString()} ({oneAdapter.AdapterName}) AdapterID display ID#{oneDisplayInfo.DisplayID.DisplayLogicalIndex} is not a real display as its DisplayID.DisplayLogicalAdapterIndex is -1"); - continue; - } - - // Convert the displayInfoValue to something usable using a library function I made - ConvertedDisplayInfoValue displayInfoValue = ADL.ConvertDisplayInfoValue(oneDisplayInfo.DisplayInfoValue); - - if (!displayInfoValue.DISPLAYCONNECTED) - { - SharedLogger.logger.Trace($"AMDLibrary/GenerateProfileDisplayIdentifiers: AMD Adapter #{oneAdapter.AdapterIndex.ToString()} ({oneAdapter.AdapterName}) AdapterID display ID#{oneDisplayInfo.DisplayID.DisplayLogicalIndex} is not connected"); - continue; - } - - // Skip connected but non-mapped displays (not mapped in windows) - we want all displays currently visible in the OS - if (!displayInfoValue.DISPLAYMAPPED) - { - SharedLogger.logger.Trace($"AMDLibrary/GenerateProfileDisplayIdentifiers: AMD Adapter #{oneAdapter.AdapterIndex.ToString()} ({oneAdapter.AdapterName}) AdapterID display ID#{oneDisplayInfo.DisplayID.DisplayLogicalIndex} is not mapped in Windows OS"); - continue; - } - - SharedLogger.logger.Trace($"AMDLibrary/GenerateProfileDisplayIdentifiers: AMD Adapter #{oneAdapter.AdapterIndex.ToString()} ({oneAdapter.AdapterName}) AdapterID display ID#{oneDisplayInfo.DisplayID.DisplayLogicalIndex} is connected and mapped in Windows OS"); - - ADL.ADLDisplayConnectionType displayConnector = (ADL.ADLDisplayConnectionType)oneDisplayInfo.DisplayConnector; - - SharedLogger.logger.Trace($"AMDLibrary/GenerateProfileDisplayIdentifiers: ### Display Info for Display #{oneDisplayInfo.DisplayID.DisplayLogicalIndex} on Adapter #{oneAdapter.AdapterIndex} ###"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateProfileDisplayIdentifiers: Display Connector = {displayConnector.ToString("G")}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateProfileDisplayIdentifiers: Display Controller Index = {oneDisplayInfo.DisplayControllerIndex}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateProfileDisplayIdentifiers: Display Logical Adapter Index = {oneDisplayInfo.DisplayID.DisplayLogicalAdapterIndex}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateProfileDisplayIdentifiers: Display Logical Index = {oneDisplayInfo.DisplayID.DisplayLogicalIndex}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateProfileDisplayIdentifiers: Display Physical Adapter Index = {oneDisplayInfo.DisplayID.DisplayPhysicalAdapterIndex}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateProfileDisplayIdentifiers: Display Physical Index = {oneDisplayInfo.DisplayID.DisplayPhysicalIndex}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateProfileDisplayIdentifiers: Display Info Mask = {oneDisplayInfo.DisplayInfoMask}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateProfileDisplayIdentifiers: Display Info Value = {oneDisplayInfo.DisplayInfoValue}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateProfileDisplayIdentifiers: Display Manufacturer Name = {oneDisplayInfo.DisplayManufacturerName}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateProfileDisplayIdentifiers: Display Name = {oneDisplayInfo.DisplayName}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateProfileDisplayIdentifiers: Display Output Type = {oneDisplayInfo.DisplayOutputType}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateProfileDisplayIdentifiers: Display Type = {oneDisplayInfo.DisplayType}"); - - SharedLogger.logger.Trace($"AMDLibrary/GenerateProfileDisplayIdentifiers: Display Info Value DISPLAYCONNECTED = {displayInfoValue.DISPLAYCONNECTED}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateProfileDisplayIdentifiers: Display Info Value DISPLAYMAPPED = {displayInfoValue.DISPLAYMAPPED}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateProfileDisplayIdentifiers: Display Info Value FORCIBLESUPPORTED = {displayInfoValue.FORCIBLESUPPORTED}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateProfileDisplayIdentifiers: Display Info Value GENLOCKSUPPORTED = {displayInfoValue.GENLOCKSUPPORTED}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateProfileDisplayIdentifiers: Display Info Value LDA_DISPLAY = {displayInfoValue.LDA_DISPLAY}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateProfileDisplayIdentifiers: Display Info Value MANNER_SUPPORTED_2HSTRETCH = {displayInfoValue.MANNER_SUPPORTED_2HSTRETCH}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateProfileDisplayIdentifiers: Display Info Value MANNER_SUPPORTED_2VSTRETCH = {displayInfoValue.MANNER_SUPPORTED_2VSTRETCH}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateProfileDisplayIdentifiers: Display Info Value MANNER_SUPPORTED_CLONE = {displayInfoValue.MANNER_SUPPORTED_CLONE}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateProfileDisplayIdentifiers: Display Info Value MANNER_SUPPORTED_EXTENDED = {displayInfoValue.MANNER_SUPPORTED_EXTENDED}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateProfileDisplayIdentifiers: Display Info Value MANNER_SUPPORTED_NSTRETCH1GPU = {displayInfoValue.MANNER_SUPPORTED_NSTRETCH1GPU}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateProfileDisplayIdentifiers: Display Info Value MANNER_SUPPORTED_NSTRETCHNGPU = {displayInfoValue.MANNER_SUPPORTED_NSTRETCHNGPU}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateProfileDisplayIdentifiers: Display Info Value MANNER_SUPPORTED_SINGLE = {displayInfoValue.MANNER_SUPPORTED_SINGLE}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateProfileDisplayIdentifiers: Display Info Value MODETIMING_OVERRIDESSUPPORTED = {displayInfoValue.MODETIMING_OVERRIDESSUPPORTED}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateProfileDisplayIdentifiers: Display Info Value MULTIVPU_SUPPORTED = {displayInfoValue.MULTIVPU_SUPPORTED}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateProfileDisplayIdentifiers: Display Info Value NONLOCAL = {displayInfoValue.NONLOCAL}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateProfileDisplayIdentifiers: Display Info Value SHOWTYPE_PROJECTOR = {displayInfoValue.SHOWTYPE_PROJECTOR}"); - - ADL.ADLDisplayConnectionType displayConnectionType = ADL.ADLDisplayConnectionType.Unknown; - ADLDisplayConfig displayConfig = new ADLDisplayConfig(); - displayConfig.Size = Marshal.SizeOf(displayConfig); - if (ADL.ADL2_Display_DeviceConfig_Get != null) - { - // Get the DisplayConfig from the Display - ADLRet = ADL.ADL2_Display_DeviceConfig_Get(_adlContextHandle, oneAdapter.AdapterIndex, oneDisplayInfo.DisplayID.DisplayPhysicalIndex, out displayConfig); - if (ADLRet == ADL.ADL_OK) - { - displayConnectionType = (ADL.ADLDisplayConnectionType)displayConfig.ConnectorType; - - SharedLogger.logger.Trace($"AMDLibrary/GenerateProfileDisplayIdentifiers: ### Display Device Config for Display #{oneDisplayInfo.DisplayID.DisplayLogicalIndex} on Adapter #{oneAdapter.AdapterIndex} ###"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateProfileDisplayIdentifiers: Display Connector Type = {displayConnectionType.ToString("G")}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateProfileDisplayIdentifiers: Display Device Data = {displayConfig.DeviceData}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateProfileDisplayIdentifiers: Display Overridded Device Data = {displayConfig.OverriddedDeviceData}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateProfileDisplayIdentifiers: Display Reserved Data = {displayConfig.Reserved}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateProfileDisplayIdentifiers: Display Size = {displayConfig.Size}"); - } - else - { - SharedLogger.logger.Warn($"AMDLibrary/GenerateProfileDisplayIdentifiers: Error running ADL2_Display_DeviceConfig_Get on Display #{oneDisplayInfo.DisplayID.DisplayLogicalIndex} on Adapter #{oneAdapter.AdapterIndex}: {ADL.ConvertADLReturnValueIntoWords(ADLRet)}"); - } - } - - ADLDDCInfo2 displayDDCInfo2 = new ADLDDCInfo2(); - displayDDCInfo2.Size = Marshal.SizeOf(displayDDCInfo2); - // Create a stringbuilder buffer that EDID can be loaded into - //displayEDIDData.EDIDData = new StringBuilder(256); - - if (ADL.ADL2_Display_DDCInfo2_Get != null) - { - // Get the DDC Data from the Display - ADLRet = ADL.ADL2_Display_DDCInfo2_Get(_adlContextHandle, oneAdapter.AdapterIndex, oneDisplayInfo.DisplayID.DisplayPhysicalIndex, out displayDDCInfo2); - if (ADLRet == ADL.ADL_OK) - { - - // Convert the DDCInfoFlag to something usable using a library function I made - ConvertedDDCInfoFlag DDCInfoFlag = ADL.ConvertDDCInfoFlag(displayDDCInfo2.DDCInfoFlag); - - // Convert the DDCInfoFlag to something usable using a library function I made - ConvertedSupportedHDR supportedHDR = ADL.ConvertSupportedHDR(displayDDCInfo2.SupportedHDR); - - SharedLogger.logger.Trace($"AMDLibrary/GenerateProfileDisplayIdentifiers: ### Display DDCInfo2 for Display #{oneDisplayInfo.DisplayID.DisplayLogicalIndex} on Adapter #{oneAdapter.AdapterIndex} ###"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateProfileDisplayIdentifiers: Display AvgLuminanceData = {displayDDCInfo2.AvgLuminanceData}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateProfileDisplayIdentifiers: Display DDCInfoFlag = {displayDDCInfo2.DDCInfoFlag}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateProfileDisplayIdentifiers: Display DiffuseScreenReflectance = {displayDDCInfo2.DiffuseScreenReflectance}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateProfileDisplayIdentifiers: Display DisplayName = {displayDDCInfo2.DisplayName}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateProfileDisplayIdentifiers: Display FreesyncFlags = {displayDDCInfo2.FreesyncFlags}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateProfileDisplayIdentifiers: Display ManufacturerID = {displayDDCInfo2.ManufacturerID}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateProfileDisplayIdentifiers: Display MaxBacklightMaxLuminanceData = {displayDDCInfo2.MaxBacklightMaxLuminanceData}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateProfileDisplayIdentifiers: Display MaxBacklightMinLuminanceData = {displayDDCInfo2.MaxBacklightMinLuminanceData}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateProfileDisplayIdentifiers: Display MaxHResolution = {displayDDCInfo2.MaxHResolution}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateProfileDisplayIdentifiers: Display MaxLuminanceData = {displayDDCInfo2.MaxLuminanceData}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateProfileDisplayIdentifiers: Display MaxRefresh = {displayDDCInfo2.MaxRefresh}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateProfileDisplayIdentifiers: Display MaxVResolution = {displayDDCInfo2.MaxVResolution}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateProfileDisplayIdentifiers: Display MinBacklightMaxLuminanceData = {displayDDCInfo2.MinBacklightMaxLuminanceData}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateProfileDisplayIdentifiers: Display MinBacklightMinLuminanceData = {displayDDCInfo2.MinBacklightMinLuminanceData}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateProfileDisplayIdentifiers: Display MinLuminanceData = {displayDDCInfo2.MinLuminanceData}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateProfileDisplayIdentifiers: Display MinLuminanceNoDimmingData = {displayDDCInfo2.MinLuminanceNoDimmingData}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateProfileDisplayIdentifiers: Display NativeDisplayChromaticityBlueX = {displayDDCInfo2.NativeDisplayChromaticityBlueX}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateProfileDisplayIdentifiers: Display NativeDisplayChromaticityBlueY = {displayDDCInfo2.NativeDisplayChromaticityBlueY}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateProfileDisplayIdentifiers: Display NativeDisplayChromaticityGreenX = {displayDDCInfo2.NativeDisplayChromaticityGreenX}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateProfileDisplayIdentifiers: Display NativeDisplayChromaticityGreenY = {displayDDCInfo2.NativeDisplayChromaticityGreenY}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateProfileDisplayIdentifiers: Display NativeDisplayChromaticityRedX = {displayDDCInfo2.NativeDisplayChromaticityRedX}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateProfileDisplayIdentifiers: Display NativeDisplayChromaticityRedY = {displayDDCInfo2.NativeDisplayChromaticityRedY}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateProfileDisplayIdentifiers: Display NativeDisplayChromaticityWhiteX = {displayDDCInfo2.NativeDisplayChromaticityWhiteX}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateProfileDisplayIdentifiers: Display NativeDisplayChromaticityWhiteY = {displayDDCInfo2.NativeDisplayChromaticityWhiteY}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateProfileDisplayIdentifiers: Display PackedPixelSupported = {displayDDCInfo2.PackedPixelSupported}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateProfileDisplayIdentifiers: Display PanelPixelFormat = {displayDDCInfo2.PanelPixelFormat}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateProfileDisplayIdentifiers: Display ProductID = {displayDDCInfo2.ProductID}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateProfileDisplayIdentifiers: Display PTMCx = {displayDDCInfo2.PTMCx}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateProfileDisplayIdentifiers: Display PTMCy = {displayDDCInfo2.PTMCy}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateProfileDisplayIdentifiers: Display PTMRefreshRate = {displayDDCInfo2.PTMRefreshRate}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateProfileDisplayIdentifiers: Display SerialID = {displayDDCInfo2.SerialID}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateProfileDisplayIdentifiers: Display Size = {displayDDCInfo2.Size}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateProfileDisplayIdentifiers: Display SpecularScreenReflectance = {displayDDCInfo2.SpecularScreenReflectance}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateProfileDisplayIdentifiers: Display SupportedColorSpace = {displayDDCInfo2.SupportedColorSpace}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateProfileDisplayIdentifiers: Display SupportedHDR = {displayDDCInfo2.SupportedHDR}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateProfileDisplayIdentifiers: Display SupportedTransferFunction = {displayDDCInfo2.SupportedTransferFunction}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateProfileDisplayIdentifiers: Display SupportsDDC = {displayDDCInfo2.SupportsDDC}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateProfileDisplayIdentifiers: Display DDCInfoFlag Digital Device = {DDCInfoFlag.DIGITALDEVICE}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateProfileDisplayIdentifiers: Display DDCInfoFlag EDID Extension = {DDCInfoFlag.EDIDEXTENSION}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateProfileDisplayIdentifiers: Display DDCInfoFlag HDMI Audio Device = {DDCInfoFlag.HDMIAUDIODEVICE}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateProfileDisplayIdentifiers: Display DDCInfoFlag Projector Device = {DDCInfoFlag.PROJECTORDEVICE}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateProfileDisplayIdentifiers: Display DDCInfoFlag Supports AI = {DDCInfoFlag.SUPPORTS_AI}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateProfileDisplayIdentifiers: Display DDCInfoFlag Supports xvYCC601 = {DDCInfoFlag.SUPPORT_xvYCC601}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateProfileDisplayIdentifiers: Display DDCInfoFlag Supports xvYCC709 = {DDCInfoFlag.SUPPORT_xvYCC709}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateProfileDisplayIdentifiers: Display SupportedHDR Supports CEA861_3 = {supportedHDR.CEA861_3}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateProfileDisplayIdentifiers: Display SupportedHDR Supports DOLBYVISION = {supportedHDR.DOLBYVISION}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateProfileDisplayIdentifiers: Display SupportedHDR Supports FREESYNC_HDR = {supportedHDR.FREESYNC_HDR}"); - } - else - { - SharedLogger.logger.Warn($"AMDLibrary/GenerateProfileDisplayIdentifiers: Error running ADL2_Display_DDCInfo2_Get on Display #{oneDisplayInfo.DisplayID.DisplayLogicalIndex} on Adapter #{oneAdapter.AdapterIndex}: {ADL.ConvertADLReturnValueIntoWords(ADLRet)}"); - } - } - - int HDRSupported = 0; - int HDREnabled = 0; - if (ADL.ADL2_Display_HDRState_Get != null) - { - // Get the HDR State from the Display - ADLRet = ADL.ADL2_Display_HDRState_Get(_adlContextHandle, oneAdapter.AdapterIndex, oneDisplayInfo.DisplayID, out HDRSupported, out HDREnabled); - if (ADLRet == ADL.ADL_OK) - { - SharedLogger.logger.Trace($"AMDLibrary/GenerateProfileDisplayIdentifiers: ### Display HDR State for Display #{oneDisplayInfo.DisplayID.DisplayLogicalIndex} on Adapter #{oneAdapter.AdapterIndex} ###"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateProfileDisplayIdentifiers: Display HDR Supported = {HDRSupported}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateProfileDisplayIdentifiers: Display HDR Enabled = {HDREnabled}"); - } - else - { - SharedLogger.logger.Warn($"AMDLibrary/GenerateProfileDisplayIdentifiers: Error running ADL2_Display_HDRState_Get on Display #{oneDisplayInfo.DisplayID.DisplayLogicalIndex} on Adapter #{oneAdapter.AdapterIndex}: {ADL.ConvertADLReturnValueIntoWords(ADLRet)}"); - } - } - - - // Create an array of all the important display info we need to record - List displayInfoIdentifierSection = new List(); - displayInfoIdentifierSection.Add("AMD"); - try - { - displayInfoIdentifierSection.Add(oneAdapter.VendorID.ToString()); - } - catch (Exception ex) - { - SharedLogger.logger.Warn(ex, $"AMDLibrary/GenerateProfileDisplayIdentifiers: Exception getting AMD Vendor ID from video card. Substituting with a # instead"); - displayInfoIdentifierSection.Add("#"); - } - - try - { - displayInfoIdentifierSection.Add(oneAdapter.AdapterName); - } - catch (Exception ex) - { - SharedLogger.logger.Warn(ex, $"AMDLibrary/GenerateProfileDisplayIdentifiers: Exception getting AMD Adapter Name from video card. Substituting with a # instead"); - displayInfoIdentifierSection.Add("#"); - } - - try - { - displayInfoIdentifierSection.Add(oneAdapter.VendorID.ToString()); - } - catch (Exception ex) - { - SharedLogger.logger.Warn(ex, $"AMDLibrary/GenerateProfileDisplayIdentifiers: Exception getting AMD VendorID from video card. Substituting with a # instead"); - displayInfoIdentifierSection.Add("1002"); - } - - try - { - displayInfoIdentifierSection.Add(AdapterCapabilities.AdapterID.ToString()); - } - catch (Exception ex) - { - SharedLogger.logger.Warn(ex, $"AMDLibrary/GenerateProfileDisplayIdentifiers: Exception getting AMD AdapterID from video card. Substituting with a # instead"); - displayInfoIdentifierSection.Add("#"); - } - - try - { - displayInfoIdentifierSection.Add(displayConnector.ToString("G")); - } - catch (Exception ex) - { - SharedLogger.logger.Warn(ex, $"AMDLibrary/GenerateProfileDisplayIdentifiers: Exception getting AMD Display Connector from video card to display. Substituting with a # instead"); - displayInfoIdentifierSection.Add("#"); - } - - try - { - displayInfoIdentifierSection.Add(oneDisplayInfo.DisplayName); - } - catch (Exception ex) - { - SharedLogger.logger.Warn(ex, $"AMDLibrary/GenerateProfileDisplayIdentifiers: Exception getting Display Name from display connected to AMD video card. Substituting with a # instead"); - displayInfoIdentifierSection.Add("#"); - } - - try - { - displayInfoIdentifierSection.Add(displayDDCInfo2.ManufacturerID.ToString()); - } - catch (Exception ex) - { - SharedLogger.logger.Warn(ex, $"AMDLibrary/GenerateProfileDisplayIdentifiers: Exception getting Manufacturer ID from display connected to AMD video card. Substituting with a # instead"); - displayInfoIdentifierSection.Add("#"); - } - - try - { - displayInfoIdentifierSection.Add(displayDDCInfo2.ProductID.ToString()); - } - catch (Exception ex) - { - SharedLogger.logger.Warn(ex, $"AMDLibrary/GenerateProfileDisplayIdentifiers: Exception getting Product ID from display connected to AMD video card. Substituting with a # instead"); - displayInfoIdentifierSection.Add("#"); - } - - try - { - displayInfoIdentifierSection.Add(displayDDCInfo2.SerialID.ToString()); - } - catch (Exception ex) - { - SharedLogger.logger.Warn(ex, $"AMDLibrary/GenerateProfileDisplayIdentifiers: Exception getting Serial ID from display connected to AMD video card. Substituting with a # instead"); - displayInfoIdentifierSection.Add("#"); - } - - // Create a display identifier out of it - string displayIdentifier = String.Join("|", displayInfoIdentifierSection); - - // Check first to see if there is already an existing display identifier the same! - // This appears to be a bug with the AMD driver, or with the install on my test machine - // Either way, it is potentially going to happen in the wild, so I will filter it out if it does - if (displayIdentifiers.Contains(displayIdentifier)) - { - SharedLogger.logger.Trace($"AMDLibrary/GenerateProfileDisplayIdentifiers: Your AMD driver reported the following Display Identifier multiple times, so ignoring it as we already have it: {displayIdentifier}"); - continue; - } - - // Add it to the list of display identifiers so we can return it - displayIdentifiers.Add(displayIdentifier); - - SharedLogger.logger.Debug($"ProfileRepository/GenerateProfileDisplayIdentifiers: DisplayIdentifier: {displayIdentifier}"); - } - } - catch (Exception ex) - { - SharedLogger.logger.Warn(ex, $"ProfileRepository/GenerateProfileDisplayIdentifiers: Exception caused trying to access attached displays"); - continue; - } - } - else - { - SharedLogger.logger.Warn($"AMDLibrary/GenerateProfileDisplayIdentifiers: Error running ADL2_Display_DisplayInfo_Get on Adapter #{oneAdapter.AdapterIndex}: {ADL.ConvertADLReturnValueIntoWords(ADLRet)}"); - } - // Release the memory for the DisplayInfo structure - if (IntPtr.Zero != DisplayBuffer) - Marshal.FreeCoTaskMem(DisplayBuffer); - } - } - else - { - SharedLogger.logger.Warn($"AMDLibrary/GenerateProfileDisplayIdentifiers: Error running ADL2_Adapter_Active_Get on Adapter #{oneAdapter.AdapterIndex}: {ADL.ConvertADLReturnValueIntoWords(ADLRet)}"); - } + SharedLogger.logger.Trace($"AMDLibrary/GetAMDDisplayConfig: ADL2_Adapter_Active_Get returned ADL_TRUE - AMD Adapter #{adapterIndex} is active! We can continue."); + } + else + { + SharedLogger.logger.Trace($"AMDLibrary/GetAMDDisplayConfig: ADL2_Adapter_Active_Get returned ADL_FALSE - AMD Adapter #{adapterIndex} is NOT active, so skipping."); + continue; } } else { - SharedLogger.logger.Warn($"AMDLibrary/GenerateProfileDisplayIdentifiers: Error running ADL2_Adapter_AdapterInfoX4_Get on AMD Video card: {ADL.ConvertADLReturnValueIntoWords(ADLRet)}"); + SharedLogger.logger.Warn($"AMDLibrary/GetAMDDisplayConfig: WARNING - ADL2_Adapter_Active_Get returned ADL_STATUS {ADLRet} when trying to see if AMD Adapter #{adapterIndex} is active. Trying to skip this adapter so something at least works."); + continue; } - } - // Release the memory for the AdapterInfo structure - if (IntPtr.Zero != AdapterBuffer) - { - Marshal.FreeCoTaskMem(AdapterBuffer); - } - // Return all the identifiers we've found - return displayIdentifiers; - } - else - { - SharedLogger.logger.Warn($"AMDLibrary/GenerateProfileDisplayIdentifiers: There were no AMD adapters found by AMD ADL."); - return null; - } - } - - public List GenerateAllAvailableDisplayIdentifiers() - { - SharedLogger.logger.Trace($"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: Getting AMD active adapter count"); - - int ADLRet = ADL.ADL_ERR; - int NumberOfAdapters = 0; - - List displayIdentifiers = new List(); - - if (null != ADL.ADL2_Adapter_NumberOfAdapters_Get) - { - ADL.ADL2_Adapter_NumberOfAdapters_Get(_adlContextHandle, ref NumberOfAdapters); - SharedLogger.logger.Trace($"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: Number Of Adapters: {NumberOfAdapters.ToString()} "); - } - - if (NumberOfAdapters > 0) - { - - IntPtr AdapterBuffer = IntPtr.Zero; - if (ADL.ADL2_Adapter_AdapterInfoX4_Get != null) - { - SharedLogger.logger.Trace($"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: ADL2_Adapter_AdapterInfoX4_Get DLL function exists."); - - // Get the Adapter info and put it in the AdapterBuffer - SharedLogger.logger.Trace($"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: Running ADL2_Adapter_AdapterInfoX4_Get to find all known AMD adapters."); - //ADLRet = ADL.ADL2_Adapter_AdapterInfoX4_Get(_adlContextHandle, AdapterBuffer, size); - int numAdapters = 0; - ADLRet = ADL.ADL2_Adapter_AdapterInfoX4_Get(_adlContextHandle, ADL.ADL_ADAPTER_INDEX_ALL, out numAdapters, out AdapterBuffer); - if (ADLRet == ADL.ADL_OK) + // Get the Adapter info for this adapter and put it in the AdapterBuffer + SharedLogger.logger.Trace($"AMDLibrary/GetAMDDisplayConfig: Running ADL2_Adapter_AdapterInfoX4_Get to get the information about AMD Adapter #{adapterIndex}."); + int numAdaptersInfo = 0; + IntPtr adapterInfoBuffer = IntPtr.Zero; + ADLRet = ADLImport.ADL2_Adapter_AdapterInfoX4_Get(_adlContextHandle, adapterIndex, out numAdaptersInfo, out adapterInfoBuffer); + if (ADLRet == ADL_STATUS.ADL_OK) { - - int IsActive = ADL.ADL_TRUE; // We only want to search for active adapters - - SharedLogger.logger.Trace($"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: Successfully run ADL2_Adapter_AdapterInfoX4_Get to find information about all known AMD adapters."); - - ADLAdapterInfoX2 oneAdapter = new ADLAdapterInfoX2(); - // Go through each adapter - for (int adapterLoop = 0; adapterLoop < numAdapters; adapterLoop++) - { - oneAdapter = (ADLAdapterInfoX2)Marshal.PtrToStructure(new IntPtr(AdapterBuffer.ToInt64() + (adapterLoop * Marshal.SizeOf(oneAdapter))), oneAdapter.GetType()); - - if (oneAdapter.Exist != 1) - { - SharedLogger.logger.Trace($"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: AMD Adapter #{oneAdapter.AdapterIndex.ToString()} doesn't exist at present so skipping detection for this adapter."); - continue; - } - - if (oneAdapter.Present != 1) - { - SharedLogger.logger.Trace($"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: AMD Adapter #{oneAdapter.AdapterIndex.ToString()} isn't enabled at present so skipping detection for this adapter."); - continue; - } - - // Check if the adapter is active - if (ADL.ADL2_Adapter_Active_Get != null) - ADLRet = ADL.ADL2_Adapter_Active_Get(_adlContextHandle, oneAdapter.AdapterIndex, ref IsActive); - - if (ADLRet == ADL.ADL_OK) - { - // Only continue if the adapter is enabled - if (IsActive != ADL.ADL_TRUE) - { - SharedLogger.logger.Trace($"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: AMD Adapter #{oneAdapter.AdapterIndex.ToString()} isn't active ({oneAdapter.AdapterName})."); - continue; - } - - // Only continue if the adapter index is > 0 - if (oneAdapter.AdapterIndex < 0) - { - SharedLogger.logger.Trace($"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: AMD Adapter has an adapter index of {oneAdapter.AdapterIndex.ToString()} which indicates it is not a real adapter."); - continue; - } - - SharedLogger.logger.Trace($"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: AMD Adapter #{oneAdapter.AdapterIndex.ToString()} is active! ({oneAdapter.AdapterName})."); - - SharedLogger.logger.Trace($"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: ### Adapter Info for Adapter #{oneAdapter.AdapterIndex} ###"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: Adapter AdapterIndex = {oneAdapter.AdapterIndex}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: Adapter AdapterName = {oneAdapter.AdapterName}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: Adapter BusNumber = {oneAdapter.BusNumber}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: Adapter DeviceNumber = {oneAdapter.DeviceNumber}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: Adapter DisplayName = {oneAdapter.DisplayName}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: Adapter DriverPath = {oneAdapter.DriverPath}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: Adapter DriverPathExt = {oneAdapter.DriverPathExt}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: Adapter Exist = {oneAdapter.Exist}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: Adapter FunctionNumber = {oneAdapter.FunctionNumber}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: Adapter InfoMask = {oneAdapter.InfoMask}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: Adapter InfoValue = {oneAdapter.InfoValue}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: Adapter OSDisplayIndex = {oneAdapter.OSDisplayIndex}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: Adapter PNPString = {oneAdapter.PNPString}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: Adapter Present = {oneAdapter.Present}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: Adapter Size = {oneAdapter.Size}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: Adapter UDID = {oneAdapter.UDID}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: Adapter VendorID = {oneAdapter.VendorID}"); - - // Get the Adapter Capabilities - ADLAdapterCapsX2 AdapterCapabilities = new ADLAdapterCapsX2(); - if (ADL.ADL2_AdapterX2_Caps != null) - { - ADLRet = ADL.ADL2_AdapterX2_Caps(_adlContextHandle, oneAdapter.AdapterIndex, out AdapterCapabilities); - } - - SharedLogger.logger.Trace($"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: ### Adapter Capabilities for Adapter #{oneAdapter.AdapterIndex} ###"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: Adapter ID = {AdapterCapabilities.AdapterID}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: Adapter Capabilities Mask = {AdapterCapabilities.CapsMask}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: Adapter Capabilities Value = {AdapterCapabilities.CapsValue}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: Adapter Num of Connectors = {AdapterCapabilities.NumConnectors}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: Adapter Num of Controllers = {AdapterCapabilities.NumControllers}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: Adapter Num of Displays = {AdapterCapabilities.NumDisplays}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: Adapter Num of GL Sync Connectors = {AdapterCapabilities.NumOfGLSyncConnectors}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: Adapter Num of Overlays = {AdapterCapabilities.NumOverlays}"); - - if (ADL.ADL2_Display_DisplayInfo_Get != null) - { - IntPtr DisplayBuffer = IntPtr.Zero; - int numDisplays = 0; - // Force the display detection and get the Display Info. Use 0 as last parameter to NOT force detection - ADLRet = ADL.ADL2_Display_DisplayInfo_Get(_adlContextHandle, oneAdapter.AdapterIndex, ref numDisplays, out DisplayBuffer, 1); - if (ADLRet == ADL.ADL_OK) - { - - try - { - ADLDisplayInfo oneDisplayInfo = new ADLDisplayInfo(); - - for (int displayLoop = 0; displayLoop < numDisplays; displayLoop++) - { - oneDisplayInfo = (ADLDisplayInfo)Marshal.PtrToStructure(new IntPtr(DisplayBuffer.ToInt64() + (displayLoop * Marshal.SizeOf(oneDisplayInfo))), oneDisplayInfo.GetType()); - - // Is the display mapped to this adapter? If not we skip it! - if (oneDisplayInfo.DisplayID.DisplayLogicalAdapterIndex != oneAdapter.AdapterIndex) - { - SharedLogger.logger.Trace($"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: AMD Adapter #{oneAdapter.AdapterIndex.ToString()} ({oneAdapter.AdapterName}) AdapterID display ID#{oneDisplayInfo.DisplayID.DisplayLogicalIndex} is not a real display as its DisplayID.DisplayLogicalAdapterIndex is -1"); - continue; - } - - // Convert the displayInfoValue to something usable using a library function I made - ConvertedDisplayInfoValue displayInfoValue = ADL.ConvertDisplayInfoValue(oneDisplayInfo.DisplayInfoValue); - - // Is the display mapped to this adapter? If not we skip it! - if (!displayInfoValue.DISPLAYCONNECTED) - { - SharedLogger.logger.Trace($"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: AMD Adapter #{oneAdapter.AdapterIndex.ToString()} ({oneAdapter.AdapterName}) AdapterID display ID#{oneDisplayInfo.DisplayID.DisplayLogicalIndex} is not connected"); - continue; - } - - // We want connected displays whether they are mapped or not mapped in Windows OS - - SharedLogger.logger.Trace($"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: AMD Adapter #{oneAdapter.AdapterIndex.ToString()} ({oneAdapter.AdapterName}) AdapterID display ID#{oneDisplayInfo.DisplayID.DisplayLogicalIndex} is connected and mapped in Windows OS"); - - ADL.ADLDisplayConnectionType displayConnector = (ADL.ADLDisplayConnectionType)oneDisplayInfo.DisplayConnector; - - SharedLogger.logger.Trace($"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: ### Display Info for Display #{oneDisplayInfo.DisplayID.DisplayLogicalIndex} on Adapter #{oneAdapter.AdapterIndex} ###"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: Display Connector = {displayConnector.ToString("G")}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: Display Controller Index = {oneDisplayInfo.DisplayControllerIndex}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: Display Logical Adapter Index = {oneDisplayInfo.DisplayID.DisplayLogicalAdapterIndex}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: Display Logical Index = {oneDisplayInfo.DisplayID.DisplayLogicalIndex}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: Display Physical Adapter Index = {oneDisplayInfo.DisplayID.DisplayPhysicalAdapterIndex}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: Display Physical Index = {oneDisplayInfo.DisplayID.DisplayPhysicalIndex}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: Display Info Mask = {oneDisplayInfo.DisplayInfoMask}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: Display Info Value = {oneDisplayInfo.DisplayInfoValue}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: Display Manufacturer Name = {oneDisplayInfo.DisplayManufacturerName}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: Display Name = {oneDisplayInfo.DisplayName}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: Display Output Type = {oneDisplayInfo.DisplayOutputType}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: Display Type = {oneDisplayInfo.DisplayType}"); - - SharedLogger.logger.Trace($"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: Display Info Value DISPLAYCONNECTED = {displayInfoValue.DISPLAYCONNECTED}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: Display Info Value DISPLAYMAPPED = {displayInfoValue.DISPLAYMAPPED}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: Display Info Value FORCIBLESUPPORTED = {displayInfoValue.FORCIBLESUPPORTED}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: Display Info Value GENLOCKSUPPORTED = {displayInfoValue.GENLOCKSUPPORTED}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: Display Info Value LDA_DISPLAY = {displayInfoValue.LDA_DISPLAY}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: Display Info Value MANNER_SUPPORTED_2HSTRETCH = {displayInfoValue.MANNER_SUPPORTED_2HSTRETCH}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: Display Info Value MANNER_SUPPORTED_2VSTRETCH = {displayInfoValue.MANNER_SUPPORTED_2VSTRETCH}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: Display Info Value MANNER_SUPPORTED_CLONE = {displayInfoValue.MANNER_SUPPORTED_CLONE}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: Display Info Value MANNER_SUPPORTED_EXTENDED = {displayInfoValue.MANNER_SUPPORTED_EXTENDED}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: Display Info Value MANNER_SUPPORTED_NSTRETCH1GPU = {displayInfoValue.MANNER_SUPPORTED_NSTRETCH1GPU}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: Display Info Value MANNER_SUPPORTED_NSTRETCHNGPU = {displayInfoValue.MANNER_SUPPORTED_NSTRETCHNGPU}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: Display Info Value MANNER_SUPPORTED_SINGLE = {displayInfoValue.MANNER_SUPPORTED_SINGLE}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: Display Info Value MODETIMING_OVERRIDESSUPPORTED = {displayInfoValue.MODETIMING_OVERRIDESSUPPORTED}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: Display Info Value MULTIVPU_SUPPORTED = {displayInfoValue.MULTIVPU_SUPPORTED}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: Display Info Value NONLOCAL = {displayInfoValue.NONLOCAL}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: Display Info Value SHOWTYPE_PROJECTOR = {displayInfoValue.SHOWTYPE_PROJECTOR}"); - - ADL.ADLDisplayConnectionType displayConnectionType = ADL.ADLDisplayConnectionType.Unknown; - ADLDisplayConfig displayConfig = new ADLDisplayConfig(); - displayConfig.Size = Marshal.SizeOf(displayConfig); - if (ADL.ADL2_Display_DeviceConfig_Get != null) - { - // Get the DisplayConfig from the Display - ADLRet = ADL.ADL2_Display_DeviceConfig_Get(_adlContextHandle, oneAdapter.AdapterIndex, oneDisplayInfo.DisplayID.DisplayPhysicalIndex, out displayConfig); - if (ADLRet == ADL.ADL_OK) - { - displayConnectionType = (ADL.ADLDisplayConnectionType)displayConfig.ConnectorType; - - SharedLogger.logger.Trace($"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: ### Display Device Config for Display #{oneDisplayInfo.DisplayID.DisplayLogicalIndex} on Adapter #{oneAdapter.AdapterIndex} ###"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: Display Connector Type = {displayConnectionType.ToString("G")}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: Display Device Data = {displayConfig.DeviceData}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: Display Overridded Device Data = {displayConfig.OverriddedDeviceData}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: Display Reserved Data = {displayConfig.Reserved}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: Display Size = {displayConfig.Size}"); - } - else - { - SharedLogger.logger.Warn($"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: Error running ADL2_Display_DeviceConfig_Get on Display #{oneDisplayInfo.DisplayID.DisplayLogicalIndex} on Adapter #{oneAdapter.AdapterIndex}: {ADL.ConvertADLReturnValueIntoWords(ADLRet)}"); - } - } - - ADLDDCInfo2 displayDDCInfo2 = new ADLDDCInfo2(); - displayDDCInfo2.Size = Marshal.SizeOf(displayDDCInfo2); - // Create a stringbuilder buffer that EDID can be loaded into - //displayEDIDData.EDIDData = new StringBuilder(256); - - if (ADL.ADL2_Display_DDCInfo2_Get != null) - { - // Get the DDC Data from the Display - ADLRet = ADL.ADL2_Display_DDCInfo2_Get(_adlContextHandle, oneAdapter.AdapterIndex, oneDisplayInfo.DisplayID.DisplayPhysicalIndex, out displayDDCInfo2); - if (ADLRet == ADL.ADL_OK) - { - - // Convert the DDCInfoFlag to something usable using a library function I made - ConvertedDDCInfoFlag DDCInfoFlag = ADL.ConvertDDCInfoFlag(displayDDCInfo2.DDCInfoFlag); - - // Convert the DDCInfoFlag to something usable using a library function I made - ConvertedSupportedHDR supportedHDR = ADL.ConvertSupportedHDR(displayDDCInfo2.SupportedHDR); - - SharedLogger.logger.Trace($"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: ### Display DDCInfo2 for Display #{oneDisplayInfo.DisplayID.DisplayLogicalIndex} on Adapter #{oneAdapter.AdapterIndex} ###"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: Display AvgLuminanceData = {displayDDCInfo2.AvgLuminanceData}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: Display DDCInfoFlag = {displayDDCInfo2.DDCInfoFlag}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: Display DiffuseScreenReflectance = {displayDDCInfo2.DiffuseScreenReflectance}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: Display DisplayName = {displayDDCInfo2.DisplayName}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: Display FreesyncFlags = {displayDDCInfo2.FreesyncFlags}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: Display ManufacturerID = {displayDDCInfo2.ManufacturerID}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: Display MaxBacklightMaxLuminanceData = {displayDDCInfo2.MaxBacklightMaxLuminanceData}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: Display MaxBacklightMinLuminanceData = {displayDDCInfo2.MaxBacklightMinLuminanceData}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: Display MaxHResolution = {displayDDCInfo2.MaxHResolution}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: Display MaxLuminanceData = {displayDDCInfo2.MaxLuminanceData}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: Display MaxRefresh = {displayDDCInfo2.MaxRefresh}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: Display MaxVResolution = {displayDDCInfo2.MaxVResolution}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: Display MinBacklightMaxLuminanceData = {displayDDCInfo2.MinBacklightMaxLuminanceData}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: Display MinBacklightMinLuminanceData = {displayDDCInfo2.MinBacklightMinLuminanceData}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: Display MinLuminanceData = {displayDDCInfo2.MinLuminanceData}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: Display MinLuminanceNoDimmingData = {displayDDCInfo2.MinLuminanceNoDimmingData}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: Display NativeDisplayChromaticityBlueX = {displayDDCInfo2.NativeDisplayChromaticityBlueX}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: Display NativeDisplayChromaticityBlueY = {displayDDCInfo2.NativeDisplayChromaticityBlueY}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: Display NativeDisplayChromaticityGreenX = {displayDDCInfo2.NativeDisplayChromaticityGreenX}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: Display NativeDisplayChromaticityGreenY = {displayDDCInfo2.NativeDisplayChromaticityGreenY}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: Display NativeDisplayChromaticityRedX = {displayDDCInfo2.NativeDisplayChromaticityRedX}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: Display NativeDisplayChromaticityRedY = {displayDDCInfo2.NativeDisplayChromaticityRedY}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: Display NativeDisplayChromaticityWhiteX = {displayDDCInfo2.NativeDisplayChromaticityWhiteX}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: Display NativeDisplayChromaticityWhiteY = {displayDDCInfo2.NativeDisplayChromaticityWhiteY}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: Display PackedPixelSupported = {displayDDCInfo2.PackedPixelSupported}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: Display PanelPixelFormat = {displayDDCInfo2.PanelPixelFormat}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: Display ProductID = {displayDDCInfo2.ProductID}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: Display PTMCx = {displayDDCInfo2.PTMCx}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: Display PTMCy = {displayDDCInfo2.PTMCy}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: Display PTMRefreshRate = {displayDDCInfo2.PTMRefreshRate}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: Display SerialID = {displayDDCInfo2.SerialID}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: Display Size = {displayDDCInfo2.Size}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: Display SpecularScreenReflectance = {displayDDCInfo2.SpecularScreenReflectance}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: Display SupportedColorSpace = {displayDDCInfo2.SupportedColorSpace}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: Display SupportedHDR = {displayDDCInfo2.SupportedHDR}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: Display SupportedTransferFunction = {displayDDCInfo2.SupportedTransferFunction}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: Display SupportsDDC = {displayDDCInfo2.SupportsDDC}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: Display DDCInfoFlag Digital Device = {DDCInfoFlag.DIGITALDEVICE}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: Display DDCInfoFlag EDID Extension = {DDCInfoFlag.EDIDEXTENSION}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: Display DDCInfoFlag HDMI Audio Device = {DDCInfoFlag.HDMIAUDIODEVICE}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: Display DDCInfoFlag Projector Device = {DDCInfoFlag.PROJECTORDEVICE}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: Display DDCInfoFlag Supports AI = {DDCInfoFlag.SUPPORTS_AI}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: Display DDCInfoFlag Supports xvYCC601 = {DDCInfoFlag.SUPPORT_xvYCC601}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: Display DDCInfoFlag Supports xvYCC709 = {DDCInfoFlag.SUPPORT_xvYCC709}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: Display SupportedHDR Supports CEA861_3 = {supportedHDR.CEA861_3}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: Display SupportedHDR Supports DOLBYVISION = {supportedHDR.DOLBYVISION}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: Display SupportedHDR Supports FREESYNC_HDR = {supportedHDR.FREESYNC_HDR}"); - } - else - { - SharedLogger.logger.Warn($"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: Error running ADL2_Display_DDCInfo2_Get on Display #{oneDisplayInfo.DisplayID.DisplayLogicalIndex} on Adapter #{oneAdapter.AdapterIndex}: {ADL.ConvertADLReturnValueIntoWords(ADLRet)}"); - } - } - - int HDRSupported = 0; - int HDREnabled = 0; - if (ADL.ADL2_Display_HDRState_Get != null) - { - // Get the HDR State from the Display - ADLRet = ADL.ADL2_Display_HDRState_Get(_adlContextHandle, oneAdapter.AdapterIndex, oneDisplayInfo.DisplayID, out HDRSupported, out HDREnabled); - if (ADLRet == ADL.ADL_OK) - { - SharedLogger.logger.Trace($"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: ### Display HDR State for Display #{oneDisplayInfo.DisplayID.DisplayLogicalIndex} on Adapter #{oneAdapter.AdapterIndex} ###"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: Display HDR Supported = {HDRSupported}"); - SharedLogger.logger.Trace($"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: Display HDR Enabled = {HDREnabled}"); - } - else - { - SharedLogger.logger.Warn($"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: Error running ADL2_Display_HDRState_Get on Display #{oneDisplayInfo.DisplayID.DisplayLogicalIndex} on Adapter #{oneAdapter.AdapterIndex}: {ADL.ConvertADLReturnValueIntoWords(ADLRet)}"); - } - } - - - // Create an array of all the important display info we need to record - List displayInfoIdentifierSection = new List(); - displayInfoIdentifierSection.Add("AMD"); - try - { - displayInfoIdentifierSection.Add(oneAdapter.VendorID.ToString()); - } - catch (Exception ex) - { - SharedLogger.logger.Warn(ex, $"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: Exception getting AMD Vendor ID from video card. Substituting with a # instead"); - displayInfoIdentifierSection.Add("#"); - } - - try - { - displayInfoIdentifierSection.Add(oneAdapter.AdapterName); - } - catch (Exception ex) - { - SharedLogger.logger.Warn(ex, $"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: Exception getting AMD Adapter Name from video card. Substituting with a # instead"); - displayInfoIdentifierSection.Add("#"); - } - - try - { - displayInfoIdentifierSection.Add(oneAdapter.VendorID.ToString()); - } - catch (Exception ex) - { - SharedLogger.logger.Warn(ex, $"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: Exception getting AMD VendorID from video card. Substituting with a # instead"); - displayInfoIdentifierSection.Add("1002"); - } - - try - { - displayInfoIdentifierSection.Add(AdapterCapabilities.AdapterID.ToString()); - } - catch (Exception ex) - { - SharedLogger.logger.Warn(ex, $"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: Exception getting AMD AdapterID from video card. Substituting with a # instead"); - displayInfoIdentifierSection.Add("#"); - } - - try - { - displayInfoIdentifierSection.Add(displayConnector.ToString("G")); - } - catch (Exception ex) - { - SharedLogger.logger.Warn(ex, $"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: Exception getting AMD Display Connector from video card to display. Substituting with a # instead"); - displayInfoIdentifierSection.Add("#"); - } - - try - { - displayInfoIdentifierSection.Add(oneDisplayInfo.DisplayName); - } - catch (Exception ex) - { - SharedLogger.logger.Warn(ex, $"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: Exception getting Display Name from display connected to AMD video card. Substituting with a # instead"); - displayInfoIdentifierSection.Add("#"); - } - - try - { - displayInfoIdentifierSection.Add(displayDDCInfo2.ManufacturerID.ToString()); - } - catch (Exception ex) - { - SharedLogger.logger.Warn(ex, $"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: Exception getting Manufacturer ID from display connected to AMD video card. Substituting with a # instead"); - displayInfoIdentifierSection.Add("#"); - } - - try - { - displayInfoIdentifierSection.Add(displayDDCInfo2.ProductID.ToString()); - } - catch (Exception ex) - { - SharedLogger.logger.Warn(ex, $"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: Exception getting Product ID from display connected to AMD video card. Substituting with a # instead"); - displayInfoIdentifierSection.Add("#"); - } - - try - { - displayInfoIdentifierSection.Add(displayDDCInfo2.SerialID.ToString()); - } - catch (Exception ex) - { - SharedLogger.logger.Warn(ex, $"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: Exception getting Serial ID from display connected to AMD video card. Substituting with a # instead"); - displayInfoIdentifierSection.Add("#"); - } - - // Create a display identifier out of it - string displayIdentifier = String.Join("|", displayInfoIdentifierSection); - - // Check first to see if there is already an existing display identifier the same! - // This appears to be a bug with the AMD driver, or with the install on my test machine - // Either way, it is potentially going to happen in the wild, so I will filter it out if it does - if (displayIdentifiers.Contains(displayIdentifier)) - { - SharedLogger.logger.Trace($"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: Your AMD driver reported the following Display Identifier multiple times, so ignoring it as we already have it: {displayIdentifier}"); - continue; - } - - // Add it to the list of display identifiers so we can return it - displayIdentifiers.Add(displayIdentifier); - - SharedLogger.logger.Debug($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: DisplayIdentifier: {displayIdentifier}"); - } - } - catch (Exception ex) - { - SharedLogger.logger.Warn(ex, $"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: Exception caused trying to access attached displays"); - continue; - } - } - else - { - SharedLogger.logger.Warn($"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: Error running ADL2_Display_DisplayInfo_Get on Adapter #{oneAdapter.AdapterIndex}: {ADL.ConvertADLReturnValueIntoWords(ADLRet)}"); - } - // Release the memory for the DisplayInfo structure - if (IntPtr.Zero != DisplayBuffer) - Marshal.FreeCoTaskMem(DisplayBuffer); - } - } - else - { - SharedLogger.logger.Warn($"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: Error running ADL2_Adapter_Active_Get on Adapter #{oneAdapter.AdapterIndex}: {ADL.ConvertADLReturnValueIntoWords(ADLRet)}"); - } - } + SharedLogger.logger.Trace($"AMDLibrary/GetAMDDisplayConfig: ADL2_Adapter_AdapterInfoX4_Get returned information about AMD Adapter #{adapterIndex}."); } else { - SharedLogger.logger.Warn($"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: Error running ADL2_Adapter_AdapterInfoX4_Get on AMD Video card: {ADL.ConvertADLReturnValueIntoWords(ADLRet)}"); + SharedLogger.logger.Error($"AMDLibrary/GetAMDDisplayConfig: ERROR - ADL2_Adapter_AdapterInfoX4_Get returned ADL_STATUS {ADLRet} when trying to get the adapter info from AMD Adapter #{adapterIndex}. Trying to skip this adapter so something at least works."); + continue; } - } - // Release the memory for the AdapterInfo structure - if (IntPtr.Zero != AdapterBuffer) - { - Marshal.FreeCoTaskMem(AdapterBuffer); + + ADL_ADAPTER_INFOX2[] adapterArray = new ADL_ADAPTER_INFOX2[numAdaptersInfo]; + if (numAdaptersInfo > 0) + { + IntPtr currentDisplayTargetBuffer = adapterInfoBuffer; + for (int i = 0; i < numAdaptersInfo; i++) + { + // build a structure in the array slot + adapterArray[i] = new ADL_ADAPTER_INFOX2(); + // fill the array slot structure with the data from the buffer + adapterArray[i] = (ADL_ADAPTER_INFOX2)Marshal.PtrToStructure(currentDisplayTargetBuffer, typeof(ADL_ADAPTER_INFOX2)); + // destroy the bit of memory we no longer need + Marshal.DestroyStructure(currentDisplayTargetBuffer, typeof(ADL_ADAPTER_INFOX2)); + // advance the buffer forwards to the next object + currentDisplayTargetBuffer = (IntPtr)((long)currentDisplayTargetBuffer + Marshal.SizeOf(adapterArray[i])); + } + // Free the memory used by the buffer + Marshal.FreeCoTaskMem(adapterInfoBuffer); + } + + SharedLogger.logger.Trace($"AMDLibrary/GetAMDDisplayConfig: Converted ADL2_Adapter_AdapterInfoX4_Get memory buffer into a {adapterArray.Length} long array about AMD Adapter #{adapterIndex}."); + + AMD_ADAPTER_CONFIG savedAdapterConfig = new AMD_ADAPTER_CONFIG(); + ADL_ADAPTER_INFOX2 oneAdapter = adapterArray[0]; + if (oneAdapter.Exist != 1) + { + SharedLogger.logger.Trace($"AMDLibrary/GetAMDDisplayConfig: AMD Adapter #{oneAdapter.AdapterIndex.ToString()} doesn't exist at present so skipping detection for this adapter."); + continue; + } + + // Only skip non-present displays if we want all displays information + if (allDisplays && oneAdapter.Present != 1) + { + SharedLogger.logger.Trace($"AMDLibrary/GetAMDDisplayConfig: AMD Adapter #{oneAdapter.AdapterIndex.ToString()} isn't enabled at present so skipping detection for this adapter."); + continue; + } + + + savedAdapterConfig.AdapterBusNumber = oneAdapter.BusNumber; + savedAdapterConfig.AdapterDeviceNumber = oneAdapter.DeviceNumber; + savedAdapterConfig.AdapterIndex = oneAdapter.AdapterIndex; + if (oneAdapter.AdapterIndex == primaryAdapterIndex) + { + savedAdapterConfig.IsPrimaryAdapter = true; + } + else + { + savedAdapterConfig.IsPrimaryAdapter = false; + } + + + // Go grab the DisplayMaps and DisplayTargets + int numDisplayTargets = 0; + int numDisplayMaps = 0; + IntPtr displayTargetBuffer = IntPtr.Zero; + IntPtr displayMapBuffer = IntPtr.Zero; + ADLRet = ADLImport.ADL2_Display_DisplayMapConfig_Get(_adlContextHandle, adapterIndex, out numDisplayMaps, out displayMapBuffer, out numDisplayTargets, out displayTargetBuffer, ADLImport.ADL_DISPLAY_DISPLAYMAP_OPTION_GPUINFO); + if (ADLRet == ADL_STATUS.ADL_OK) + { + SharedLogger.logger.Trace($"AMDLibrary/GetAMDDisplayConfig: ADL2_Display_DisplayMapConfig_Get returned information about all displaytargets connected to AMD adapter {adapterIndex}."); + } + else + { + SharedLogger.logger.Error($"AMDLibrary/GetAMDDisplayConfig: ERROR - ADL2_Display_DisplayMapConfig_Get returned ADL_STATUS {ADLRet} when trying to get the display target info from AMD adapter {adapterIndex} in the computer."); + throw new AMDLibraryException($"ADL2_Display_DisplayMapConfig_Get returned ADL_STATUS {ADLRet} when trying to get the display target info from AMD adapter {adapterIndex} in the computer"); + } + + ADL_DISPLAY_MAP[] displayMapArray = { }; + if (numDisplayMaps > 0) + { + + IntPtr currentDisplayMapBuffer = displayMapBuffer; + displayMapArray = new ADL_DISPLAY_MAP[numDisplayMaps]; + for (int i = 0; i < numDisplayMaps; i++) + { + // build a structure in the array slot + displayMapArray[i] = new ADL_DISPLAY_MAP(); + // fill the array slot structure with the data from the buffer + displayMapArray[i] = (ADL_DISPLAY_MAP)Marshal.PtrToStructure(currentDisplayMapBuffer, typeof(ADL_DISPLAY_MAP)); + // destroy the bit of memory we no longer need + Marshal.DestroyStructure(currentDisplayMapBuffer, typeof(ADL_DISPLAY_MAP)); + // advance the buffer forwards to the next object + currentDisplayMapBuffer = (IntPtr)((long)currentDisplayMapBuffer + Marshal.SizeOf(displayMapArray[i])); + } + // Free the memory used by the buffer + Marshal.FreeCoTaskMem(displayMapBuffer); + // Save the item + //savedAdapterConfig.DisplayMaps = displayMapArray; + + } + + ADL_DISPLAY_TARGET[] retrievedDisplayTargets = { }; + if (numDisplayTargets > 0) + { + IntPtr currentDisplayTargetBuffer = displayTargetBuffer; + //displayTargetArray = new ADL_DISPLAY_TARGET[numDisplayTargets]; + retrievedDisplayTargets = new ADL_DISPLAY_TARGET[numDisplayTargets]; + for (int i = 0; i < numDisplayTargets; i++) + { + // build a structure in the array slot + retrievedDisplayTargets[i] = new ADL_DISPLAY_TARGET(); + //displayTargetArray[i] = new ADL_DISPLAY_TARGET(); + // fill the array slot structure with the data from the buffer + retrievedDisplayTargets[i] = (ADL_DISPLAY_TARGET)Marshal.PtrToStructure(currentDisplayTargetBuffer, typeof(ADL_DISPLAY_TARGET)); + //displayTargetArray[i] = (ADL_DISPLAY_TARGET)Marshal.PtrToStructure(currentDisplayTargetBuffer, typeof(ADL_DISPLAY_TARGET)); + // destroy the bit of memory we no longer need + Marshal.DestroyStructure(currentDisplayTargetBuffer, typeof(ADL_DISPLAY_TARGET)); + // advance the buffer forwards to the next object + currentDisplayTargetBuffer = (IntPtr)((long)currentDisplayTargetBuffer + Marshal.SizeOf(retrievedDisplayTargets[i])); + //currentDisplayTargetBuffer = (IntPtr)((long)currentDisplayTargetBuffer + Marshal.SizeOf(displayTargetArray[i])); + + } + // Free the memory used by the buffer + Marshal.FreeCoTaskMem(displayTargetBuffer); + // Save the item + //savedAdapterConfig.DisplayTargets = new ADL_DISPLAY_TARGET[numDisplayTargets]; + //savedAdapterConfig.DisplayTargets = displayTargetArray; + } + + for (int displayMapIndex = 0; displayMapIndex < numDisplayMaps; displayMapIndex++) + { + int foundDisplays = 0; + ADL_DISPLAY_MAP oneAdlDesktop = displayMapArray[displayMapIndex]; + ADL_DISPLAY_ID preferredDisplay; + + for (int displayTargetIndex = 0; displayTargetIndex < numDisplayTargets; displayTargetIndex++) + { + ADL_DISPLAY_TARGET oneAdlDisplay = retrievedDisplayTargets[displayTargetIndex]; + + if (oneAdlDesktop.DisplayMode.Orientation090Set || oneAdlDesktop.DisplayMode.Orientation270Set) + { + int oldXRes = oneAdlDesktop.DisplayMode.XRes; + oneAdlDesktop.DisplayMode.XRes = oneAdlDesktop.DisplayMode.YRes; + oneAdlDesktop.DisplayMode.YRes = oldXRes; + } + + // By default non-SLS; one row, one column + int rows = 1, cols = 1; + // By default SLsMapIndex is -1 and SLS Mode is fill + int slsMapIndex = -1, slsMode = ADLImport.ADL_DISPLAY_SLSMAP_SLSLAYOUTMODE_FILL; + + if (oneAdlDisplay.DisplayMapIndex == oneAdlDesktop.DisplayMapIndex) + { + if (primaryAdapterIndex == oneAdlDisplay.DisplayID.DisplayPhysicalAdapterIndex) + { + //add a display in list. For SLS this info will be updated later + /*displays.push_back(TopologyDisplay(oneAdlDisplay.displayID, 0, + oneAdlDesktop.displayMode.iXRes, oneAdlDesktop.displayMode.iYRes, //size + 0, 0, //offset in desktop + 0, 0)); //grid location (0-based)*/ + + // count it and bail out of we found enough + foundDisplays++; + if (foundDisplays == oneAdlDesktop.NumDisplayTarget) + break; + } + } + } + } + + // Only check for SLS if there is more than one displaytarget (screen) + if (numDisplayTargets > 1) + { + + int numSLSMapIDs = -1; + IntPtr SLSMapIDBuffer = IntPtr.Zero; + int[] SLSMapIDArray; + ADLRet = ADLImport.ADL2_Display_SLSMapIndexList_Get(_adlContextHandle, oneAdapter.AdapterIndex, ref numSLSMapIDs, out SLSMapIDBuffer, ADLImport.ADL_DISPLAY_SLSMAPINDEXLIST_OPTION_ACTIVE); + if (ADLRet == ADL_STATUS.ADL_OK) + { + SLSMapIDArray = new int[numSLSMapIDs]; + if (numSLSMapIDs > 0) + { + IntPtr currentSLSMapsBuffer = SLSMapIDBuffer; + SLSMapIDArray = new int[numSLSMapIDs]; + for (int i = 0; i < numSLSMapIDs; i++) + { + // build a structure in the array slot + SLSMapIDArray[i] = 0; + // fill the array slot structure with the data from the buffer + SLSMapIDArray[i] = (int)Marshal.PtrToStructure(currentSLSMapsBuffer, typeof(int)); + // destroy the bit of memory we no longer need + Marshal.DestroyStructure(currentSLSMapsBuffer, typeof(ADL_SLS_MAP)); + // advance the buffer forwards to the next object + currentSLSMapsBuffer = (IntPtr)((long)currentSLSMapsBuffer + Marshal.SizeOf(SLSMapIDArray[i])); + } + // Free the memory used by the buffer + Marshal.FreeCoTaskMem(SLSMapIDBuffer); + } + } + + /*int numSLSRecords = -1; + IntPtr SLSRecordBuffer = IntPtr.Zero; + int[] SLSRecordArray; + ADLRet = ADLImport.ADL2_Display_SLSRecords_Get(_adlContextHandle, oneAdapter.AdapterIndex, savedAdapterConfig.DisplayTargets[0].DisplayID, out numSLSRecords, out SLSRecordBuffer); + if (ADLRet == ADL_STATUS.ADL_OK) + { + SLSRecordArray = new int[numSLSRecords]; + if (numSLSRecords > 0) + { + IntPtr currentSLSBuffer = SLSRecordBuffer; + SLSRecordArray = new int[numSLSRecords]; + for (int i = 0; i < numSLSMapIDs; i++) + { + // build a structure in the array slot + SLSRecordArray[i] = 0; + // fill the array slot structure with the data from the buffer + SLSRecordArray[i] = (int)Marshal.PtrToStructure(currentSLSBuffer, typeof(int)); + // destroy the bit of memory we no longer need + Marshal.DestroyStructure(currentSLSBuffer, typeof(ADL_SLS_MAP)); + // advance the buffer forwards to the next object + currentSLSBuffer = (IntPtr)((long)currentSLSBuffer + Marshal.SizeOf(SLSRecordArray[i])); + } + // Free the memory used by the buffer + Marshal.FreeCoTaskMem(SLSRecordBuffer); + } + }*/ + + + int SLSMapIndex = -1; + ADLRet = ADLImport.ADL2_Display_SLSMapIndex_Get(_adlContextHandle, oneAdapter.AdapterIndex, numDisplayTargets, retrievedDisplayTargets, out SLSMapIndex); + //ADLRet = ADLImport.ADL2_Display_SLSMapIndexList_Get(_adlContextHandle, adapterNum, ref numSLSMapIDs, out SLSMapIDBuffer, ADLImport.ADL_DISPLAY_SLSMAPINDEXLIST_OPTION_ACTIVE); + if (ADLRet == ADL_STATUS.ADL_OK) + { + SharedLogger.logger.Trace($"AMDLibrary/GetAMDDisplayConfig: SLS (Eyfinity) is enabled on AMD adapter {adapterIndex}."); + + // Set the SLS Map Index if there is Eyefinity + //savedAdapterConfig.IsSLSPossible = true; + savedAdapterConfig.SLSMapIndex = SLSMapIndex; + /*for (int slsMapIdx = 0; slsMapIdx < SLSMapIndex; slsMapIdx++) + {*/ + //bool isActiveSLS = false; + // TODO Get the SLS Map Config X2?? + + int numSLSTargets = 0; + IntPtr SLSTargetBuffer = IntPtr.Zero; + int numNativeMode = 0; + IntPtr nativeModeBuffer = IntPtr.Zero; + int numNativeModeOffsets = 0; + IntPtr nativeModeOffsetsBuffer = IntPtr.Zero; + int numBezelMode = 0; + IntPtr bezelModeBuffer = IntPtr.Zero; + int numTransientMode = 0; + IntPtr TransientModeBuffer = IntPtr.Zero; + int numSLSOffset = 0; + IntPtr SLSOffsetBuffer = IntPtr.Zero; + //ADL2_Display_SLSMapConfigX2_Get(IntPtr ADLContextHandle, int adapterIndex, int SLSMapIndex, ref ADL_SLS_MAP[] SLSMap, ref int NumSLSTarget, out IntPtr SLSTargetArray, ref int lpNumNativeMode, out IntPtr NativeMode, ref int NumNativeModeOffsets, out IntPtr NativeModeOffsets, ref int NumBezelMode, out IntPtr BezelMode, ref int NumTransientMode, out IntPtr TransientMode, ref int NumSLSOffset, out IntPtr SLSOffset, int option); + ADL_SLS_MAP SLSMap = new ADL_SLS_MAP(); + //int SLSMapIndex = SLSMapIDArray[slsMapIdx]; + //ADLRet = ADLImport.ADL2_Display_SLSMapConfigX2_Get(_adlContextHandle, adapterNum, SLSMapIndex, out SLSMap, out numSLSTargets, out SLSTargetBuffer, out numNativeMode, out nativeModeBuffer, out numNativeModeOffsets, + // out nativeModeOffsetsBuffer, out numBezelMode, out bezelModeBuffer, out numTransientMode, out TransientModeBuffer, out numSLSOffset, out SLSOffsetBuffer, (int)2); + ADLRet = ADLImport.ADL2_Display_SLSMapConfigX2_Get( + _adlContextHandle, + oneAdapter.AdapterIndex, + SLSMapIndex, + out SLSMap, + out numSLSTargets, + out SLSTargetBuffer, + out numNativeMode, + out nativeModeBuffer, + out numNativeModeOffsets, + out nativeModeOffsetsBuffer, + out numBezelMode, + out bezelModeBuffer, + out numTransientMode, + out TransientModeBuffer, + out numSLSOffset, + out SLSOffsetBuffer, + ADLImport.ADL_DISPLAY_SLSGRID_CAP_OPTION_RELATIVETO_CURRENTANGLE); + if (ADLRet == ADL_STATUS.ADL_OK) + { + SharedLogger.logger.Trace($"AMDLibrary/GetAMDDisplayConfig: ADL2_Display_SLSMapConfigX2_Get returned information about the SLS Info connected to AMD adapter {adapterIndex}."); + } + else + { + SharedLogger.logger.Error($"AMDLibrary/GetAMDDisplayConfig: ERROR - ADL2_Display_SLSMapConfigX2_Get returned ADL_STATUS {ADLRet} when trying to get the SLS Info from AMD adapter {adapterIndex} in the computer."); + //throw new AMDLibraryException($"ADL2_Display_DisplayMapConfig_Get returned ADL_STATUS {ADLRet} when trying to get the display target info from AMD adapter {adapterNum} in the computer"); + } + } + else + { + SharedLogger.logger.Error($"AMDLibrary/GetAMDDisplayConfig: SLS (Eyfinity) is NOT enabled on AMD adapter {adapterIndex} (can't be as there is only one display!)."); + // Set the SLS Map Index if there is NOT Eyefinity + savedAdapterConfig.IsSLSEnabled = false; + savedAdapterConfig.SLSMapIndex = -1; + + } + } + + // We want to get the AMD HDR information and store it for later + //ADL2_Display_HDRState_Get(ADL_CONTEXT_HANDLE context, int iAdapterIndex, ADLDisplayID displayID, int * iSupport, int * iEnable) + // Save the AMD Adapter Config + if (!myDisplayConfig.AdapterConfigs.Contains(savedAdapterConfig)) + { + // Save the new adapter config only if we haven't already + myDisplayConfig.AdapterConfigs.Add(savedAdapterConfig); + } + } - // Return all the identifiers we've found - return displayIdentifiers; + // We want to get the Windows CCD information and store it for later so that we record + // display sizes, and screen positions and the like. + myDisplayConfig.WindowsDisplayConfig = _winLibrary.GetActiveConfig(); } else { - SharedLogger.logger.Warn($"AMDLibrary/GenerateAllAvailableDisplayIdentifiers: There were no AMD adapters found by AMD ADL."); - return null; + SharedLogger.logger.Error($"AMDLibrary/GetAMDDisplayConfig: ERROR - Tried to run GetAMDDisplayConfig but the AMD ADL library isn't initialised!"); + throw new AMDLibraryException($"Tried to run GetAMDDisplayConfig but the AMD ADL library isn't initialised!"); } + + // Return the configuration + return myDisplayConfig; } - public AMDProfile GetActiveProfile() + + public string PrintActiveConfig() { - SharedLogger.logger.Trace($"AMDLibrary/GetActiveProfile: Getting AMD active adapter count"); + string stringToReturn = ""; - int ADLRet = ADL.ADL_ERR; - int NumberOfAdapters = 0; - - List displayIdentifiers = new List(); - AMDProfile profileToCreate = new AMDProfile(); - - - if (null != ADL.ADL2_Adapter_NumberOfAdapters_Get) + // Get the size of the largest Active Paths and Modes arrays + int pathCount = 0; + int modeCount = 0; + WIN32STATUS err = CCDImport.GetDisplayConfigBufferSizes(QDC.QDC_ONLY_ACTIVE_PATHS, out pathCount, out modeCount); + if (err != WIN32STATUS.ERROR_SUCCESS) { - ADL.ADL2_Adapter_NumberOfAdapters_Get(_adlContextHandle, ref NumberOfAdapters); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveProfile: Number Of Adapters: {NumberOfAdapters.ToString()} "); + SharedLogger.logger.Error($"AMDLibrary/PrintActiveConfig: ERROR - GetDisplayConfigBufferSizes returned WIN32STATUS {err} when trying to get the maximum path and mode sizes"); + throw new AMDLibraryException($"GetDisplayConfigBufferSizes returned WIN32STATUS {err} when trying to get the maximum path and mode sizes"); } - if (NumberOfAdapters > 0) + SharedLogger.logger.Trace($"AMDLibrary/PrintActiveConfig: Getting the current Display Config path and mode arrays"); + var paths = new DISPLAYCONFIG_PATH_INFO[pathCount]; + var modes = new DISPLAYCONFIG_MODE_INFO[modeCount]; + err = CCDImport.QueryDisplayConfig(QDC.QDC_ONLY_ACTIVE_PATHS, ref pathCount, paths, ref modeCount, modes, IntPtr.Zero); + if (err == WIN32STATUS.ERROR_INSUFFICIENT_BUFFER) { - profileToCreate.Adapters = new List(); - IntPtr AdapterBuffer = IntPtr.Zero; - if (ADL.ADL2_Adapter_AdapterInfoX4_Get != null) + SharedLogger.logger.Warn($"AMDLibrary/PrintActiveConfig: The displays were modified between GetDisplayConfigBufferSizes and QueryDisplayConfig so we need to get the buffer sizes again."); + SharedLogger.logger.Trace($"AMDLibrary/PrintActiveConfig: Getting the size of the largest Active Paths and Modes arrays"); + // Screen changed in between GetDisplayConfigBufferSizes and QueryDisplayConfig, so we need to get buffer sizes again + // as per https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-querydisplayconfig + err = CCDImport.GetDisplayConfigBufferSizes(QDC.QDC_ONLY_ACTIVE_PATHS, out pathCount, out modeCount); + if (err != WIN32STATUS.ERROR_SUCCESS) { - SharedLogger.logger.Trace($"AMDLibrary/GetActiveProfile: ADL2_Adapter_AdapterInfoX4_Get DLL function exists."); + SharedLogger.logger.Error($"AMDLibrary/PrintActiveConfig: ERROR - GetDisplayConfigBufferSizes returned WIN32STATUS {err} when trying to get the maximum path and mode sizes again"); + throw new AMDLibraryException($"GetDisplayConfigBufferSizes returned WIN32STATUS {err} when trying to get the maximum path and mode sizes again"); + } + SharedLogger.logger.Trace($"AMDLibrary/PrintActiveConfig: Getting the current Display Config path and mode arrays"); + paths = new DISPLAYCONFIG_PATH_INFO[pathCount]; + modes = new DISPLAYCONFIG_MODE_INFO[modeCount]; + err = CCDImport.QueryDisplayConfig(QDC.QDC_ONLY_ACTIVE_PATHS, ref pathCount, paths, ref modeCount, modes, IntPtr.Zero); + if (err == WIN32STATUS.ERROR_INSUFFICIENT_BUFFER) + { + SharedLogger.logger.Error($"AMDLibrary/PrintActiveConfig: ERROR - The displays were still modified between GetDisplayConfigBufferSizes and QueryDisplayConfig, even though we tried twice. Something is wrong."); + throw new AMDLibraryException($"The displays were still modified between GetDisplayConfigBufferSizes and QueryDisplayConfig, even though we tried twice. Something is wrong."); + } + else if (err != WIN32STATUS.ERROR_SUCCESS) + { + SharedLogger.logger.Error($"AMDLibrary/PrintActiveConfig: ERROR - QueryDisplayConfig returned WIN32STATUS {err} when trying to query all available displays again"); + throw new AMDLibraryException($"QueryDisplayConfig returned WIN32STATUS {err} when trying to query all available displays again."); + } + } + else if (err != WIN32STATUS.ERROR_SUCCESS) + { + SharedLogger.logger.Error($"AMDLibrary/PrintActiveConfig: ERROR - QueryDisplayConfig returned WIN32STATUS {err} when trying to query all available displays"); + throw new AMDLibraryException($"QueryDisplayConfig returned WIN32STATUS {err} when trying to query all available displays."); + } - // Get the Adapter info and put it in the AdapterBuffer - SharedLogger.logger.Trace($"AMDLibrary/GetActiveProfile: Running ADL2_Adapter_AdapterInfoX4_Get to find all known AMD adapters."); - //ADLRet = ADL.ADL2_Adapter_AdapterInfoX4_Get(_adlContextHandle, AdapterBuffer, size); - int numAdapters = 0; - ADLRet = ADL.ADL2_Adapter_AdapterInfoX4_Get(_adlContextHandle, ADL.ADL_ADAPTER_INDEX_ALL, out numAdapters, out AdapterBuffer); - if (ADLRet == ADL.ADL_OK) + foreach (var path in paths) + { + stringToReturn += $"----++++==== Path ====++++----\n"; + + // get display source name + var sourceInfo = new DISPLAYCONFIG_SOURCE_DEVICE_NAME(); + sourceInfo.Header.Type = DISPLAYCONFIG_DEVICE_INFO_TYPE.DISPLAYCONFIG_DEVICE_INFO_GET_SOURCE_NAME; + sourceInfo.Header.Size = (uint)Marshal.SizeOf(); + sourceInfo.Header.AdapterId = path.SourceInfo.AdapterId; + sourceInfo.Header.Id = path.SourceInfo.Id; + err = CCDImport.DisplayConfigGetDeviceInfo(ref sourceInfo); + if (err == WIN32STATUS.ERROR_SUCCESS) + { + SharedLogger.logger.Trace($"AMDLibrary/PrintActiveConfig: Found Display Source {sourceInfo.ViewGdiDeviceName} for source {path.SourceInfo.Id}."); + stringToReturn += $"****** Interrogating Display Source {path.SourceInfo.Id} *******\n"; + stringToReturn += $"Found Display Source {sourceInfo.ViewGdiDeviceName}\n"; + stringToReturn += $"\n"; + } + else + { + SharedLogger.logger.Warn($"AMDLibrary/PrintActiveConfig: WARNING - DisplayConfigGetDeviceInfo returned WIN32STATUS {err} when trying to get the source info for source adapter #{path.SourceInfo.AdapterId}"); + } + + + // get display target name + var targetInfo = new DISPLAYCONFIG_TARGET_DEVICE_NAME(); + targetInfo.Header.Type = DISPLAYCONFIG_DEVICE_INFO_TYPE.DISPLAYCONFIG_DEVICE_INFO_GET_TARGET_NAME; + targetInfo.Header.Size = (uint)Marshal.SizeOf(); + targetInfo.Header.AdapterId = path.TargetInfo.AdapterId; + targetInfo.Header.Id = path.TargetInfo.Id; + err = CCDImport.DisplayConfigGetDeviceInfo(ref targetInfo); + if (err == WIN32STATUS.ERROR_SUCCESS) + { + SharedLogger.logger.Trace($"AMDLibrary/PrintActiveConfig: Connector Instance: {targetInfo.ConnectorInstance} for source {path.TargetInfo.Id}."); + SharedLogger.logger.Trace($"AMDLibrary/PrintActiveConfig: EDID Manufacturer ID: {targetInfo.EdidManufactureId} for source {path.TargetInfo.Id}."); + SharedLogger.logger.Trace($"AMDLibrary/PrintActiveConfig: EDID Product Code ID: {targetInfo.EdidProductCodeId} for source {path.TargetInfo.Id}."); + SharedLogger.logger.Trace($"AMDLibrary/PrintActiveConfig: Flags Friendly Name from EDID: {targetInfo.Flags.FriendlyNameFromEdid} for source {path.TargetInfo.Id}."); + SharedLogger.logger.Trace($"AMDLibrary/PrintActiveConfig: Flags Friendly Name Forced: {targetInfo.Flags.FriendlyNameForced} for source {path.TargetInfo.Id}."); + SharedLogger.logger.Trace($"AMDLibrary/PrintActiveConfig: Flags EDID ID is Valid: {targetInfo.Flags.EdidIdsValid} for source {path.TargetInfo.Id}."); + SharedLogger.logger.Trace($"AMDLibrary/PrintActiveConfig: Monitor Device Path: {targetInfo.MonitorDevicePath} for source {path.TargetInfo.Id}."); + SharedLogger.logger.Trace($"AMDLibrary/PrintActiveConfig: Monitor Friendly Device Name: {targetInfo.MonitorFriendlyDeviceName} for source {path.TargetInfo.Id}."); + SharedLogger.logger.Trace($"AMDLibrary/PrintActiveConfig: Output Technology: {targetInfo.OutputTechnology} for source {path.TargetInfo.Id}."); + + stringToReturn += $"****** Interrogating Display Target {targetInfo.MonitorFriendlyDeviceName} *******\n"; + stringToReturn += $" Connector Instance: {targetInfo.ConnectorInstance}\n"; + stringToReturn += $" EDID Manufacturer ID: {targetInfo.EdidManufactureId}\n"; + stringToReturn += $" EDID Product Code ID: {targetInfo.EdidProductCodeId}\n"; + stringToReturn += $" Flags Friendly Name from EDID: {targetInfo.Flags.FriendlyNameFromEdid}\n"; + stringToReturn += $" Flags Friendly Name Forced: {targetInfo.Flags.FriendlyNameForced}\n"; + stringToReturn += $" Flags EDID ID is Valid: {targetInfo.Flags.EdidIdsValid}\n"; + stringToReturn += $" Monitor Device Path: {targetInfo.MonitorDevicePath}\n"; + stringToReturn += $" Monitor Friendly Device Name: {targetInfo.MonitorFriendlyDeviceName}\n"; + stringToReturn += $" Output Technology: {targetInfo.OutputTechnology}\n"; + stringToReturn += $"\n"; + } + else + { + SharedLogger.logger.Warn($"AMDLibrary/PrintActiveConfig: WARNING - DisplayConfigGetDeviceInfo returned WIN32STATUS {err} when trying to get the target info for display #{path.TargetInfo.Id}"); + } + + + // get display adapter name + var adapterInfo = new DISPLAYCONFIG_ADAPTER_NAME(); + adapterInfo.Header.Type = DISPLAYCONFIG_DEVICE_INFO_TYPE.DISPLAYCONFIG_DEVICE_INFO_GET_ADAPTER_NAME; + adapterInfo.Header.Size = (uint)Marshal.SizeOf(); + adapterInfo.Header.AdapterId = path.TargetInfo.AdapterId; + adapterInfo.Header.Id = path.TargetInfo.Id; + err = CCDImport.DisplayConfigGetDeviceInfo(ref adapterInfo); + if (err == WIN32STATUS.ERROR_SUCCESS) + { + SharedLogger.logger.Trace($"AMDLibrary/PrintActiveConfig: Found Adapter Device Path {adapterInfo.AdapterDevicePath} for source {path.TargetInfo.AdapterId}."); + stringToReturn += $"****** Interrogating Display Adapter {adapterInfo.AdapterDevicePath} *******\n"; + stringToReturn += $" Display Adapter {adapterInfo.AdapterDevicePath}\n"; + stringToReturn += $"\n"; + } + else + { + SharedLogger.logger.Warn($"AMDLibrary/GetWindowsDisplayConfig: WARNING - DisplayConfigGetDeviceInfo returned WIN32STATUS {err} when trying to get the adapter device path for target #{path.TargetInfo.AdapterId}"); + } + + // get display target preferred mode + var targetPreferredInfo = new DISPLAYCONFIG_TARGET_PREFERRED_MODE(); + targetPreferredInfo.Header.Type = DISPLAYCONFIG_DEVICE_INFO_TYPE.DISPLAYCONFIG_DEVICE_INFO_GET_TARGET_PREFERRED_MODE; + targetPreferredInfo.Header.Size = (uint)Marshal.SizeOf(); + targetPreferredInfo.Header.AdapterId = path.TargetInfo.AdapterId; + targetPreferredInfo.Header.Id = path.TargetInfo.Id; + err = CCDImport.DisplayConfigGetDeviceInfo(ref targetPreferredInfo); + if (err == WIN32STATUS.ERROR_SUCCESS) + { + SharedLogger.logger.Trace($"AMDLibrary/GetWindowsDisplayConfig: Found Target Preferred Width {targetPreferredInfo.Width} for target {path.TargetInfo.Id}."); + SharedLogger.logger.Trace($"AMDLibrary/GetWindowsDisplayConfig: Found Target Preferred Height {targetPreferredInfo.Height} for target {path.TargetInfo.Id}."); + SharedLogger.logger.Trace($"AMDLibrary/GetWindowsDisplayConfig: Found Target Video Signal Info Active Size: ({targetPreferredInfo.TargetMode.TargetVideoSignalInfo.ActiveSize.Cx}x{targetPreferredInfo.TargetMode.TargetVideoSignalInfo.ActiveSize.Cy} for target {path.TargetInfo.Id}."); + SharedLogger.logger.Trace($"AMDLibrary/GetWindowsDisplayConfig: Found Target Video Signal Info Total Size: ({targetPreferredInfo.TargetMode.TargetVideoSignalInfo.TotalSize.Cx}x{targetPreferredInfo.TargetMode.TargetVideoSignalInfo.TotalSize.Cy} for target {path.TargetInfo.Id}."); + SharedLogger.logger.Trace($"AMDLibrary/GetWindowsDisplayConfig: Found Target Video Signal Info HSync Frequency: {targetPreferredInfo.TargetMode.TargetVideoSignalInfo.HSyncFreq} for target {path.TargetInfo.Id}."); + SharedLogger.logger.Trace($"AMDLibrary/GetWindowsDisplayConfig: Found Target Video Signal Info VSync Frequency: {targetPreferredInfo.TargetMode.TargetVideoSignalInfo.VSyncFreq} for target {path.TargetInfo.Id}."); + SharedLogger.logger.Trace($"AMDLibrary/GetWindowsDisplayConfig: Found Target Video Signal Info Pixel Rate: {targetPreferredInfo.TargetMode.TargetVideoSignalInfo.PixelRate} for target {path.TargetInfo.Id}."); + SharedLogger.logger.Trace($"AMDLibrary/GetWindowsDisplayConfig: Found Target Video Signal Info Scan Line Ordering: {targetPreferredInfo.TargetMode.TargetVideoSignalInfo.ScanLineOrdering} for target {path.TargetInfo.Id}."); + SharedLogger.logger.Trace($"AMDLibrary/GetWindowsDisplayConfig: Found Target Video Signal Info Video Standard: {targetPreferredInfo.TargetMode.TargetVideoSignalInfo.VideoStandard} for target {path.TargetInfo.Id}."); + + stringToReturn += $"****** Interrogating Target Preferred Mode for Display {path.TargetInfo.Id} *******\n"; + stringToReturn += $" Target Preferred Width {targetPreferredInfo.Width} for target {path.TargetInfo.Id}\n"; + stringToReturn += $" Target Preferred Height {targetPreferredInfo.Height} for target {path.TargetInfo.Id}\n"; + stringToReturn += $" Target Video Signal Info Active Size: ({targetPreferredInfo.TargetMode.TargetVideoSignalInfo.ActiveSize.Cx}x{targetPreferredInfo.TargetMode.TargetVideoSignalInfo.ActiveSize.Cy}\n"; + stringToReturn += $" Target Video Signal Info Total Size: ({targetPreferredInfo.TargetMode.TargetVideoSignalInfo.TotalSize.Cx}x{targetPreferredInfo.TargetMode.TargetVideoSignalInfo.TotalSize.Cy}\n"; + stringToReturn += $" Target Video Signal Info HSync Frequency: {targetPreferredInfo.TargetMode.TargetVideoSignalInfo.HSyncFreq}\n"; + stringToReturn += $" Target Video Signal Info VSync Frequency: {targetPreferredInfo.TargetMode.TargetVideoSignalInfo.VSyncFreq}\n"; + stringToReturn += $" Target Video Signal Info Pixel Rate: {targetPreferredInfo.TargetMode.TargetVideoSignalInfo.PixelRate}\n"; + stringToReturn += $" Target Video Signal Info Scan Line Ordering: {targetPreferredInfo.TargetMode.TargetVideoSignalInfo.ScanLineOrdering}\n"; + stringToReturn += $" Target Video Signal Info Video Standard: {targetPreferredInfo.TargetMode.TargetVideoSignalInfo.VideoStandard}\n"; + stringToReturn += $"\n"; + } + else + { + SharedLogger.logger.Warn($"AMDLibrary/GetWindowsDisplayConfig: WARNING - DisplayConfigGetDeviceInfo returned WIN32STATUS {err} when trying to get the preferred target name for display #{path.TargetInfo.Id}"); + } + + // get display target base type + var targetBaseTypeInfo = new DISPLAYCONFIG_TARGET_BASE_TYPE(); + targetBaseTypeInfo.Header.Type = DISPLAYCONFIG_DEVICE_INFO_TYPE.DISPLAYCONFIG_DEVICE_INFO_GET_TARGET_BASE_TYPE; + targetBaseTypeInfo.Header.Size = (uint)Marshal.SizeOf(); + targetBaseTypeInfo.Header.AdapterId = path.TargetInfo.AdapterId; + targetBaseTypeInfo.Header.Id = path.TargetInfo.Id; + err = CCDImport.DisplayConfigGetDeviceInfo(ref targetBaseTypeInfo); + if (err == WIN32STATUS.ERROR_SUCCESS) + { + SharedLogger.logger.Trace($"AMDLibrary/GetWindowsDisplayConfig: Found Virtual Resolution is Disabled: {targetBaseTypeInfo.BaseOutputTechnology} for target {path.TargetInfo.Id}."); + + stringToReturn += $"****** Interrogating Target Base Type for Display {path.TargetInfo.Id} *******\n"; + stringToReturn += $" Base Output Technology: {targetBaseTypeInfo.BaseOutputTechnology}\n"; + stringToReturn += $"\n"; + } + else + { + SharedLogger.logger.Warn($"AMDLibrary/GetWindowsDisplayConfig: WARNING - DisplayConfigGetDeviceInfo returned WIN32STATUS {err} when trying to get the target base type for display #{path.TargetInfo.Id}"); + } + + // get display support virtual resolution + var supportVirtResInfo = new DISPLAYCONFIG_SUPPORT_VIRTUAL_RESOLUTION(); + supportVirtResInfo.Header.Type = DISPLAYCONFIG_DEVICE_INFO_TYPE.DISPLAYCONFIG_DEVICE_INFO_GET_SUPPORT_VIRTUAL_RESOLUTION; + supportVirtResInfo.Header.Size = (uint)Marshal.SizeOf(); + supportVirtResInfo.Header.AdapterId = path.TargetInfo.AdapterId; + supportVirtResInfo.Header.Id = path.TargetInfo.Id; + err = CCDImport.DisplayConfigGetDeviceInfo(ref supportVirtResInfo); + if (err == WIN32STATUS.ERROR_SUCCESS) + { + SharedLogger.logger.Trace($"AMDLibrary/GetWindowsDisplayConfig: Found Base Output Technology: {supportVirtResInfo.IsMonitorVirtualResolutionDisabled} for target {path.TargetInfo.Id}."); + stringToReturn += $"****** Interrogating Target Supporting virtual resolution for Display {path.TargetInfo.Id} *******\n"; + stringToReturn += $" Virtual Resolution is Disabled: {supportVirtResInfo.IsMonitorVirtualResolutionDisabled}\n"; + stringToReturn += $"\n"; + } + else + { + SharedLogger.logger.Warn($"AMDLibrary/GetWindowsDisplayConfig: WARNING - DisplayConfigGetDeviceInfo returned WIN32STATUS {err} when trying to find out the virtual resolution support for display #{path.TargetInfo.Id}"); + } + + //get advanced color info + var colorInfo = new DISPLAYCONFIG_GET_ADVANCED_COLOR_INFO(); + colorInfo.Header.Type = DISPLAYCONFIG_DEVICE_INFO_TYPE.DISPLAYCONFIG_DEVICE_INFO_GET_ADVANCED_COLOR_INFO; + colorInfo.Header.Size = (uint)Marshal.SizeOf(); + colorInfo.Header.AdapterId = path.TargetInfo.AdapterId; + colorInfo.Header.Id = path.TargetInfo.Id; + err = CCDImport.DisplayConfigGetDeviceInfo(ref colorInfo); + if (err == WIN32STATUS.ERROR_SUCCESS) + { + SharedLogger.logger.Trace($"AMDLibrary/GetWindowsDisplayConfig: Found Advanced Color Supported: {colorInfo.AdvancedColorSupported} for target {path.TargetInfo.Id}."); + SharedLogger.logger.Trace($"AMDLibrary/GetWindowsDisplayConfig: Found Advanced Color Enabled: {colorInfo.AdvancedColorEnabled} for target {path.TargetInfo.Id}."); + SharedLogger.logger.Trace($"AMDLibrary/GetWindowsDisplayConfig: Found Advanced Color Force Disabled: {colorInfo.AdvancedColorForceDisabled} for target {path.TargetInfo.Id}."); + SharedLogger.logger.Trace($"AMDLibrary/GetWindowsDisplayConfig: Found Bits per Color Channel: {colorInfo.BitsPerColorChannel} for target {path.TargetInfo.Id}."); + SharedLogger.logger.Trace($"AMDLibrary/GetWindowsDisplayConfig: Found Color Encoding: {colorInfo.ColorEncoding} for target {path.TargetInfo.Id}."); + SharedLogger.logger.Trace($"AMDLibrary/GetWindowsDisplayConfig: Found Wide Color Enforced: {colorInfo.WideColorEnforced} for target {path.TargetInfo.Id}."); + + stringToReturn += $"****** Interrogating Advanced Color Info for Display {path.TargetInfo.Id} *******\n"; + stringToReturn += $" Advanced Color Supported: {colorInfo.AdvancedColorSupported}\n"; + stringToReturn += $" Advanced Color Enabled: {colorInfo.AdvancedColorEnabled}\n"; + stringToReturn += $" Advanced Color Force Disabled: {colorInfo.AdvancedColorForceDisabled}\n"; + stringToReturn += $" Bits per Color Channel: {colorInfo.BitsPerColorChannel}\n"; + stringToReturn += $" Color Encoding: {colorInfo.ColorEncoding}\n"; + stringToReturn += $" Wide Color Enforced: {colorInfo.WideColorEnforced}\n"; + stringToReturn += $"\n"; + } + else + { + SharedLogger.logger.Warn($"AMDLibrary/GetWindowsDisplayConfig: WARNING - DisplayConfigGetDeviceInfo returned WIN32STATUS {err} when trying to find out the virtual resolution support for display #{path.TargetInfo.Id}"); + } + + // get SDR white levels + var whiteLevelInfo = new DISPLAYCONFIG_SDR_WHITE_LEVEL(); + whiteLevelInfo.Header.Type = DISPLAYCONFIG_DEVICE_INFO_TYPE.DISPLAYCONFIG_DEVICE_INFO_GET_SDR_WHITE_LEVEL; + whiteLevelInfo.Header.Size = (uint)Marshal.SizeOf(); + whiteLevelInfo.Header.AdapterId = path.TargetInfo.AdapterId; + whiteLevelInfo.Header.Id = path.TargetInfo.Id; + err = CCDImport.DisplayConfigGetDeviceInfo(ref whiteLevelInfo); + if (err == WIN32STATUS.ERROR_SUCCESS) + { + SharedLogger.logger.Trace($"AMDLibrary/GetWindowsDisplayConfig: Found SDR White Level: {whiteLevelInfo.SDRWhiteLevel} for target {path.TargetInfo.Id}."); + + stringToReturn += $"****** Interrogating SDR Whilte Level for Display {path.TargetInfo.Id} *******\n"; + stringToReturn += $" SDR White Level: {whiteLevelInfo.SDRWhiteLevel}\n"; + stringToReturn += $"\n"; + } + else + { + SharedLogger.logger.Warn($"AMDLibrary/GetWindowsDisplayConfig: WARNING - DisplayConfigGetDeviceInfo returned WIN32STATUS {err} when trying to find out the SDL white level for display #{path.TargetInfo.Id}"); + } + } + return stringToReturn; + } + + public bool SetActiveConfig(AMD_DISPLAY_CONFIG displayConfig) + { + + if (_initialised) + { + + ADL_STATUS ADLRet = 0; + // We want to get the current config + //AMD_DISPLAY_CONFIG currentDisplayConfig = GetAMDDisplayConfig(QDC.QDC_ALL_PATHS); + + // We want to check the AMD Eyefinity (SLS) config is valid + SharedLogger.logger.Trace($"AMDLibrary/SetActiveConfig: Testing whether the display configuration is valid"); + //ADL2_Display_SLSMapConfig_Valid(ADL_CONTEXT_HANDLE context, int iAdapterIndex, ADLSLSMap slsMap, int iNumDisplayTarget, ADLSLSTarget * lpSLSTarget, int * lpSupportedSLSLayoutImageMode, int * lpReasonForNotSupportSLS, int iOption) + foreach (var adapter in displayConfig.AdapterConfigs) + { + // set the display locations + if (adapter.IsSLSEnabled) { - - int IsActive = ADL.ADL_TRUE; // We only want to search for active adapters - - SharedLogger.logger.Trace($"AMDLibrary/GetActiveProfile: Successfully run ADL2_Adapter_AdapterInfoX4_Get to find information about all known AMD adapters."); - - ADLAdapterInfoX2 oneAdapter = new ADLAdapterInfoX2(); - // Go through each adapter - for (int adapterLoop = 0; adapterLoop < numAdapters; adapterLoop++) + // Turn the SLS based display map on + ADLRet = ADLImport.ADL2_Display_SLSMapConfig_SetState(_adlContextHandle, adapter.AdapterIndex, adapter.SLSMapIndex, ADLImport.ADL_TRUE); + if (ADLRet == ADL_STATUS.ADL_OK) { - oneAdapter = (ADLAdapterInfoX2)Marshal.PtrToStructure(new IntPtr(AdapterBuffer.ToInt64() + (adapterLoop * Marshal.SizeOf(oneAdapter))), oneAdapter.GetType()); + SharedLogger.logger.Trace($"AMDLibrary/SetActiveConfig: ADL2_Display_SLSMapConfig_SetState successfully set the SLSMAP with index {adapter.SLSMapIndex} to TRUE for adapter {adapter.AdapterIndex}."); + } + else + { + SharedLogger.logger.Error($"AMDLibrary/SetActiveConfig: ERROR - ADL2_Display_SLSMapConfig_SetState returned ADL_STATUS {ADLRet} when trying to set the SLSMAP with index {adapter.SLSMapIndex} to TRUE for adapter {adapter.AdapterIndex}."); + throw new AMDLibraryException($"ADL2_Display_SLSMapConfig_SetState returned ADL_STATUS {ADLRet} when trying to set the SLSMAP with index {adapter.SLSMapIndex} to TRUE for adapter {adapter.AdapterIndex}"); + } + /* - if (oneAdapter.Exist != 1) - { - SharedLogger.logger.Trace($"AMDLibrary/GetActiveProfile: AMD Adapter #{oneAdapter.AdapterIndex.ToString()} doesn't exist at present so skipping detection for this adapter."); - continue; - } - - if (oneAdapter.Present != 1) - { - SharedLogger.logger.Trace($"AMDLibrary/GetActiveProfile: AMD Adapter #{oneAdapter.AdapterIndex.ToString()} isn't enabled at present so skipping detection for this adapter."); - continue; - } - - // Check if the adapter is active - if (ADL.ADL2_Adapter_Active_Get != null) - ADLRet = ADL.ADL2_Adapter_Active_Get(_adlContextHandle, oneAdapter.AdapterIndex, ref IsActive); - - if (ADLRet == ADL.ADL_OK) - { - // Only continue if the adapter is enabled - if (IsActive != ADL.ADL_TRUE) - { - SharedLogger.logger.Trace($"AMDLibrary/GetActiveProfile: AMD Adapter #{oneAdapter.AdapterIndex.ToString()} isn't active ({oneAdapter.AdapterName})."); - continue; - } - - // Only continue if the adapter index is > 0 - if (oneAdapter.AdapterIndex < 0) - { - SharedLogger.logger.Trace($"AMDLibrary/GenerateAllAGetActiveProfilevailableDisplayIdentifiers: AMD Adapter has an adapter index of {oneAdapter.AdapterIndex.ToString()} which indicates it is not a real adapter."); - continue; - } - - SharedLogger.logger.Trace($"AMDLibrary/GetActiveProfile: AMD Adapter #{oneAdapter.AdapterIndex.ToString()} is active! ({oneAdapter.AdapterName})."); - - // Store the Adapter information for later - AMDAdapter adapterToCreate = new AMDAdapter(); - adapterToCreate.AdapterInfoX2 = oneAdapter; - adapterToCreate.Displays = new List(); - - - SharedLogger.logger.Trace($"AMDLibrary/GetActiveProfile: ### Adapter Info for Adapter #{oneAdapter.AdapterIndex} ###"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveProfile: Adapter AdapterIndex = {oneAdapter.AdapterIndex}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveProfile: Adapter AdapterName = {oneAdapter.AdapterName}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveProfile: Adapter BusNumber = {oneAdapter.BusNumber}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveProfile: Adapter DeviceNumber = {oneAdapter.DeviceNumber}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveProfile: Adapter DisplayName = {oneAdapter.DisplayName}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveProfile: Adapter DriverPath = {oneAdapter.DriverPath}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveProfile: Adapter DriverPathExt = {oneAdapter.DriverPathExt}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveProfile: Adapter Exist = {oneAdapter.Exist}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveProfile: Adapter FunctionNumber = {oneAdapter.FunctionNumber}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveProfile: Adapter InfoMask = {oneAdapter.InfoMask}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveProfile: Adapter InfoValue = {oneAdapter.InfoValue}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveProfile: Adapter OSDisplayIndex = {oneAdapter.OSDisplayIndex}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveProfile: Adapter PNPString = {oneAdapter.PNPString}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveProfile: Adapter Present = {oneAdapter.Present}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveProfile: Adapter Size = {oneAdapter.Size}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveProfile: Adapter UDID = {oneAdapter.UDID}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveProfile: Adapter VendorID = {oneAdapter.VendorID}"); - - // Get the Adapter Capabilities - ADLAdapterCapsX2 AdapterCapabilities = new ADLAdapterCapsX2(); - if (ADL.ADL2_AdapterX2_Caps != null) - { - ADLRet = ADL.ADL2_AdapterX2_Caps(_adlContextHandle, oneAdapter.AdapterIndex, out AdapterCapabilities); - } - - SharedLogger.logger.Trace($"AMDLibrary/GetActiveProfile: ### Adapter Capabilities for Adapter #{oneAdapter.AdapterIndex} ###"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveProfile: Adapter ID = {AdapterCapabilities.AdapterID}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveProfile: Adapter Capabilities Mask = {AdapterCapabilities.CapsMask}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveProfile: Adapter Capabilities Value = {AdapterCapabilities.CapsValue}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveProfile: Adapter Num of Connectors = {AdapterCapabilities.NumConnectors}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveProfile: Adapter Num of Controllers = {AdapterCapabilities.NumControllers}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveProfile: Adapter Num of Displays = {AdapterCapabilities.NumDisplays}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveProfile: Adapter Num of GL Sync Connectors = {AdapterCapabilities.NumOfGLSyncConnectors}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveProfile: Adapter Num of Overlays = {AdapterCapabilities.NumOverlays}"); - - // Store the Adapters Info for later - profileToCreate.Adapters.Add(adapterToCreate); - - if (ADL.ADL2_Display_DisplayInfo_Get != null) - { - IntPtr DisplayBuffer = IntPtr.Zero; - int numDisplays = 0; - // Force the display detection and get the Display Info. Use 0 as last parameter to NOT force detection - ADLRet = ADL.ADL2_Display_DisplayInfo_Get(_adlContextHandle, oneAdapter.AdapterIndex, ref numDisplays, out DisplayBuffer, 1); - if (ADLRet == ADL.ADL_OK) - { - - try - { - - for (int displayLoop = 0; displayLoop < numDisplays; displayLoop++) - { - ADLDisplayInfo oneDisplayInfo = new ADLDisplayInfo(); - oneDisplayInfo = (ADLDisplayInfo)Marshal.PtrToStructure(new IntPtr(DisplayBuffer.ToInt64() + (displayLoop * Marshal.SizeOf(oneDisplayInfo))), oneDisplayInfo.GetType()); - - // Is the display mapped to this adapter? If not we skip it! - if (oneDisplayInfo.DisplayID.DisplayLogicalAdapterIndex != oneAdapter.AdapterIndex) + foreach (var slsMap in adapter.SLSMap) { - SharedLogger.logger.Trace($"AMDLibrary/GetActiveProfile: AMD Adapter #{oneAdapter.AdapterIndex.ToString()} ({oneAdapter.AdapterName}) AdapterID display ID#{oneDisplayInfo.DisplayID.DisplayLogicalIndex} is not a real display as its DisplayID.DisplayLogicalAdapterIndex is -1"); - continue; - } - - // Convert the displayInfoValue to something usable using a library function I made - ConvertedDisplayInfoValue displayInfoValue = ADL.ConvertDisplayInfoValue(oneDisplayInfo.DisplayInfoValue); - - if (!displayInfoValue.DISPLAYCONNECTED) - { - SharedLogger.logger.Trace($"AMDLibrary/GetActiveProfile: AMD Adapter #{oneAdapter.AdapterIndex.ToString()} ({oneAdapter.AdapterName}) AdapterID display ID#{oneDisplayInfo.DisplayID.DisplayLogicalIndex} is not connected"); - continue; - } - - // Skip connected but non-mapped displays (not mapped in windows) - we only want displays currently visible in the OS because they're in use - if (!displayInfoValue.DISPLAYMAPPED) - { - SharedLogger.logger.Trace($"AMDLibrary/GetActiveProfile: AMD Adapter #{oneAdapter.AdapterIndex.ToString()} ({oneAdapter.AdapterName}) AdapterID display ID#{oneDisplayInfo.DisplayID.DisplayLogicalIndex} is not mapped in Windows OS"); - continue; - } - - SharedLogger.logger.Trace($"AMDLibrary/GetActiveProfile: AMD Adapter #{oneAdapter.AdapterIndex.ToString()} ({oneAdapter.AdapterName}) AdapterID display ID#{oneDisplayInfo.DisplayID.DisplayLogicalIndex} is connected and mapped in Windows OS"); - - ADL.ADLDisplayConnectionType displayConnector = (ADL.ADLDisplayConnectionType)oneDisplayInfo.DisplayConnector; - - // Store the Display information for later - AMDDisplay displayToCreate = new AMDDisplay(); - displayToCreate.DisplayModes = new List(); - displayToCreate.DisplayName = oneDisplayInfo.DisplayName; - displayToCreate.DisplayConnector = displayConnector.ToString("G"); - displayToCreate.IsEyefinity = false; - displayToCreate.HDRSupported = false; - displayToCreate.HDREnabled = false; - - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: ### Display Info for Display #{oneDisplayInfo.DisplayID.DisplayLogicalIndex} on Adapter #{oneAdapter.AdapterIndex} ###"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: Display Connector = {displayConnector.ToString("G")}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: Display Controller Index = {oneDisplayInfo.DisplayControllerIndex}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: Display Logical Adapter Index = {oneDisplayInfo.DisplayID.DisplayLogicalAdapterIndex}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: Display Logical Index = {oneDisplayInfo.DisplayID.DisplayLogicalIndex}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: Display Physical Adapter Index = {oneDisplayInfo.DisplayID.DisplayPhysicalAdapterIndex}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: Display Physical Index = {oneDisplayInfo.DisplayID.DisplayPhysicalIndex}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: Display Info Mask = {oneDisplayInfo.DisplayInfoMask}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: Display Info Value = {oneDisplayInfo.DisplayInfoValue}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: Display Manufacturer Name = {oneDisplayInfo.DisplayManufacturerName}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: Display Name = {oneDisplayInfo.DisplayName}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: Display Output Type = {oneDisplayInfo.DisplayOutputType}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: Display Type = {oneDisplayInfo.DisplayType}"); - - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: Display Info Value DISPLAYCONNECTED = {displayInfoValue.DISPLAYCONNECTED}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: Display Info Value DISPLAYMAPPED = {displayInfoValue.DISPLAYMAPPED}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: Display Info Value FORCIBLESUPPORTED = {displayInfoValue.FORCIBLESUPPORTED}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: Display Info Value GENLOCKSUPPORTED = {displayInfoValue.GENLOCKSUPPORTED}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: Display Info Value LDA_DISPLAY = {displayInfoValue.LDA_DISPLAY}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: Display Info Value MANNER_SUPPORTED_2HSTRETCH = {displayInfoValue.MANNER_SUPPORTED_2HSTRETCH}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: Display Info Value MANNER_SUPPORTED_2VSTRETCH = {displayInfoValue.MANNER_SUPPORTED_2VSTRETCH}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: Display Info Value MANNER_SUPPORTED_CLONE = {displayInfoValue.MANNER_SUPPORTED_CLONE}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: Display Info Value MANNER_SUPPORTED_EXTENDED = {displayInfoValue.MANNER_SUPPORTED_EXTENDED}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: Display Info Value MANNER_SUPPORTED_NSTRETCH1GPU = {displayInfoValue.MANNER_SUPPORTED_NSTRETCH1GPU}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: Display Info Value MANNER_SUPPORTED_NSTRETCHNGPU = {displayInfoValue.MANNER_SUPPORTED_NSTRETCHNGPU}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: Display Info Value MANNER_SUPPORTED_SINGLE = {displayInfoValue.MANNER_SUPPORTED_SINGLE}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: Display Info Value MODETIMING_OVERRIDESSUPPORTED = {displayInfoValue.MODETIMING_OVERRIDESSUPPORTED}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: Display Info Value MULTIVPU_SUPPORTED = {displayInfoValue.MULTIVPU_SUPPORTED}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: Display Info Value NONLOCAL = {displayInfoValue.NONLOCAL}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: Display Info Value SHOWTYPE_PROJECTOR = {displayInfoValue.SHOWTYPE_PROJECTOR}"); - - IntPtr displayModeBuffer = IntPtr.Zero; - int numModes = 0; - if (ADL.ADL2_Display_Modes_Get != null) - { - // Get the ADLModes from the Display - ADLRet = ADL.ADL2_Display_Modes_Get(_adlContextHandle, oneAdapter.AdapterIndex, oneDisplayInfo.DisplayID.DisplayPhysicalIndex, out numModes, out displayModeBuffer); - if (ADLRet == ADL.ADL_OK) + // Check the SLS config is valid + int numDisplayTargets = 0; + int supportedSLSLayoutImageMode = 0; + int reasonForNotSupportingSLS = 0; + ADL_DISPLAY_TARGET[] displayTargetArray = { new ADL_DISPLAY_TARGET() }; + IntPtr displayTargetBuffer = IntPtr.Zero; + int option = ADLImport.ADL_DISPLAY_SLSGRID_CAP_OPTION_RELATIVETO_LANDSCAPE; + ADLRet = ADLImport.ADL2_Display_SLSMapConfig_Valid(_adlContextHandle, adapter.AdapterIndex, slsMap, slsMap.NumSLSTarget, displayTargetArray, out supportedSLSLayoutImageMode, out reasonForNotSupportingSLS, option); + if (ADLRet == ADL_STATUS.ADL_OK) { - for (int displayModeLoop = 0; displayModeLoop < numModes; displayModeLoop++) + SharedLogger.logger.Trace($"AMDLibrary/GetAMDDisplayConfig: ADL2_Display_SLSMapConfig_Valid confirmed the SLS configuration is valid for AMD adapter {adapter.AdapterIndex}."); + } + else + { + SharedLogger.logger.Error($"AMDLibrary/GetAMDDisplayConfig: ERROR - ADL2_Display_SLSMapConfig_Valid returned ADL_STATUS {ADLRet} when trying to validate the SLS configuration for AMD adapter {adapter.AdapterIndex} in the computer."); + throw new AMDLibraryException($"ADL2_Display_SLSMapConfig_Valid returned ADL_STATUS {ADLRet}when trying to validate the SLS configuration for AMD adapter {adapter.AdapterIndex} in the computer"); + } + + if (numDisplayTargets > 0) + { + IntPtr currentDisplayTargetBuffer = displayTargetBuffer; + displayTargetArray = new ADL_DISPLAY_TARGET[numDisplayTargets]; + for (int i = 0; i < numDisplayTargets; i++) { - ADLMode oneDisplayMode = new ADLMode(); - oneDisplayMode = (ADLMode)Marshal.PtrToStructure(new IntPtr(displayModeBuffer.ToInt64() + (displayModeLoop * Marshal.SizeOf(oneDisplayMode))), oneDisplayMode.GetType()); - - displayToCreate.DisplayModes.Add(oneDisplayMode); - - //displayConnectionType = (ADL.ADLDisplayConnectionType)displayConfig.ConnectorType; - ConvertedDisplayModeFlags displayModeFlag = ADL.ConvertDisplayModeFlags(oneDisplayMode.ModeFlag); - ConvertedDisplayModeFlags displayModeMask = ADL.ConvertDisplayModeFlags(oneDisplayMode.ModeMask); - ConvertedDisplayModeFlags displayModeValue = ADL.ConvertDisplayModeFlags(oneDisplayMode.ModeValue); - - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: ### Display Modes for Display #{oneDisplayInfo.DisplayID.DisplayLogicalIndex} on Adapter #{oneAdapter.AdapterIndex} ###"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: DisplayMode Colour Depth = {oneDisplayMode.ColourDepth}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: DisplayMode Mode Flag = {oneDisplayMode.ModeFlag}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: DisplayMode Mode Flag ColourFormat 565 = {displayModeFlag.COLOURFORMAT_565}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: DisplayMode Mode Flag ColourFormat 8888 = {displayModeFlag.COLOURFORMAT_8888}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: DisplayMode Mode Flag ORIENTATION_SUPPORTED_000 = {displayModeFlag.ORIENTATION_SUPPORTED_000}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: DisplayMode Mode Flag ORIENTATION_SUPPORTED_090 = {displayModeFlag.ORIENTATION_SUPPORTED_090}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: DisplayMode Mode Flag ORIENTATION_SUPPORTED_180 = {displayModeFlag.ORIENTATION_SUPPORTED_180}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: DisplayMode Mode Flag ORIENTATION_SUPPORTED_270 = {displayModeFlag.ORIENTATION_SUPPORTED_270}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: DisplayMode Mode Flag REFRESHRATE_ROUNDED = {displayModeFlag.REFRESHRATE_ROUNDED}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: DisplayMode Mode Flag REFRESHRATE_ONLY = {displayModeFlag.REFRESHRATE_ONLY}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: DisplayMode Mode Mask = {oneDisplayMode.ModeMask}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: DisplayMode Mode Value = {oneDisplayMode.ModeValue}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: DisplayMode Orientation = {oneDisplayMode.Orientation}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: DisplayMode Refresh Rate = {oneDisplayMode.RefreshRate}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: DisplayMode X Position = {oneDisplayMode.XPos}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: DisplayMode X Resolution = {oneDisplayMode.XRes}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: DisplayMode Y Position = {oneDisplayMode.YPos}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: DisplayMode Y Resolution = {oneDisplayMode.YRes}"); - - - - } - } - else - { - SharedLogger.logger.Warn($"AMDLibrary/GetActiveprofile: Error running ADL2_Display_DeviceConfig_Get on Display #{oneDisplayInfo.DisplayID.DisplayLogicalIndex} on Adapter #{oneAdapter.AdapterIndex}: {ADL.ConvertADLReturnValueIntoWords(ADLRet)}"); - } - } - - ADLDDCInfo2 displayDDCInfo2 = new ADLDDCInfo2(); - displayDDCInfo2.Size = Marshal.SizeOf(displayDDCInfo2); - - if (ADL.ADL2_Display_DDCInfo2_Get != null) - { - // Get the DDC Data from the Display - ADLRet = ADL.ADL2_Display_DDCInfo2_Get(_adlContextHandle, oneAdapter.AdapterIndex, oneDisplayInfo.DisplayID.DisplayPhysicalIndex, out displayDDCInfo2); - if (ADLRet == ADL.ADL_OK) - { - - // Convert the DDCInfoFlag to something usable using a library function I made - ConvertedDDCInfoFlag DDCInfoFlag = ADL.ConvertDDCInfoFlag(displayDDCInfo2.DDCInfoFlag); - - // Convert the DDCInfoFlag to something usable using a library function I made - ConvertedSupportedHDR supportedHDR = ADL.ConvertSupportedHDR(displayDDCInfo2.SupportedHDR); - - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: ### Display DDCInfo2 for Display #{oneDisplayInfo.DisplayID.DisplayLogicalIndex} on Adapter #{oneAdapter.AdapterIndex} ###"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: Display AvgLuminanceData = {displayDDCInfo2.AvgLuminanceData}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: Display DDCInfoFlag = {displayDDCInfo2.DDCInfoFlag}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: Display DiffuseScreenReflectance = {displayDDCInfo2.DiffuseScreenReflectance}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: Display DisplayName = {displayDDCInfo2.DisplayName}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: Display FreesyncFlags = {displayDDCInfo2.FreesyncFlags}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: Display ManufacturerID = {displayDDCInfo2.ManufacturerID}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: Display MaxBacklightMaxLuminanceData = {displayDDCInfo2.MaxBacklightMaxLuminanceData}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: Display MaxBacklightMinLuminanceData = {displayDDCInfo2.MaxBacklightMinLuminanceData}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: Display MaxHResolution = {displayDDCInfo2.MaxHResolution}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: Display MaxLuminanceData = {displayDDCInfo2.MaxLuminanceData}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: Display MaxRefresh = {displayDDCInfo2.MaxRefresh}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: Display MaxVResolution = {displayDDCInfo2.MaxVResolution}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: Display MinBacklightMaxLuminanceData = {displayDDCInfo2.MinBacklightMaxLuminanceData}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: Display MinBacklightMinLuminanceData = {displayDDCInfo2.MinBacklightMinLuminanceData}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: Display MinLuminanceData = {displayDDCInfo2.MinLuminanceData}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: Display MinLuminanceNoDimmingData = {displayDDCInfo2.MinLuminanceNoDimmingData}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: Display NativeDisplayChromaticityBlueX = {displayDDCInfo2.NativeDisplayChromaticityBlueX}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: Display NativeDisplayChromaticityBlueY = {displayDDCInfo2.NativeDisplayChromaticityBlueY}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: Display NativeDisplayChromaticityGreenX = {displayDDCInfo2.NativeDisplayChromaticityGreenX}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: Display NativeDisplayChromaticityGreenY = {displayDDCInfo2.NativeDisplayChromaticityGreenY}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: Display NativeDisplayChromaticityRedX = {displayDDCInfo2.NativeDisplayChromaticityRedX}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: Display NativeDisplayChromaticityRedY = {displayDDCInfo2.NativeDisplayChromaticityRedY}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: Display NativeDisplayChromaticityWhiteX = {displayDDCInfo2.NativeDisplayChromaticityWhiteX}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: Display NativeDisplayChromaticityWhiteY = {displayDDCInfo2.NativeDisplayChromaticityWhiteY}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: Display PackedPixelSupported = {displayDDCInfo2.PackedPixelSupported}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: Display PanelPixelFormat = {displayDDCInfo2.PanelPixelFormat}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: Display ProductID = {displayDDCInfo2.ProductID}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: Display PTMCx = {displayDDCInfo2.PTMCx}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: Display PTMCy = {displayDDCInfo2.PTMCy}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: Display PTMRefreshRate = {displayDDCInfo2.PTMRefreshRate}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: Display SerialID = {displayDDCInfo2.SerialID}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: Display Size = {displayDDCInfo2.Size}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: Display SpecularScreenReflectance = {displayDDCInfo2.SpecularScreenReflectance}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: Display SupportedColorSpace = {displayDDCInfo2.SupportedColorSpace}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: Display SupportedHDR = {displayDDCInfo2.SupportedHDR}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: Display SupportedTransferFunction = {displayDDCInfo2.SupportedTransferFunction}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: Display SupportsDDC = {displayDDCInfo2.SupportsDDC}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: Display DDCInfoFlag Digital Device = {DDCInfoFlag.DIGITALDEVICE}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: Display DDCInfoFlag EDID Extension = {DDCInfoFlag.EDIDEXTENSION}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: Display DDCInfoFlag HDMI Audio Device = {DDCInfoFlag.HDMIAUDIODEVICE}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: Display DDCInfoFlag Projector Device = {DDCInfoFlag.PROJECTORDEVICE}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: Display DDCInfoFlag Supports AI = {DDCInfoFlag.SUPPORTS_AI}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: Display DDCInfoFlag Supports xvYCC601 = {DDCInfoFlag.SUPPORT_xvYCC601}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: Display DDCInfoFlag Supports xvYCC709 = {DDCInfoFlag.SUPPORT_xvYCC709}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: Display SupportedHDR Supports CEA861_3 = {supportedHDR.CEA861_3}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: Display SupportedHDR Supports DOLBYVISION = {supportedHDR.DOLBYVISION}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: Display SupportedHDR Supports FREESYNC_HDR = {supportedHDR.FREESYNC_HDR}"); - } - else - { - SharedLogger.logger.Warn($"AMDLibrary/GetActiveprofile: Error running ADL2_Display_DDCInfo2_Get on Display #{oneDisplayInfo.DisplayID.DisplayLogicalIndex} on Adapter #{oneAdapter.AdapterIndex}: {ADL.ConvertADLReturnValueIntoWords(ADLRet)}"); - } - - - // Add the things we learnt about the Display to the AMDProfile. - adapterToCreate.Displays.Add(displayToCreate); - } - - - // Add the HDR information to the profile display storage - int HDRSupported = 0; - int HDREnabled = 0; - if (ADL.ADL2_Display_HDRState_Get != null) - { - // Get the HDR State from the Display - ADLRet = ADL.ADL2_Display_HDRState_Get(_adlContextHandle, oneAdapter.AdapterIndex, oneDisplayInfo.DisplayID, out HDRSupported, out HDREnabled); - if (ADLRet == ADL.ADL_OK) - { - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: ### Display HDR State for Display #{oneDisplayInfo.DisplayID.DisplayLogicalIndex} on Adapter #{oneAdapter.AdapterIndex} ###"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: Display HDR Supported = {HDRSupported}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: Display HDR Enabled = {HDREnabled}"); - } - else - { - SharedLogger.logger.Warn($"AMDLibrary/GetActiveprofile: Error running ADL2_Display_HDRState_Get on Display #{oneDisplayInfo.DisplayID.DisplayLogicalIndex} on Adapter #{oneAdapter.AdapterIndex}: {ADL.ConvertADLReturnValueIntoWords(ADLRet)}"); - } - } - - displayToCreate.HDREnabled = HDREnabled == 0 ? false : true; - displayToCreate.HDRSupported = HDRSupported == 0 ? false : true; - } - } - catch (Exception ex) - { - SharedLogger.logger.Warn(ex, $"ProfileRepository/GetActiveprofile: Exception caused trying to access attached displays"); - continue; - } - } - else - { - SharedLogger.logger.Warn($"AMDLibrary/GetActiveprofile: Error running ADL2_Display_DisplayInfo_Get on Adapter #{oneAdapter.AdapterIndex}: {ADL.ConvertADLReturnValueIntoWords(ADLRet)}"); - } - // Release the memory for the DisplayInfo structure - if (IntPtr.Zero != DisplayBuffer) - Marshal.FreeCoTaskMem(DisplayBuffer); - } - } - else - { - SharedLogger.logger.Warn($"AMDLibrary/GetActiveprofile: Error running ADL2_Adapter_Active_Get on Adapter #{oneAdapter.AdapterIndex}: {ADL.ConvertADLReturnValueIntoWords(ADLRet)}"); - } - } - } - else - { - SharedLogger.logger.Warn($"AMDLibrary/GetActiveprofile: Error running ADL2_Adapter_AdapterInfoX4_Get on AMD Video card: {ADL.ConvertADLReturnValueIntoWords(ADLRet)}"); - } - } - // Release the memory for the AdapterInfo structure - if (IntPtr.Zero != AdapterBuffer) - { - Marshal.FreeCoTaskMem(AdapterBuffer); - } - - } - else - { - SharedLogger.logger.Warn($"AMDLibrary/GetActiveprofile: There were no AMD adapters found by AMD ADL."); - - } - - // Return the profile - return profileToCreate; - } - - public bool SetActiveProfile(AMDProfile profileDataToUse) - { - // Get the list of adapters - // Get the list of displays - - // Look for the display and see if it is used in the profile - // If it is then set the display up - // if it is not, then disable the display - - // Make the driver settign permanent - - SharedLogger.logger.Trace($"AMDLibrary/SetActiveProfile: Getting AMD active adapter count"); - - int ADLRet = ADL.ADL_ERR; - int NumberOfAdapters = 0; - List UsedDisplays = new List(); - - if (null != ADL.ADL2_Adapter_NumberOfAdapters_Get) - { - ADL.ADL2_Adapter_NumberOfAdapters_Get(_adlContextHandle, ref NumberOfAdapters); - SharedLogger.logger.Trace($"AMDLibrary/SetActiveProfile: Number Of Adapters: {NumberOfAdapters.ToString()} "); - } - - if (NumberOfAdapters > 0) - { - IntPtr AdapterBuffer = IntPtr.Zero; - if (ADL.ADL2_Adapter_AdapterInfoX4_Get != null) - { - SharedLogger.logger.Trace($"AMDLibrary/SetActiveProfile: ADL2_Adapter_AdapterInfoX4_Get DLL function exists."); - - // Get the Adapter info and put it in the AdapterBuffer - SharedLogger.logger.Trace($"AMDLibrary/SetActiveProfile: Running ADL2_Adapter_AdapterInfoX4_Get to find all known AMD adapters."); - //ADLRet = ADL.ADL2_Adapter_AdapterInfoX4_Get(_adlContextHandle, AdapterBuffer, size); - int numAdapters = 0; - ADLRet = ADL.ADL2_Adapter_AdapterInfoX4_Get(_adlContextHandle, ADL.ADL_ADAPTER_INDEX_ALL, out numAdapters, out AdapterBuffer); - if (ADLRet == ADL.ADL_OK) - { - - int IsActive = ADL.ADL_TRUE; // We only want to search for active adapters - - SharedLogger.logger.Trace($"AMDLibrary/SetActiveProfile: Successfully run ADL2_Adapter_AdapterInfoX4_Get to find information about all known AMD adapters."); - - ADLAdapterInfoX2 oneAdapter = new ADLAdapterInfoX2(); - // Go through each adapter - for (int adapterLoop = 0; adapterLoop < numAdapters; adapterLoop++) - { - oneAdapter = (ADLAdapterInfoX2)Marshal.PtrToStructure(new IntPtr(AdapterBuffer.ToInt64() + (adapterLoop * Marshal.SizeOf(oneAdapter))), oneAdapter.GetType()); - - if (oneAdapter.Exist != 1) - { - SharedLogger.logger.Trace($"AMDLibrary/SetActiveProfile: AMD Adapter #{oneAdapter.AdapterIndex.ToString()} doesn't exist at present so skipping detection for this adapter."); - continue; - } - - if (oneAdapter.Present != 1) - { - SharedLogger.logger.Trace($"AMDLibrary/SetActiveProfile: AMD Adapter #{oneAdapter.AdapterIndex.ToString()} isn't enabled at present so skipping detection for this adapter."); - continue; - } - - // Check if the adapter is active - if (ADL.ADL2_Adapter_Active_Get != null) - ADLRet = ADL.ADL2_Adapter_Active_Get(_adlContextHandle, oneAdapter.AdapterIndex, ref IsActive); - - if (ADLRet == ADL.ADL_OK) - { - // Only continue if the adapter is enabled - if (IsActive != ADL.ADL_TRUE) - { - SharedLogger.logger.Trace($"AMDLibrary/SetActiveProfile: AMD Adapter #{oneAdapter.AdapterIndex.ToString()} isn't active ({oneAdapter.AdapterName})."); - continue; - } - - // Only continue if the adapter index is > 0 - if (oneAdapter.AdapterIndex < 0) - { - SharedLogger.logger.Trace($"AMDLibrary/GenerateAllASetActiveProfilevailableDisplayIdentifiers: AMD Adapter has an adapter index of {oneAdapter.AdapterIndex.ToString()} which indicates it is not a real adapter."); - continue; - } - - SharedLogger.logger.Trace($"AMDLibrary/SetActiveProfile: AMD Adapter #{oneAdapter.AdapterIndex.ToString()} is active! ({oneAdapter.AdapterName})."); - - /*// Get the Adapter Capabilities - ADLAdapterCapsX2 AdapterCapabilities = new ADLAdapterCapsX2(); - if (ADL.ADL2_AdapterX2_Caps != null) - { - ADLRet = ADL.ADL2_AdapterX2_Caps(_adlContextHandle, oneAdapter.AdapterIndex, out AdapterCapabilities); - }*/ - - if (ADL.ADL2_Display_DisplayInfo_Get != null) - { - IntPtr DisplayBuffer = IntPtr.Zero; - int numDisplays = 0; - // Force the display detection and get the Display Info. Use 0 as last parameter to NOT force detection - ADLRet = ADL.ADL2_Display_DisplayInfo_Get(_adlContextHandle, oneAdapter.AdapterIndex, ref numDisplays, out DisplayBuffer, 1); - if (ADLRet == ADL.ADL_OK) - { - - try - { - - for (int displayLoop = 0; displayLoop < numDisplays; displayLoop++) - { - ADLDisplayInfo oneDisplayInfo = new ADLDisplayInfo(); - oneDisplayInfo = (ADLDisplayInfo)Marshal.PtrToStructure(new IntPtr(DisplayBuffer.ToInt64() + (displayLoop * Marshal.SizeOf(oneDisplayInfo))), oneDisplayInfo.GetType()); - - // Is the display mapped to this adapter? If not we skip it! - if (oneDisplayInfo.DisplayID.DisplayLogicalAdapterIndex != oneAdapter.AdapterIndex) - { - SharedLogger.logger.Trace($"AMDLibrary/SetActiveProfile: AMD Adapter #{oneAdapter.AdapterIndex.ToString()} ({oneAdapter.AdapterName}) AdapterID display ID#{oneDisplayInfo.DisplayID.DisplayLogicalIndex} is not a real display as its DisplayID.DisplayLogicalAdapterIndex is -1"); - continue; - } - - // Convert the displayInfoValue to something usable using a library function I made - ConvertedDisplayInfoValue displayInfoValue = ADL.ConvertDisplayInfoValue(oneDisplayInfo.DisplayInfoValue); - - if (!displayInfoValue.DISPLAYCONNECTED) - { - SharedLogger.logger.Trace($"AMDLibrary/SetActiveProfile: AMD Adapter #{oneAdapter.AdapterIndex.ToString()} ({oneAdapter.AdapterName}) AdapterID display ID#{oneDisplayInfo.DisplayID.DisplayLogicalIndex} is not connected"); - continue; - } - - - SharedLogger.logger.Trace($"AMDLibrary/SetActiveProfile: AMD Adapter #{oneAdapter.AdapterIndex.ToString()} ({oneAdapter.AdapterName}) AdapterID display ID#{oneDisplayInfo.DisplayID.DisplayLogicalIndex} is connected and mapped in Windows OS"); - - // At this point we have the basic information about the displays currently connected - // We need to check to see what we do in order to implement this profile - - // We may need to disable profiles - - // We may need to move windows - foreach (AMDAdapter storedAMDAdapter in profileDataToUse.Adapters) - { - if (oneAdapter.AdapterIndex == storedAMDAdapter.AdapterIndex) - { - foreach (AMDDisplay storedAMDDisplay in storedAMDAdapter.Displays) - { - if (oneAdapter.UDID == storedAMDDisplay.UDID) - { - // Then this is one that we want to change and use - - // First step is to record the fact we used this one - // This is used to figre out the displays we need to turn off later - UsedDisplays.Add(storedAMDDisplay); - - // Set the basic display configuration - //ADL.ADL2_Display_Modes_Set - IntPtr displayModeBuffer = IntPtr.Zero; - int numModes = 0; - if (ADL.ADL2_Display_Modes_Get != null) - { - // Get the ADLModes from the Display - ADLRet = ADL.ADL2_Display_Modes_Get(_adlContextHandle, oneAdapter.AdapterIndex, oneDisplayInfo.DisplayID.DisplayPhysicalIndex, out numModes, out displayModeBuffer); - if (ADLRet == ADL.ADL_OK) - { - for (int displayModeLoop = 0; displayModeLoop < numModes; displayModeLoop++) - { - ADLMode oneDisplayMode = new ADLMode(); - oneDisplayMode = (ADLMode)Marshal.PtrToStructure(new IntPtr(displayModeBuffer.ToInt64() + (displayModeLoop * Marshal.SizeOf(oneDisplayMode))), oneDisplayMode.GetType()); - - } - } - else - { - SharedLogger.logger.Warn($"AMDLibrary/GetActiveprofile: Error running ADL2_Display_DeviceConfig_Get on Display #{oneDisplayInfo.DisplayID.DisplayLogicalIndex} on Adapter #{oneAdapter.AdapterIndex}: {ADL.ConvertADLReturnValueIntoWords(ADLRet)}"); - } - } - - // Set the display color configuration - //ADL.ADL2_Display_Color_Set - - // Set the display mode timing override configuration - //ADL.ADL2_Display_ModeTimingOverride_Set - - // Validate the display map config we want to set - //ADL.ADL2_Display_DisplayMapConfig_Validate - - // Figure out which display targets need to be added or removed in the display map config - //ADL.ADL2_Display_DisplayMapConfig_PossibleAddAndRemove - - // Set the display map config - //ADL.ADL2_Display_DisplayMapConfig_Set - - // Set the HDR function if needed - if (storedAMDDisplay.HDREnabled) - { - //ADL.ADL2_Display_HDRState_Set - } - - } + // build a structure in the array slot + displayTargetArray[i] = new ADL_DISPLAY_TARGET(); + // fill the array slot structure with the data from the buffer + displayTargetArray[i] = (ADL_DISPLAY_TARGET)Marshal.PtrToStructure(currentDisplayTargetBuffer, typeof(ADL_DISPLAY_TARGET)); + // destroy the bit of memory we no longer need + Marshal.DestroyStructure(currentDisplayTargetBuffer, typeof(ADL_DISPLAY_TARGET)); + // advance the buffer forwards to the next object + currentDisplayTargetBuffer = (IntPtr)((long)currentDisplayTargetBuffer + Marshal.SizeOf(displayTargetArray[i])); } + // Free the memory used by the buffer + Marshal.FreeCoTaskMem(displayTargetBuffer); } - } - + }*/ - + } + /*else + { + *//*// Do the non-SLS based display setup + AMD_ADAPTER_CONFIG amdAdapterConfig = adapter; + //int numPossibleMapResult = 0; + //IntPtr possibleMapResultBuffer = IntPtr.Zero; + ADLRet = ADLImport.ADL2_Display_DisplayMapConfig_Set(_adlContextHandle, amdAdapterConfig.AdapterIndex, amdAdapterConfig.DisplayMaps.Length, amdAdapterConfig.DisplayMaps, amdAdapterConfig.DisplayTargets.Length, amdAdapterConfig.DisplayTargets); + if (ADLRet == ADL_STATUS.ADL_OK) + { + SharedLogger.logger.Trace($"AMDLibrary/GetAMDDisplayConfig: ADL2_Display_DisplayMapConfig_Set returned information about all displaytargets connected to AMD adapter {amdAdapterConfig.AdapterIndex}."); + } + else + { + SharedLogger.logger.Error($"AMDLibrary/GetAMDDisplayConfig: ERROR - ADL2_Display_DisplayMapConfig_Get returned ADL_STATUS {ADLRet} when trying to get the display target info from AMD adapter {amdAdapterConfig.AdapterIndex} in the computer."); + throw new AMDLibraryException($"ADL2_Display_DisplayMapConfig_Get returned ADL_STATUS {ADLRet} when trying to get the display target info from AMD adapter {amdAdapterConfig.AdapterIndex} in the computer"); + }*//* + }*/ + else + { + // Turn the SLS based display map off + ADLRet = ADLImport.ADL2_Display_SLSMapConfig_SetState(_adlContextHandle, adapter.AdapterIndex, adapter.SLSMapIndex, ADLImport.ADL_FALSE); + if (ADLRet == ADL_STATUS.ADL_OK) + { + SharedLogger.logger.Trace($"AMDLibrary/SetActiveConfig: ADL2_Display_SLSMapConfig_SetState successfully set the SLSMAP with index {adapter.SLSMapIndex} to FALSE for adapter {adapter.AdapterIndex}."); + } + else + { + SharedLogger.logger.Error($"AMDLibrary/SetActiveConfig: ERROR - ADL2_Display_SLSMapConfig_SetState returned ADL_STATUS {ADLRet} when trying to set the SLSMAP with index {adapter.SLSMapIndex} to FALSE for adapter {adapter.AdapterIndex}."); + throw new AMDLibraryException($"ADL2_Display_SLSMapConfig_SetState returned ADL_STATUS {ADLRet} when trying to set the SLSMAP with index {adapter.SLSMapIndex} to FALSE for adapter {adapter.AdapterIndex}"); + } + } - ADLDDCInfo2 displayDDCInfo2 = new ADLDDCInfo2(); - displayDDCInfo2.Size = Marshal.SizeOf(displayDDCInfo2); + } - if (ADL.ADL2_Display_DDCInfo2_Get != null) - { - // Get the DDC Data from the Display - ADLRet = ADL.ADL2_Display_DDCInfo2_Get(_adlContextHandle, oneAdapter.AdapterIndex, oneDisplayInfo.DisplayID.DisplayPhysicalIndex, out displayDDCInfo2); - if (ADLRet == ADL.ADL_OK) - { + // We want to set the AMD HDR settings - // Convert the DDCInfoFlag to something usable using a library function I made - ConvertedDDCInfoFlag DDCInfoFlag = ADL.ConvertDDCInfoFlag(displayDDCInfo2.DDCInfoFlag); - - // Convert the DDCInfoFlag to something usable using a library function I made - ConvertedSupportedHDR supportedHDR = ADL.ConvertSupportedHDR(displayDDCInfo2.SupportedHDR); - - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: ### Display DDCInfo2 for Display #{oneDisplayInfo.DisplayID.DisplayLogicalIndex} on Adapter #{oneAdapter.AdapterIndex} ###"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: Display AvgLuminanceData = {displayDDCInfo2.AvgLuminanceData}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: Display DDCInfoFlag = {displayDDCInfo2.DDCInfoFlag}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: Display DiffuseScreenReflectance = {displayDDCInfo2.DiffuseScreenReflectance}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: Display DisplayName = {displayDDCInfo2.DisplayName}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: Display FreesyncFlags = {displayDDCInfo2.FreesyncFlags}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: Display ManufacturerID = {displayDDCInfo2.ManufacturerID}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: Display MaxBacklightMaxLuminanceData = {displayDDCInfo2.MaxBacklightMaxLuminanceData}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: Display MaxBacklightMinLuminanceData = {displayDDCInfo2.MaxBacklightMinLuminanceData}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: Display MaxHResolution = {displayDDCInfo2.MaxHResolution}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: Display MaxLuminanceData = {displayDDCInfo2.MaxLuminanceData}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: Display MaxRefresh = {displayDDCInfo2.MaxRefresh}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: Display MaxVResolution = {displayDDCInfo2.MaxVResolution}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: Display MinBacklightMaxLuminanceData = {displayDDCInfo2.MinBacklightMaxLuminanceData}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: Display MinBacklightMinLuminanceData = {displayDDCInfo2.MinBacklightMinLuminanceData}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: Display MinLuminanceData = {displayDDCInfo2.MinLuminanceData}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: Display MinLuminanceNoDimmingData = {displayDDCInfo2.MinLuminanceNoDimmingData}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: Display NativeDisplayChromaticityBlueX = {displayDDCInfo2.NativeDisplayChromaticityBlueX}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: Display NativeDisplayChromaticityBlueY = {displayDDCInfo2.NativeDisplayChromaticityBlueY}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: Display NativeDisplayChromaticityGreenX = {displayDDCInfo2.NativeDisplayChromaticityGreenX}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: Display NativeDisplayChromaticityGreenY = {displayDDCInfo2.NativeDisplayChromaticityGreenY}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: Display NativeDisplayChromaticityRedX = {displayDDCInfo2.NativeDisplayChromaticityRedX}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: Display NativeDisplayChromaticityRedY = {displayDDCInfo2.NativeDisplayChromaticityRedY}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: Display NativeDisplayChromaticityWhiteX = {displayDDCInfo2.NativeDisplayChromaticityWhiteX}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: Display NativeDisplayChromaticityWhiteY = {displayDDCInfo2.NativeDisplayChromaticityWhiteY}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: Display PackedPixelSupported = {displayDDCInfo2.PackedPixelSupported}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: Display PanelPixelFormat = {displayDDCInfo2.PanelPixelFormat}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: Display ProductID = {displayDDCInfo2.ProductID}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: Display PTMCx = {displayDDCInfo2.PTMCx}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: Display PTMCy = {displayDDCInfo2.PTMCy}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: Display PTMRefreshRate = {displayDDCInfo2.PTMRefreshRate}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: Display SerialID = {displayDDCInfo2.SerialID}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: Display Size = {displayDDCInfo2.Size}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: Display SpecularScreenReflectance = {displayDDCInfo2.SpecularScreenReflectance}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: Display SupportedColorSpace = {displayDDCInfo2.SupportedColorSpace}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: Display SupportedHDR = {displayDDCInfo2.SupportedHDR}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: Display SupportedTransferFunction = {displayDDCInfo2.SupportedTransferFunction}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: Display SupportsDDC = {displayDDCInfo2.SupportsDDC}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: Display DDCInfoFlag Digital Device = {DDCInfoFlag.DIGITALDEVICE}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: Display DDCInfoFlag EDID Extension = {DDCInfoFlag.EDIDEXTENSION}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: Display DDCInfoFlag HDMI Audio Device = {DDCInfoFlag.HDMIAUDIODEVICE}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: Display DDCInfoFlag Projector Device = {DDCInfoFlag.PROJECTORDEVICE}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: Display DDCInfoFlag Supports AI = {DDCInfoFlag.SUPPORTS_AI}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: Display DDCInfoFlag Supports xvYCC601 = {DDCInfoFlag.SUPPORT_xvYCC601}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: Display DDCInfoFlag Supports xvYCC709 = {DDCInfoFlag.SUPPORT_xvYCC709}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: Display SupportedHDR Supports CEA861_3 = {supportedHDR.CEA861_3}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: Display SupportedHDR Supports DOLBYVISION = {supportedHDR.DOLBYVISION}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: Display SupportedHDR Supports FREESYNC_HDR = {supportedHDR.FREESYNC_HDR}"); - } - else - { - SharedLogger.logger.Warn($"AMDLibrary/GetActiveprofile: Error running ADL2_Display_DDCInfo2_Get on Display #{oneDisplayInfo.DisplayID.DisplayLogicalIndex} on Adapter #{oneAdapter.AdapterIndex}: {ADL.ConvertADLReturnValueIntoWords(ADLRet)}"); - } + // We want to apply the Windows CCD layout info and HDR + } + else + { + SharedLogger.logger.Error($"AMDLibrary/SetActiveConfig: ERROR - Tried to run SetActiveConfig but the AMD ADL library isn't initialised!"); + throw new AMDLibraryException($"Tried to run SetActiveConfig but the AMD ADL library isn't initialised!"); + } - } + /* + // Get the all possible windows display configs + SharedLogger.logger.Trace($"AMDLibrary/SetActiveConfig: Generating a list of all the current display configs"); + WINDOWS_DISPLAY_CONFIG allWindowsDisplayConfig = GetWindowsDisplayConfig(QDC.QDC_ALL_PATHS); + // Now we go through the Paths to update the LUIDs as per Soroush's suggestion + SharedLogger.logger.Trace($"AMDLibrary/SetActiveConfig: Patching the adapter IDs to make the saved config valid"); + PatchAdapterIDs(ref displayConfig, allWindowsDisplayConfig.displayAdapters); - // Add the HDR information to the profile display storage - int HDRSupported = 0; - int HDREnabled = 0; - if (ADL.ADL2_Display_HDRState_Get != null) - { - // Get the HDR State from the Display - ADLRet = ADL.ADL2_Display_HDRState_Get(_adlContextHandle, oneAdapter.AdapterIndex, oneDisplayInfo.DisplayID, out HDRSupported, out HDREnabled); - if (ADLRet == ADL.ADL_OK) - { - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: ### Display HDR State for Display #{oneDisplayInfo.DisplayID.DisplayLogicalIndex} on Adapter #{oneAdapter.AdapterIndex} ###"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: Display HDR Supported = {HDRSupported}"); - SharedLogger.logger.Trace($"AMDLibrary/GetActiveprofile: Display HDR Enabled = {HDREnabled}"); - } - else - { - SharedLogger.logger.Warn($"AMDLibrary/GetActiveprofile: Error running ADL2_Display_HDRState_Get on Display #{oneDisplayInfo.DisplayID.DisplayLogicalIndex} on Adapter #{oneAdapter.AdapterIndex}: {ADL.ConvertADLReturnValueIntoWords(ADLRet)}"); - } - } + SharedLogger.logger.Trace($"AMDLibrary/SetActiveConfig: Testing whether the display configuration is valid"); + // Test whether a specified display configuration is supported on the computer + uint myPathsCount = (uint)displayConfig.displayConfigPaths.Length; + uint myModesCount = (uint)displayConfig.displayConfigModes.Length; + WIN32STATUS err = CCDImport.SetDisplayConfig(myPathsCount, displayConfig.displayConfigPaths, myModesCount, displayConfig.displayConfigModes, SDC.DISPLAYMAGICIAN_VALIDATE); + if (err == WIN32STATUS.ERROR_SUCCESS) + { + SharedLogger.logger.Trace($"AMDLibrary/SetActiveConfig: Successfully validated that the display configuration supplied would work!"); + } + else + { + SharedLogger.logger.Error($"AMDLibrary/SetActiveConfig: ERROR - SetDisplayConfig couldn't validate the display configuration supplied. This display configuration wouldn't work."); + return false; + } - } - } - catch (Exception ex) - { - SharedLogger.logger.Warn(ex, $"ProfileRepository/GetActiveprofile: Exception caused trying to access attached displays"); - continue; - } + SharedLogger.logger.Trace($"AMDLibrary/SetActiveConfig: Yay! The display configuration is valid! Attempting to set the Display Config now"); + // Now set the specified display configuration for this computer + err = CCDImport.SetDisplayConfig(myPathsCount, displayConfig.displayConfigPaths, myModesCount, displayConfig.displayConfigModes, SDC.DISPLAYMAGICIAN_SET); + if (err == WIN32STATUS.ERROR_SUCCESS) + { + SharedLogger.logger.Trace($"AMDLibrary/SetActiveConfig: Successfully set the display configuration to the settings supplied!"); + } + else + { + SharedLogger.logger.Error($"AMDLibrary/SetActiveConfig: ERROR - SetDisplayConfig couldn't set the display configuration using the settings supplied. Something is wrong."); + throw new AMDLibraryException($"SetDisplayConfig couldn't set the display configuration using the settings supplied. Something is wrong."); + } + + SharedLogger.logger.Trace($"AMDLibrary/SetActiveConfig: SUCCESS! The display configuration has been successfully applied"); + + foreach (ADVANCED_HDR_INFO_PER_PATH myHDRstate in displayConfig.displayHDRStates) + { + SharedLogger.logger.Trace($"Trying to get information whether HDR color is in use now on Display {myHDRstate.Id}."); + // Get advanced HDR info + var colorInfo = new DISPLAYCONFIG_GET_ADVANCED_COLOR_INFO(); + colorInfo.Header.Type = DISPLAYCONFIG_DEVICE_INFO_TYPE.DISPLAYCONFIG_DEVICE_INFO_GET_ADVANCED_COLOR_INFO; + colorInfo.Header.Size = (uint)Marshal.SizeOf(); + colorInfo.Header.AdapterId = myHDRstate.AdapterId; + colorInfo.Header.Id = myHDRstate.Id; + err = CCDImport.DisplayConfigGetDeviceInfo(ref colorInfo); + if (err == WIN32STATUS.ERROR_SUCCESS) + { + SharedLogger.logger.Trace($"AMDLibrary/SetActiveConfig: Advanced Color Info gathered from Display {myHDRstate.Id}"); + + if (myHDRstate.AdvancedColorInfo.AdvancedColorSupported && colorInfo.AdvancedColorEnabled != myHDRstate.AdvancedColorInfo.AdvancedColorEnabled) + { + SharedLogger.logger.Trace($"HDR is available for use on Display {myHDRstate.Id}, and we want it set to {myHDRstate.AdvancedColorInfo.AdvancedColorEnabled} but is currently {colorInfo.AdvancedColorEnabled}."); + + var setColorState = new DISPLAYCONFIG_SET_ADVANCED_COLOR_STATE(); + setColorState.Header.Type = DISPLAYCONFIG_DEVICE_INFO_TYPE.DISPLAYCONFIG_DEVICE_INFO_SET_ADVANCED_COLOR_STATE; + setColorState.Header.Size = (uint)Marshal.SizeOf(); + setColorState.Header.AdapterId = myHDRstate.AdapterId; + setColorState.Header.Id = myHDRstate.Id; + setColorState.EnableAdvancedColor = myHDRstate.AdvancedColorInfo.AdvancedColorEnabled; + err = CCDImport.DisplayConfigSetDeviceInfo(ref setColorState); + if (err == WIN32STATUS.ERROR_SUCCESS) + { + SharedLogger.logger.Trace($"AMDLibrary/SetActiveConfig: SUCCESS! Set HDR successfully to {myHDRstate.AdvancedColorInfo.AdvancedColorEnabled} on Display {myHDRstate.Id}"); } else { - SharedLogger.logger.Warn($"AMDLibrary/GetActiveprofile: Error running ADL2_Display_DisplayInfo_Get on Adapter #{oneAdapter.AdapterIndex}: {ADL.ConvertADLReturnValueIntoWords(ADLRet)}"); + SharedLogger.logger.Error($"AMDLibrary/SetActiveConfig: ERROR - DisplayConfigGetDeviceInfo returned WIN32STATUS {err} when trying to set the HDR settings for display #{myHDRstate.Id}"); + return false; } - // Release the memory for the DisplayInfo structure - if (IntPtr.Zero != DisplayBuffer) - Marshal.FreeCoTaskMem(DisplayBuffer); + } + else + { + SharedLogger.logger.Trace($"AMDLibrary/SetActiveConfig: Skipping setting HDR on Display {myHDRstate.Id} as it does not support HDR"); } } else { - SharedLogger.logger.Warn($"AMDLibrary/GetActiveprofile: Error running ADL2_Adapter_Active_Get on Adapter #{oneAdapter.AdapterIndex}: {ADL.ConvertADLReturnValueIntoWords(ADLRet)}"); + SharedLogger.logger.Warn($"AMDLibrary/GetWindowsDisplayConfig: WARNING - DisplayConfigGetDeviceInfo returned WIN32STATUS {err} when trying to find out if HDR is supported for display #{myHDRstate.Id}"); } - } - } - else - { - SharedLogger.logger.Warn($"AMDLibrary/GetActiveprofile: Error running ADL2_Adapter_AdapterInfoX4_Get on AMD Video card: {ADL.ConvertADLReturnValueIntoWords(ADLRet)}"); - } - } - // Release the memory for the AdapterInfo structure - if (IntPtr.Zero != AdapterBuffer) - { - Marshal.FreeCoTaskMem(AdapterBuffer); - } + }*/ + return true; + } + + public bool IsActiveConfig(AMD_DISPLAY_CONFIG displayConfig) + { + // Get the current windows display configs to compare to the one we loaded + bool allDisplays = false; + AMD_DISPLAY_CONFIG currentWindowsDisplayConfig = GetAMDDisplayConfig(allDisplays); + + // Check whether the display config is in use now + SharedLogger.logger.Trace($"AMDLibrary/IsActiveConfig: Checking whether the display configuration is already being used."); + if (displayConfig.Equals(currentWindowsDisplayConfig)) + { + SharedLogger.logger.Trace($"AMDLibrary/IsActiveConfig: The display configuration is already being used (supplied displayConfig Equals currentWindowsDisplayConfig"); + return true; } else { - SharedLogger.logger.Warn($"AMDLibrary/GetActiveprofile: There were no AMD adapters found by AMD ADL."); + SharedLogger.logger.Trace($"AMDLibrary/IsActiveConfig: The display configuration is NOT currently in use (supplied displayConfig Equals currentWindowsDisplayConfig"); return false; } + } + public bool IsPossibleConfig(AMD_DISPLAY_CONFIG displayConfig) + { + /*// Get the all possible windows display configs + AMD_DISPLAY_CONFIG allWindowsDisplayConfig = GetAMDDisplayConfig(QDC.QDC_ALL_PATHS); + SharedLogger.logger.Trace("AMDLibrary/PatchAdapterIDs: Going through the list of adapters we stored in the config to make sure they still exist"); + // Firstly check that the Adapter Names are still currently available (i.e. the adapter hasn't been replaced). + foreach (string savedAdapterName in displayConfig.displayAdapters.Values) + { + // If there is even one of the saved adapters that has changed, then it's no longer possible + // to use this display config! + if (!allWindowsDisplayConfig.displayAdapters.Values.Contains(savedAdapterName)) + { + SharedLogger.logger.Error($"AMDLibrary/PatchAdapterIDs: ERROR - Saved adapter {savedAdapterName} is not available right now! This display configuration won't work!"); + return false; + } + } + SharedLogger.logger.Trace($"AMDLibrary/PatchAdapterIDs: All teh adapters that the display configuration uses are still avilable to use now!"); + + // Now we go through the Paths to update the LUIDs as per Soroush's suggestion + SharedLogger.logger.Trace($"AMDLibrary/IsPossibleConfig: Attemptong to patch the saved display configuration's adapter IDs so that it will still work (these change at each boot)"); + PatchAdapterIDs(ref displayConfig, allWindowsDisplayConfig.displayAdapters); + + SharedLogger.logger.Trace($"AMDLibrary/IsPossibleConfig: Testing whether the display configuration is valid "); + // Test whether a specified display configuration is supported on the computer + uint myPathsCount = (uint)displayConfig.displayConfigPaths.Length; + uint myModesCount = (uint)displayConfig.displayConfigModes.Length; + WIN32STATUS err = CCDImport.SetDisplayConfig(myPathsCount, displayConfig.displayConfigPaths, myModesCount, displayConfig.displayConfigModes, SDC.DISPLAYMAGICIAN_VALIDATE); + if (err == WIN32STATUS.ERROR_SUCCESS) + { + SharedLogger.logger.Trace($"AMDLibrary/IsPossibleConfig: SetDisplayConfig validated that the display configuration is valid and can be used!"); + return true; + } + else + { + SharedLogger.logger.Trace($"AMDLibrary/IsPossibleConfig: SetDisplayConfig confirmed that the display configuration is invalid and cannot be used!"); + return false; + }*/ return true; } - /*public bool IsActiveProfile(AMDProfile profileToTest) + public List GetCurrentDisplayIdentifiers() { - return true; - }*/ - - public bool IsValidProfile(AMDProfile profileToTest) - { - return true; + SharedLogger.logger.Error($"AMDLibrary/GetCurrentDisplayIdentifiers: Getting the current display identifiers for the displays in use now"); + return GetSomeDisplayIdentifiers(QDC.QDC_ONLY_ACTIVE_PATHS); + } + + public List GetAllConnectedDisplayIdentifiers() + { + SharedLogger.logger.Error($"AMDLibrary/GetAllConnectedDisplayIdentifiers: Getting all the display identifiers that can possibly be used"); + return GetSomeDisplayIdentifiers(QDC.QDC_ALL_PATHS); + } + + private List GetSomeDisplayIdentifiers(QDC selector = QDC.QDC_ONLY_ACTIVE_PATHS) + { + SharedLogger.logger.Debug($"AMDLibrary/GetCurrentDisplayIdentifiers: Generating the unique Display Identifiers for the currently active configuration"); + + List displayIdentifiers = new List(); + + SharedLogger.logger.Trace($"AMDLibrary/GetCurrentDisplayIdentifiers: Testing whether the display configuration is valid (allowing tweaks)."); + // Get the size of the largest Active Paths and Modes arrays + int pathCount = 0; + int modeCount = 0; + WIN32STATUS err = CCDImport.GetDisplayConfigBufferSizes(QDC.QDC_ONLY_ACTIVE_PATHS, out pathCount, out modeCount); + if (err != WIN32STATUS.ERROR_SUCCESS) + { + SharedLogger.logger.Error($"AMDLibrary/PrintActiveConfig: ERROR - GetDisplayConfigBufferSizes returned WIN32STATUS {err} when trying to get the maximum path and mode sizes"); + throw new AMDLibraryException($"GetDisplayConfigBufferSizes returned WIN32STATUS {err} when trying to get the maximum path and mode sizes"); + } + + SharedLogger.logger.Trace($"AMDLibrary/GetSomeDisplayIdentifiers: Getting the current Display Config path and mode arrays"); + var paths = new DISPLAYCONFIG_PATH_INFO[pathCount]; + var modes = new DISPLAYCONFIG_MODE_INFO[modeCount]; + err = CCDImport.QueryDisplayConfig(QDC.QDC_ONLY_ACTIVE_PATHS, ref pathCount, paths, ref modeCount, modes, IntPtr.Zero); + if (err == WIN32STATUS.ERROR_INSUFFICIENT_BUFFER) + { + SharedLogger.logger.Warn($"AMDLibrary/GetSomeDisplayIdentifiers: The displays were modified between GetDisplayConfigBufferSizes and QueryDisplayConfig so we need to get the buffer sizes again."); + SharedLogger.logger.Trace($"AMDLibrary/GetSomeDisplayIdentifiers: Getting the size of the largest Active Paths and Modes arrays"); + // Screen changed in between GetDisplayConfigBufferSizes and QueryDisplayConfig, so we need to get buffer sizes again + // as per https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-querydisplayconfig + err = CCDImport.GetDisplayConfigBufferSizes(QDC.QDC_ONLY_ACTIVE_PATHS, out pathCount, out modeCount); + if (err != WIN32STATUS.ERROR_SUCCESS) + { + SharedLogger.logger.Error($"AMDLibrary/GetSomeDisplayIdentifiers: ERROR - GetDisplayConfigBufferSizes returned WIN32STATUS {err} when trying to get the maximum path and mode sizes again"); + throw new AMDLibraryException($"GetDisplayConfigBufferSizes returned WIN32STATUS {err} when trying to get the maximum path and mode sizes again"); + } + SharedLogger.logger.Trace($"AMDLibrary/GetSomeDisplayIdentifiers: Getting the current Display Config path and mode arrays"); + paths = new DISPLAYCONFIG_PATH_INFO[pathCount]; + modes = new DISPLAYCONFIG_MODE_INFO[modeCount]; + err = CCDImport.QueryDisplayConfig(QDC.QDC_ONLY_ACTIVE_PATHS, ref pathCount, paths, ref modeCount, modes, IntPtr.Zero); + if (err == WIN32STATUS.ERROR_INSUFFICIENT_BUFFER) + { + SharedLogger.logger.Error($"AMDLibrary/GetSomeDisplayIdentifiers: ERROR - The displays were still modified between GetDisplayConfigBufferSizes and QueryDisplayConfig, even though we tried twice. Something is wrong."); + throw new AMDLibraryException($"The displays were still modified between GetDisplayConfigBufferSizes and QueryDisplayConfig, even though we tried twice. Something is wrong."); + } + else if (err != WIN32STATUS.ERROR_SUCCESS) + { + SharedLogger.logger.Error($"AMDLibrary/GetSomeDisplayIdentifiers: ERROR - QueryDisplayConfig returned WIN32STATUS {err} when trying to query all available displays again"); + throw new AMDLibraryException($"QueryDisplayConfig returned WIN32STATUS {err} when trying to query all available displays again."); + } + } + else if (err != WIN32STATUS.ERROR_SUCCESS) + { + SharedLogger.logger.Error($"AMDLibrary/GetSomeDisplayIdentifiers: ERROR - QueryDisplayConfig returned WIN32STATUS {err} when trying to query all available displays"); + throw new AMDLibraryException($"QueryDisplayConfig returned WIN32STATUS {err} when trying to query all available displays."); + } + + foreach (var path in paths) + { + if (path.TargetInfo.TargetAvailable == false) + { + // We want to skip this one cause it's not valid + SharedLogger.logger.Trace($"AMDLibrary/GetSomeDisplayIdentifiers: Skipping path due to TargetAvailable not existing in display #{path.TargetInfo.Id}"); + continue; + } + + // get display source name + var sourceInfo = new DISPLAYCONFIG_SOURCE_DEVICE_NAME(); + sourceInfo.Header.Type = DISPLAYCONFIG_DEVICE_INFO_TYPE.DISPLAYCONFIG_DEVICE_INFO_GET_SOURCE_NAME; + sourceInfo.Header.Size = (uint)Marshal.SizeOf(); + sourceInfo.Header.AdapterId = path.SourceInfo.AdapterId; + sourceInfo.Header.Id = path.SourceInfo.Id; + err = CCDImport.DisplayConfigGetDeviceInfo(ref sourceInfo); + if (err == WIN32STATUS.ERROR_SUCCESS) + { + SharedLogger.logger.Trace($"AMDLibrary/GetSomeDisplayIdentifiers: Successfully got the source info from {path.SourceInfo.Id}."); + } + else + { + SharedLogger.logger.Warn($"AMDLibrary/GetSomeDisplayIdentifiers: WARNING - DisplayConfigGetDeviceInfo returned WIN32STATUS {err} when trying to get the target info for display #{path.SourceInfo.Id}"); + } + + // get display target name + var targetInfo = new DISPLAYCONFIG_TARGET_DEVICE_NAME(); + targetInfo.Header.Type = DISPLAYCONFIG_DEVICE_INFO_TYPE.DISPLAYCONFIG_DEVICE_INFO_GET_TARGET_NAME; + targetInfo.Header.Size = (uint)Marshal.SizeOf(); + targetInfo.Header.AdapterId = path.TargetInfo.AdapterId; + targetInfo.Header.Id = path.TargetInfo.Id; + err = CCDImport.DisplayConfigGetDeviceInfo(ref targetInfo); + if (err == WIN32STATUS.ERROR_SUCCESS) + { + SharedLogger.logger.Trace($"AMDLibrary/GetSomeDisplayIdentifiers: Successfully got the target info from {path.TargetInfo.Id}."); + } + else + { + SharedLogger.logger.Warn($"AMDLibrary/GetSomeDisplayIdentifiers: WARNING - DisplayConfigGetDeviceInfo returned WIN32STATUS {err} when trying to get the target info for display #{path.TargetInfo.Id}"); + } + + // get display adapter name + var adapterInfo = new DISPLAYCONFIG_ADAPTER_NAME(); + adapterInfo.Header.Type = DISPLAYCONFIG_DEVICE_INFO_TYPE.DISPLAYCONFIG_DEVICE_INFO_GET_ADAPTER_NAME; + adapterInfo.Header.Size = (uint)Marshal.SizeOf(); + adapterInfo.Header.AdapterId = path.TargetInfo.AdapterId; + adapterInfo.Header.Id = path.TargetInfo.Id; + err = CCDImport.DisplayConfigGetDeviceInfo(ref adapterInfo); + if (err == WIN32STATUS.ERROR_SUCCESS) + { + SharedLogger.logger.Trace($"AMDLibrary/GetSomeDisplayIdentifiers: Successfully got the display name info from {path.TargetInfo.Id}."); + } + else + { + SharedLogger.logger.Warn($"AMDLibrary/GetSomeDisplayIdentifiers: WARNING - DisplayConfigGetDeviceInfo returned WIN32STATUS {err} when trying to get the target info for display #{path.TargetInfo.Id}"); + } + + // Create an array of all the important display info we need to record + List displayInfo = new List(); + displayInfo.Add("WINAPI"); + try + { + displayInfo.Add(adapterInfo.AdapterDevicePath.ToString()); + } + catch (Exception ex) + { + SharedLogger.logger.Warn(ex, $"AMDLibrary/GetSomeDisplayIdentifiers: Exception getting Windows Display Adapter Device Path from video card. Substituting with a # instead"); + displayInfo.Add("#"); + } + try + { + displayInfo.Add(targetInfo.OutputTechnology.ToString()); + } + catch (Exception ex) + { + SharedLogger.logger.Warn(ex, $"AMDLibrary/GetSomeDisplayIdentifiers: Exception getting Windows Display Connector Instance from video card. Substituting with a # instead"); + displayInfo.Add("#"); + } + try + { + displayInfo.Add(targetInfo.EdidManufactureId.ToString()); + } + catch (Exception ex) + { + SharedLogger.logger.Warn(ex, $"AMDLibrary/GetSomeDisplayIdentifiers: Exception getting Windows Display EDID Manufacturer Code from video card. Substituting with a # instead"); + displayInfo.Add("#"); + } + try + { + displayInfo.Add(targetInfo.EdidProductCodeId.ToString()); + } + catch (Exception ex) + { + SharedLogger.logger.Warn(ex, $"AMDLibrary/GetSomeDisplayIdentifiers: Exception getting Windows Display EDID Product Code from video card. Substituting with a # instead"); + displayInfo.Add("#"); + } + try + { + displayInfo.Add(targetInfo.MonitorFriendlyDeviceName.ToString()); + } + catch (Exception ex) + { + SharedLogger.logger.Warn(ex, $"AMDLibrary/GetSomeDisplayIdentifiers: Exception getting Windows Display Target Friendly name from video card. Substituting with a # instead"); + displayInfo.Add("#"); + } + + // Create a display identifier out of it + string displayIdentifier = String.Join("|", displayInfo); + // Add it to the list of display identifiers so we can return it + // but only add it if it doesn't already exist. Otherwise we get duplicates :/ + if (!displayIdentifiers.Contains(displayIdentifier)) + { + displayIdentifiers.Add(displayIdentifier); + SharedLogger.logger.Debug($"ProfileRepository/GenerateProfileDisplayIdentifiers: DisplayIdentifier: {displayIdentifier}"); + } + + } + + // Sort the display identifiers + displayIdentifiers.Sort(); + + return displayIdentifiers; } - } -} + + [global::System.Serializable] + public class AMDLibraryException : Exception + { + public AMDLibraryException() { } + public AMDLibraryException(string message) : base(message) { } + public AMDLibraryException(string message, Exception inner) : base(message, inner) { } + protected AMDLibraryException( + System.Runtime.Serialization.SerializationInfo info, + System.Runtime.Serialization.StreamingContext context) : base(info, context) { } + } +} \ No newline at end of file diff --git a/DisplayMagicianShared/AMD/AMDProfileItem.cs b/DisplayMagicianShared/AMD/AMDProfileItem.cs index 5c6f4e3..4ef67b4 100644 --- a/DisplayMagicianShared/AMD/AMDProfileItem.cs +++ b/DisplayMagicianShared/AMD/AMDProfileItem.cs @@ -9,13 +9,13 @@ using System.Drawing; using System.Drawing.Imaging; using System.Text.RegularExpressions; using IWshRuntimeLibrary; -using ATI.ADL; +//using ATI.ADL; //using WK.Libraries.HotkeyListenerNS; namespace DisplayMagicianShared.AMD { - // Struct to be used as the AMD Profile + /*// Struct to be used as the AMD Profile [JsonObject(MemberSerialization.Fields)] public struct AMDProfile { @@ -47,7 +47,7 @@ namespace DisplayMagicianShared.AMD public bool HDREnabled; public bool IsEyefinity; - } + }*/ public class AMDProfileItem : ProfileItem, IComparable { @@ -56,7 +56,7 @@ namespace DisplayMagicianShared.AMD private Bitmap _profileBitmap, _profileShortcutBitmap; private List _profileDisplayIdentifiers = new List(); private List _screens; - private AMDProfile _profileData = new AMDProfile(); + private AMD_DISPLAY_CONFIG _displayConfig = new AMD_DISPLAY_CONFIG(); private static readonly string uuidV4Regex = @"(?im)^[{(]?[0-9A-F]{8}[-]?(?:[0-9A-F]{4}[-]?){3}[0-9A-F]{12}[)}]?$"; private string _uuid = ""; @@ -107,15 +107,15 @@ namespace DisplayMagicianShared.AMD //public Topology.Path[] Paths { get; set; } = new Topology.Path[0]; [JsonRequired] - public AMDProfile ProfileData + public AMD_DISPLAY_CONFIG DisplayConfig { get { - return _profileData; + return _displayConfig; } set { - _profileData = value; + _displayConfig = value; } } @@ -126,7 +126,7 @@ namespace DisplayMagicianShared.AMD { if (_profileDisplayIdentifiers.Count == 0) { - _profileDisplayIdentifiers = AMDLibrary.GetLibrary().GenerateProfileDisplayIdentifiers(); + _profileDisplayIdentifiers = AMDLibrary.GetLibrary().GetCurrentDisplayIdentifiers(); } return _profileDisplayIdentifiers; } @@ -213,7 +213,7 @@ namespace DisplayMagicianShared.AMD ProfileTightestBitmap is Bitmap && ProfileDisplayIdentifiers.Count > 0) { - if (ProfileData.Adapters.Count > 0) + if (DisplayConfig.AdapterConfigs.Count > 0) return true; else return false; @@ -234,7 +234,7 @@ namespace DisplayMagicianShared.AMD // Copy all our profile data over to the other profile profile.Name = Name; - profile.ProfileData = ProfileData; + profile.DisplayConfig = DisplayConfig; profile.ProfileIcon = ProfileIcon; profile.SavedProfileIconCacheFilename = SavedProfileIconCacheFilename; profile.ProfileBitmap = ProfileBitmap; @@ -249,7 +249,7 @@ namespace DisplayMagicianShared.AMD // Prepare our profile data for saving if (_profileDisplayIdentifiers.Count == 0) { - _profileDisplayIdentifiers = AMDLibrary.GetLibrary().GenerateProfileDisplayIdentifiers(); + _profileDisplayIdentifiers = AMDLibrary.GetLibrary().GetCurrentDisplayIdentifiers(); } // Return if it is valid and we should continue @@ -299,7 +299,7 @@ namespace DisplayMagicianShared.AMD if (amdLibrary.IsInstalled) { // Create the profile data from the current config - _profileData = amdLibrary.GetActiveProfile(); + _displayConfig = amdLibrary.GetActiveConfig(); // Now, since the ActiveProfile has changed, we need to regenerate screen positions _screens = GetScreenPositions(); @@ -326,9 +326,9 @@ namespace DisplayMagicianShared.AMD // Now we create the screens structure from the AMD profile information _screens = new List(); - if ( _profileData.Adapters.Count > 0) + if ( _displayConfig.AdapterConfigs.Count > 0) { - foreach ( var adapter in _profileData.Adapters) + foreach ( var adapter in _displayConfig.AdapterConfigs) { foreach (var display in adapter.Displays) { @@ -422,7 +422,8 @@ namespace DisplayMagicianShared.AMD if (this.GetType() != other.GetType()) return false; - if (ProfileData.Adapters.Count != other.ProfileData.Adapters.Count) + // If the DisplayConfig's equal each other + if (DisplayConfig.Equals(other.DisplayConfig)) return false; // Check if the profile identifiers are not the same, then return false @@ -510,7 +511,7 @@ namespace DisplayMagicianShared.AMD int hashIds = ProfileDisplayIdentifiers == null ? 0 : ProfileDisplayIdentifiers.GetHashCode(); // Get ProfileData too - int hashProfileData = ProfileData.GetHashCode(); + int hashProfileData = DisplayConfig.GetHashCode(); // Calculate the hash code for the product. return (hashIds, hashProfileData).GetHashCode(); @@ -559,10 +560,7 @@ namespace DisplayMagicianShared.AMD //Check whether any of the compared objects is null. if (x is null || y is null) return false; - - if (x.ProfileData.Adapters.Count != y.ProfileData.Adapters.Count) - return false; - + // Check if the profile identifiers are not the same, then return false int foundDICount = 0; foreach (string profileDI in x.ProfileDisplayIdentifiers) @@ -591,92 +589,8 @@ namespace DisplayMagicianShared.AMD return false; - // Check whether the profiles' properties are equal - // We need to exclude the name as the name is solely for saving to disk - // and displaying to the user. - // Two profiles are equal only when they have the same viewport data - int foundDisplayCount = 0; - int foundOtherDisplayCount = 0; - - foreach (AMDAdapter xadapter in x.ProfileData.Adapters) - { - foreach (AMDDisplay xdisplay in xadapter.Displays) - { - foreach (AMDAdapter yadapter in y.ProfileData.Adapters) - { - foreach (AMDDisplay ydisplay in yadapter.Displays) - { - if (ydisplay.Equals(xdisplay)) - { - foreach (var ydisplaymode in ydisplay.DisplayModes) - { - foreach (var xdisplaymode in xdisplay.DisplayModes) - { - if (ydisplaymode.Equals(xdisplaymode)) - { - foundDisplayCount++; - continue; - } - } - } - - } - } - } - } - } - - foreach (AMDAdapter yadapter in y.ProfileData.Adapters) - { - foreach (AMDDisplay ydisplay in yadapter.Displays) - { - foreach (AMDAdapter xadapter in x.ProfileData.Adapters) - { - foreach (AMDDisplay xdisplay in xadapter.Displays) - { - if (xdisplay.Equals(ydisplay)) - { - foreach (var xdisplaymode in xdisplay.DisplayModes) - { - foreach (var ydisplaymode in ydisplay.DisplayModes) - { - if (xdisplaymode.Equals(ydisplaymode)) - { - foundOtherDisplayCount++; - continue; - } - } - } - - } - } - } - } - } - - /*foreach (AMDAdapter yadapter in y.ProfileData.Adapters) - { - foreach (AMDDisplay ydisplay in yadapter.Displays) - { - foreach (AMDAdapter xadapter in x.ProfileData.Adapters) - { - if (xadapter.Displays.Contains(ydisplay)) - { - foundOtherDisplayCount++; - continue; - } - } - - - } - }*/ - - // If this matches then there are an additional screen or not enough screens - if (foundDisplayCount != foundOtherDisplayCount) - return false; - - // Now we need to check the location of the screens - if (!x.ProfileData.Equals(y.ProfileData)) + // Now we need to check the Display Configs themselves + if (x.DisplayConfig.Equals(y.DisplayConfig)) return false; return true; @@ -708,7 +622,7 @@ namespace DisplayMagicianShared.AMD int hashIds = profile.ProfileDisplayIdentifiers == null ? 0 : profile.ProfileDisplayIdentifiers.GetHashCode(); // Get hash code for the Paths - int hashProfileData = profile.ProfileData.GetHashCode(); + int hashProfileData = profile.DisplayConfig.GetHashCode(); //Calculate the hash code for the product. return (hashIds, hashProfileData).GetHashCode(); diff --git a/DisplayMagicianShared/DisplayMagicianShared.csproj b/DisplayMagicianShared/DisplayMagicianShared.csproj index 86e3f24..a4d8ad9 100644 --- a/DisplayMagicianShared/DisplayMagicianShared.csproj +++ b/DisplayMagicianShared/DisplayMagicianShared.csproj @@ -54,6 +54,7 @@ + @@ -64,11 +65,11 @@ - - + + - + @@ -90,8 +91,9 @@ DisplayView.cs + - + diff --git a/DisplayMagicianShared/NVIDIA/NVAPI.cs b/DisplayMagicianShared/NVIDIA/NVAPI.cs new file mode 100644 index 0000000..8aa173d --- /dev/null +++ b/DisplayMagicianShared/NVIDIA/NVAPI.cs @@ -0,0 +1,612 @@ +using System; +using System.Runtime.InteropServices; +using FARPROC = System.IntPtr; +using HMODULE = System.IntPtr; + +namespace DisplayMagicianShared.NVIDIA +{ + //public delegate IntPtr ADL_Main_Memory_Alloc_Delegate(int size); + + public enum NVAPI_STATUS : int + { + // Result Codes + NVAPI_OK = 0, //!< Success. Request is completed. + NVAPI_ERROR = -1, //!< Generic error + NVAPI_LIBRARY_NOT_FOUND = -2, //!< NVAPI support library cannot be loaded. + NVAPI_NO_IMPLEMENTATION = -3, //!< not implemented in current driver installation + NVAPI_API_NOT_INITIALIZED = -4, //!< NvAPI_Initialize has not been called (successfully) + NVAPI_INVALID_ARGUMENT = -5, //!< The argument/parameter value is not valid or NULL. + NVAPI_NVIDIA_DEVICE_NOT_FOUND = -6, //!< No NVIDIA display driver, or NVIDIA GPU driving a display, was found. + NVAPI_END_ENUMERATION = -7, //!< No more items to enumerate + NVAPI_INVALID_HANDLE = -8, //!< Invalid handle + NVAPI_INCOMPATIBLE_STRUCT_VERSION = -9, //!< An argument's structure version is not supported + NVAPI_HANDLE_INVALIDATED = -10, //!< The handle is no longer valid (likely due to GPU or display re-configuration) + NVAPI_OPENGL_CONTEXT_NOT_CURRENT = -11, //!< No NVIDIA OpenGL context is current (but needs to be) + NVAPI_INVALID_POINTER = -14, //!< An invalid pointer, usually NULL, was passed as a parameter + NVAPI_NO_GL_EXPERT = -12, //!< OpenGL Expert is not supported by the current drivers + NVAPI_INSTRUMENTATION_DISABLED = -13, //!< OpenGL Expert is supported, but driver instrumentation is currently disabled + NVAPI_NO_GL_NSIGHT = -15, //!< OpenGL does not support Nsight + + NVAPI_EXPECTED_LOGICAL_GPU_HANDLE = -100, //!< Expected a logical GPU handle for one or more parameters + NVAPI_EXPECTED_PHYSICAL_GPU_HANDLE = -101, //!< Expected a physical GPU handle for one or more parameters + NVAPI_EXPECTED_DISPLAY_HANDLE = -102, //!< Expected an NV display handle for one or more parameters + NVAPI_INVALID_COMBINATION = -103, //!< The combination of parameters is not valid. + NVAPI_NOT_SUPPORTED = -104, //!< Requested feature is not supported in the selected GPU + NVAPI_PORTID_NOT_FOUND = -105, //!< No port ID was found for the I2C transaction + NVAPI_EXPECTED_UNATTACHED_DISPLAY_HANDLE = -106, //!< Expected an unattached display handle as one of the input parameters. + NVAPI_INVALID_PERF_LEVEL = -107, //!< Invalid perf level + NVAPI_DEVICE_BUSY = -108, //!< Device is busy; request not fulfilled + NVAPI_NV_PERSIST_FILE_NOT_FOUND = -109, //!< NV persist file is not found + NVAPI_PERSIST_DATA_NOT_FOUND = -110, //!< NV persist data is not found + NVAPI_EXPECTED_TV_DISPLAY = -111, //!< Expected a TV output display + NVAPI_EXPECTED_TV_DISPLAY_ON_DCONNECTOR = -112, //!< Expected a TV output on the D Connector - HDTV_EIAJ4120. + NVAPI_NO_ACTIVE_SLI_TOPOLOGY = -113, //!< SLI is not active on this device. + NVAPI_SLI_RENDERING_MODE_NOTALLOWED = -114, //!< Setup of SLI rendering mode is not possible right now. + NVAPI_EXPECTED_DIGITAL_FLAT_PANEL = -115, //!< Expected a digital flat panel. + NVAPI_ARGUMENT_EXCEED_MAX_SIZE = -116, //!< Argument exceeds the expected size. + NVAPI_DEVICE_SWITCHING_NOT_ALLOWED = -117, //!< Inhibit is ON due to one of the flags in NV_GPU_DISPLAY_CHANGE_INHIBIT or SLI active. + NVAPI_TESTING_CLOCKS_NOT_SUPPORTED = -118, //!< Testing of clocks is not supported. + NVAPI_UNKNOWN_UNDERSCAN_CONFIG = -119, //!< The specified underscan config is from an unknown source (e.g. INF) + NVAPI_TIMEOUT_RECONFIGURING_GPU_TOPO = -120, //!< Timeout while reconfiguring GPUs + NVAPI_DATA_NOT_FOUND = -121, //!< Requested data was not found + NVAPI_EXPECTED_ANALOG_DISPLAY = -122, //!< Expected an analog display + NVAPI_NO_VIDLINK = -123, //!< No SLI video bridge is present + NVAPI_REQUIRES_REBOOT = -124, //!< NVAPI requires a reboot for the settings to take effect + NVAPI_INVALID_HYBRID_MODE = -125, //!< The function is not supported with the current Hybrid mode. + NVAPI_MIXED_TARGET_TYPES = -126, //!< The target types are not all the same + NVAPI_SYSWOW64_NOT_SUPPORTED = -127, //!< The function is not supported from 32-bit on a 64-bit system. + NVAPI_IMPLICIT_SET_GPU_TOPOLOGY_CHANGE_NOT_ALLOWED = -128, //!< There is no implicit GPU topology active. Use NVAPI_SetHybridMode to change topology. + NVAPI_REQUEST_USER_TO_CLOSE_NON_MIGRATABLE_APPS = -129, //!< Prompt the user to close all non-migratable applications. + NVAPI_OUT_OF_MEMORY = -130, //!< Could not allocate sufficient memory to complete the call. + NVAPI_WAS_STILL_DRAWING = -131, //!< The previous operation that is transferring information to or from this surface is incomplete. + NVAPI_FILE_NOT_FOUND = -132, //!< The file was not found. + NVAPI_TOO_MANY_UNIQUE_STATE_OBJECTS = -133, //!< There are too many unique instances of a particular type of state object. + NVAPI_INVALID_CALL = -134, //!< The method call is invalid. For example, a method's parameter may not be a valid pointer. + NVAPI_D3D10_1_LIBRARY_NOT_FOUND = -135, //!< d3d10_1.dll cannot be loaded. + NVAPI_FUNCTION_NOT_FOUND = -136, //!< Couldn't find the function in the loaded DLL. + NVAPI_INVALID_USER_PRIVILEGE = -137, //!< The application will require Administrator privileges to access this API. + //!< The application can be elevated to a higher permission level by selecting "Run as Administrator". + NVAPI_EXPECTED_NON_PRIMARY_DISPLAY_HANDLE = -138, //!< The handle corresponds to GDIPrimary. + NVAPI_EXPECTED_COMPUTE_GPU_HANDLE = -139, //!< Setting Physx GPU requires that the GPU is compute-capable. + NVAPI_STEREO_NOT_INITIALIZED = -140, //!< The Stereo part of NVAPI failed to initialize completely. Check if the stereo driver is installed. + NVAPI_STEREO_REGISTRY_ACCESS_FAILED = -141, //!< Access to stereo-related registry keys or values has failed. + NVAPI_STEREO_REGISTRY_PROFILE_TYPE_NOT_SUPPORTED = -142, //!< The given registry profile type is not supported. + NVAPI_STEREO_REGISTRY_VALUE_NOT_SUPPORTED = -143, //!< The given registry value is not supported. + NVAPI_STEREO_NOT_ENABLED = -144, //!< Stereo is not enabled and the function needed it to execute completely. + NVAPI_STEREO_NOT_TURNED_ON = -145, //!< Stereo is not turned on and the function needed it to execute completely. + NVAPI_STEREO_INVALID_DEVICE_INTERFACE = -146, //!< Invalid device interface. + NVAPI_STEREO_PARAMETER_OUT_OF_RANGE = -147, //!< Separation percentage or JPEG image capture quality is out of [0-100] range. + NVAPI_STEREO_FRUSTUM_ADJUST_MODE_NOT_SUPPORTED = -148, //!< The given frustum adjust mode is not supported. + NVAPI_TOPO_NOT_POSSIBLE = -149, //!< The mosaic topology is not possible given the current state of the hardware. + NVAPI_MODE_CHANGE_FAILED = -150, //!< An attempt to do a display resolution mode change has failed. + NVAPI_D3D11_LIBRARY_NOT_FOUND = -151, //!< d3d11.dll/d3d11_beta.dll cannot be loaded. + NVAPI_INVALID_ADDRESS = -152, //!< Address is outside of valid range. + NVAPI_STRING_TOO_SMALL = -153, //!< The pre-allocated string is too small to hold the result. + NVAPI_MATCHING_DEVICE_NOT_FOUND = -154, //!< The input does not match any of the available devices. + NVAPI_DRIVER_RUNNING = -155, //!< Driver is running. + NVAPI_DRIVER_NOTRUNNING = -156, //!< Driver is not running. + NVAPI_ERROR_DRIVER_RELOAD_REQUIRED = -157, //!< A driver reload is required to apply these settings. + NVAPI_SET_NOT_ALLOWED = -158, //!< Intended setting is not allowed. + NVAPI_ADVANCED_DISPLAY_TOPOLOGY_REQUIRED = -159, //!< Information can't be returned due to "advanced display topology". + NVAPI_SETTING_NOT_FOUND = -160, //!< Setting is not found. + NVAPI_SETTING_SIZE_TOO_LARGE = -161, //!< Setting size is too large. + NVAPI_TOO_MANY_SETTINGS_IN_PROFILE = -162, //!< There are too many settings for a profile. + NVAPI_PROFILE_NOT_FOUND = -163, //!< Profile is not found. + NVAPI_PROFILE_NAME_IN_USE = -164, //!< Profile name is duplicated. + NVAPI_PROFILE_NAME_EMPTY = -165, //!< Profile name is empty. + NVAPI_EXECUTABLE_NOT_FOUND = -166, //!< Application not found in the Profile. + NVAPI_EXECUTABLE_ALREADY_IN_USE = -167, //!< Application already exists in the other profile. + NVAPI_DATATYPE_MISMATCH = -168, //!< Data Type mismatch + NVAPI_PROFILE_REMOVED = -169, //!< The profile passed as parameter has been removed and is no longer valid. + NVAPI_UNREGISTERED_RESOURCE = -170, //!< An unregistered resource was passed as a parameter. + NVAPI_ID_OUT_OF_RANGE = -171, //!< The DisplayId corresponds to a display which is not within the normal outputId range. + NVAPI_DISPLAYCONFIG_VALIDATION_FAILED = -172, //!< Display topology is not valid so the driver cannot do a mode set on this configuration. + NVAPI_DPMST_CHANGED = -173, //!< Display Port Multi-Stream topology has been changed. + NVAPI_INSUFFICIENT_BUFFER = -174, //!< Input buffer is insufficient to hold the contents. + NVAPI_ACCESS_DENIED = -175, //!< No access to the caller. + NVAPI_MOSAIC_NOT_ACTIVE = -176, //!< The requested action cannot be performed without Mosaic being enabled. + NVAPI_SHARE_RESOURCE_RELOCATED = -177, //!< The surface is relocated away from video memory. + NVAPI_REQUEST_USER_TO_DISABLE_DWM = -178, //!< The user should disable DWM before calling NvAPI. + NVAPI_D3D_DEVICE_LOST = -179, //!< D3D device status is D3DERR_DEVICELOST or D3DERR_DEVICENOTRESET - the user has to reset the device. + NVAPI_INVALID_CONFIGURATION = -180, //!< The requested action cannot be performed in the current state. + NVAPI_STEREO_HANDSHAKE_NOT_DONE = -181, //!< Call failed as stereo handshake not completed. + NVAPI_EXECUTABLE_PATH_IS_AMBIGUOUS = -182, //!< The path provided was too short to determine the correct NVDRS_APPLICATION + NVAPI_DEFAULT_STEREO_PROFILE_IS_NOT_DEFINED = -183, //!< Default stereo profile is not currently defined + NVAPI_DEFAULT_STEREO_PROFILE_DOES_NOT_EXIST = -184, //!< Default stereo profile does not exist + NVAPI_CLUSTER_ALREADY_EXISTS = -185, //!< A cluster is already defined with the given configuration. + NVAPI_DPMST_DISPLAY_ID_EXPECTED = -186, //!< The input display id is not that of a multi stream enabled connector or a display device in a multi stream topology + NVAPI_INVALID_DISPLAY_ID = -187, //!< The input display id is not valid or the monitor associated to it does not support the current operation + NVAPI_STREAM_IS_OUT_OF_SYNC = -188, //!< While playing secure audio stream, stream goes out of sync + NVAPI_INCOMPATIBLE_AUDIO_DRIVER = -189, //!< Older audio driver version than required + NVAPI_VALUE_ALREADY_SET = -190, //!< Value already set, setting again not allowed. + NVAPI_TIMEOUT = -191, //!< Requested operation timed out + NVAPI_GPU_WORKSTATION_FEATURE_INCOMPLETE = -192, //!< The requested workstation feature set has incomplete driver internal allocation resources + NVAPI_STEREO_INIT_ACTIVATION_NOT_DONE = -193, //!< Call failed because InitActivation was not called. + NVAPI_SYNC_NOT_ACTIVE = -194, //!< The requested action cannot be performed without Sync being enabled. + NVAPI_SYNC_MASTER_NOT_FOUND = -195, //!< The requested action cannot be performed without Sync Master being enabled. + NVAPI_INVALID_SYNC_TOPOLOGY = -196, //!< Invalid displays passed in the NV_GSYNC_DISPLAY pointer. + NVAPI_ECID_SIGN_ALGO_UNSUPPORTED = -197, //!< The specified signing algorithm is not supported. Either an incorrect value was entered or the current installed driver/hardware does not support the input value. + NVAPI_ECID_KEY_VERIFICATION_FAILED = -198, //!< The encrypted public key verification has failed. + NVAPI_FIRMWARE_OUT_OF_DATE = -199, //!< The device's firmware is out of date. + NVAPI_FIRMWARE_REVISION_NOT_SUPPORTED = -200, //!< The device's firmware is not supported. + NVAPI_LICENSE_CALLER_AUTHENTICATION_FAILED = -201, //!< The caller is not authorized to modify the License. + NVAPI_D3D_DEVICE_NOT_REGISTERED = -202, //!< The user tried to use a deferred context without registering the device first + NVAPI_RESOURCE_NOT_ACQUIRED = -203, //!< Head or SourceId was not reserved for the VR Display before doing the Modeset. + NVAPI_TIMING_NOT_SUPPORTED = -204, //!< Provided timing is not supported. + NVAPI_HDCP_ENCRYPTION_FAILED = -205, //!< HDCP Encryption Failed for the device. Would be applicable when the device is HDCP Capable. + NVAPI_PCLK_LIMITATION_FAILED = -206, //!< Provided mode is over sink device pclk limitation. + NVAPI_NO_CONNECTOR_FOUND = -207, //!< No connector on GPU found. + NVAPI_HDCP_DISABLED = -208, //!< When a non-HDCP capable HMD is connected, we would inform user by this code. + NVAPI_API_IN_USE = -209, //!< Atleast an API is still being called + NVAPI_NVIDIA_DISPLAY_NOT_FOUND = -210, //!< No display found on Nvidia GPU(s). + NVAPI_PRIV_SEC_VIOLATION = -211, //!< Priv security violation, improper access to a secured register. + NVAPI_INCORRECT_VENDOR = -212, //!< NVAPI cannot be called by this vendor + NVAPI_DISPLAY_IN_USE = -213, //!< DirectMode Display is already in use + NVAPI_UNSUPPORTED_CONFIG_NON_HDCP_HMD = -214, //!< The Config is having Non-NVidia GPU with Non-HDCP HMD connected + NVAPI_MAX_DISPLAY_LIMIT_REACHED = -215, //!< GPU's Max Display Limit has Reached + NVAPI_INVALID_DIRECT_MODE_DISPLAY = -216, //!< DirectMode not Enabled on the Display + NVAPI_GPU_IN_DEBUG_MODE = -217, //!< GPU is in debug mode, OC is NOT allowed. + NVAPI_D3D_CONTEXT_NOT_FOUND = -218, //!< No NvAPI context was found for this D3D object + NVAPI_STEREO_VERSION_MISMATCH = -219, //!< there is version mismatch between stereo driver and dx driver + NVAPI_GPU_NOT_POWERED = -220, //!< GPU is not powered and so the request cannot be completed. + NVAPI_ERROR_DRIVER_RELOAD_IN_PROGRESS = -221, //!< The display driver update in progress. + NVAPI_WAIT_FOR_HW_RESOURCE = -222, //!< Wait for HW resources allocation + NVAPI_REQUIRE_FURTHER_HDCP_ACTION = -223, //!< operation requires further HDCP action + NVAPI_DISPLAY_MUX_TRANSITION_FAILED = -224, //!< Dynamic Mux transition failure + NVAPI_INVALID_DSC_VERSION = -225, //!< Invalid DSC version + NVAPI_INVALID_DSC_SLICECOUNT = -226, //!< Invalid DSC slice count + NVAPI_INVALID_DSC_OUTPUT_BPP = -227, //!< Invalid DSC output BPP + NVAPI_FAILED_TO_LOAD_FROM_DRIVER_STORE = -228, //!< There was an error while loading nvapi.dll from the driver store. + NVAPI_NO_VULKAN = -229, //!< OpenGL does not export Vulkan fake extensions + NVAPI_REQUEST_PENDING = -230, //!< A request for NvTOPPs telemetry CData has already been made and is pending a response. + NVAPI_RESOURCE_IN_USE = -231, //!< Operation cannot be performed because the resource is in use. + } + + public enum NV_DISPLAYCONFIG_FLAGS : uint + { + NV_DISPLAYCONFIG_VALIDATE_ONLY = 0x00000001, + NV_DISPLAYCONFIG_SAVE_TO_PERSISTENCE = 0x00000002, + NV_DISPLAYCONFIG_DRIVER_RELOAD_ALLOWED = 0x00000004, //!< Driver reload is permitted if necessary + NV_DISPLAYCONFIG_FORCE_MODE_ENUMERATION = 0x00000008, //!< Refresh OS mode list. + NV_FORCE_COMMIT_VIDPN = 0x00000010, //!< Tell OS to avoid optimizing CommitVidPn call during a modeset + } + + public enum NV_ROTATE : uint + { + NV_ROTATE_0 = 0, + NV_ROTATE_90 = 1, + NV_ROTATE_180 = 2, + NV_ROTATE_270 = 3, + NV_ROTATE_IGNORED = 4, + } + + public enum NV_FORMAT : uint + { + NV_FORMAT_UNKNOWN = 0, //!< unknown. Driver will choose one as following value. + NV_FORMAT_P8 = 41, //!< for 8bpp mode + NV_FORMAT_R5G6B5 = 23, //!< for 16bpp mode + NV_FORMAT_A8R8G8B8 = 21, //!< for 32bpp mode + NV_FORMAT_A16B16G16R16F = 113, //!< for 64bpp(floating point) mode. + + } + + public enum NV_SCALING : uint + { + NV_SCALING_DEFAULT = 0, //!< No change + + // New Scaling Declarations + NV_SCALING_GPU_SCALING_TO_CLOSEST = 1, //!< Balanced - Full Screen + NV_SCALING_GPU_SCALING_TO_NATIVE = 2, //!< Force GPU - Full Screen + NV_SCALING_GPU_SCANOUT_TO_NATIVE = 3, //!< Force GPU - Centered\No Scaling + NV_SCALING_GPU_SCALING_TO_ASPECT_SCANOUT_TO_NATIVE = 5, //!< Force GPU - Aspect Ratio + NV_SCALING_GPU_SCALING_TO_ASPECT_SCANOUT_TO_CLOSEST = 6, //!< Balanced - Aspect Ratio + NV_SCALING_GPU_SCANOUT_TO_CLOSEST = 7, //!< Balanced - Centered\No Scaling + NV_SCALING_GPU_INTEGER_ASPECT_SCALING = 8, //!< Force GPU - Integer Scaling + + // Legacy Declarations + NV_SCALING_MONITOR_SCALING = NV_SCALING_GPU_SCALING_TO_CLOSEST, + NV_SCALING_ADAPTER_SCALING = NV_SCALING_GPU_SCALING_TO_NATIVE, + NV_SCALING_CENTERED = NV_SCALING_GPU_SCANOUT_TO_NATIVE, + NV_SCALING_ASPECT_SCALING = NV_SCALING_GPU_SCALING_TO_ASPECT_SCANOUT_TO_NATIVE, + + NV_SCALING_CUSTOMIZED = 255 //!< For future use + } + + public enum NV_TARGET_VIEW_MODE : uint + { + NV_VIEW_MODE_STANDARD = 0, + NV_VIEW_MODE_CLONE = 1, + NV_VIEW_MODE_HSPAN = 2, + NV_VIEW_MODE_VSPAN = 3, + NV_VIEW_MODE_DUALVIEW = 4, + NV_VIEW_MODE_MULTIVIEW = 5, + } + + public enum NV_DISPLAY_TV_FORMAT : uint + { + NV_DISPLAY_TV_FORMAT_NONE = 0, + NV_DISPLAY_TV_FORMAT_SD_NTSCM = 0x00000001, + NV_DISPLAY_TV_FORMAT_SD_NTSCJ = 0x00000002, + NV_DISPLAY_TV_FORMAT_SD_PALM = 0x00000004, + NV_DISPLAY_TV_FORMAT_SD_PALBDGH = 0x00000008, + NV_DISPLAY_TV_FORMAT_SD_PALN = 0x00000010, + NV_DISPLAY_TV_FORMAT_SD_PALNC = 0x00000020, + NV_DISPLAY_TV_FORMAT_SD_576i = 0x00000100, + NV_DISPLAY_TV_FORMAT_SD_480i = 0x00000200, + NV_DISPLAY_TV_FORMAT_ED_480p = 0x00000400, + NV_DISPLAY_TV_FORMAT_ED_576p = 0x00000800, + NV_DISPLAY_TV_FORMAT_HD_720p = 0x00001000, + NV_DISPLAY_TV_FORMAT_HD_1080i = 0x00002000, + NV_DISPLAY_TV_FORMAT_HD_1080p = 0x00004000, + NV_DISPLAY_TV_FORMAT_HD_720p50 = 0x00008000, + NV_DISPLAY_TV_FORMAT_HD_1080p24 = 0x00010000, + NV_DISPLAY_TV_FORMAT_HD_1080i50 = 0x00020000, + NV_DISPLAY_TV_FORMAT_HD_1080p50 = 0x00040000, + NV_DISPLAY_TV_FORMAT_UHD_4Kp30 = 0x00080000, + NV_DISPLAY_TV_FORMAT_UHD_4Kp30_3840 = NV_DISPLAY_TV_FORMAT_UHD_4Kp30, + NV_DISPLAY_TV_FORMAT_UHD_4Kp25 = 0x00100000, + NV_DISPLAY_TV_FORMAT_UHD_4Kp25_3840 = NV_DISPLAY_TV_FORMAT_UHD_4Kp25, + NV_DISPLAY_TV_FORMAT_UHD_4Kp24 = 0x00200000, + NV_DISPLAY_TV_FORMAT_UHD_4Kp24_3840 = NV_DISPLAY_TV_FORMAT_UHD_4Kp24, + NV_DISPLAY_TV_FORMAT_UHD_4Kp24_SMPTE = 0x00400000, + NV_DISPLAY_TV_FORMAT_UHD_4Kp50_3840 = 0x00800000, + NV_DISPLAY_TV_FORMAT_UHD_4Kp60_3840 = 0x00900000, + NV_DISPLAY_TV_FORMAT_UHD_4Kp30_4096 = 0x00A00000, + NV_DISPLAY_TV_FORMAT_UHD_4Kp25_4096 = 0x00B00000, + NV_DISPLAY_TV_FORMAT_UHD_4Kp24_4096 = 0x00C00000, + NV_DISPLAY_TV_FORMAT_UHD_4Kp50_4096 = 0x00D00000, + NV_DISPLAY_TV_FORMAT_UHD_4Kp60_4096 = 0x00E00000, + NV_DISPLAY_TV_FORMAT_UHD_8Kp24_7680 = 0x01000000, + NV_DISPLAY_TV_FORMAT_UHD_8Kp25_7680 = 0x02000000, + NV_DISPLAY_TV_FORMAT_UHD_8Kp30_7680 = 0x04000000, + NV_DISPLAY_TV_FORMAT_UHD_8Kp48_7680 = 0x08000000, + NV_DISPLAY_TV_FORMAT_UHD_8Kp50_7680 = 0x09000000, + NV_DISPLAY_TV_FORMAT_UHD_8Kp60_7680 = 0x0A000000, + NV_DISPLAY_TV_FORMAT_UHD_8Kp100_7680 = 0x0B000000, + NV_DISPLAY_TV_FORMAT_UHD_8Kp120_7680 = 0x0C000000, + NV_DISPLAY_TV_FORMAT_UHD_4Kp48_3840 = 0x0D000000, + NV_DISPLAY_TV_FORMAT_UHD_4Kp48_4096 = 0x0E000000, + NV_DISPLAY_TV_FORMAT_UHD_4Kp100_4096 = 0x0F000000, + NV_DISPLAY_TV_FORMAT_UHD_4Kp100_3840 = 0x10000000, + NV_DISPLAY_TV_FORMAT_UHD_4Kp120_4096 = 0x11000000, + NV_DISPLAY_TV_FORMAT_UHD_4Kp120_3840 = 0x12000000, + NV_DISPLAY_TV_FORMAT_UHD_4Kp100_5120 = 0x13000000, + NV_DISPLAY_TV_FORMAT_UHD_4Kp120_5120 = 0x14000000, + NV_DISPLAY_TV_FORMAT_UHD_4Kp24_5120 = 0x15000000, + NV_DISPLAY_TV_FORMAT_UHD_4Kp25_5120 = 0x16000000, + NV_DISPLAY_TV_FORMAT_UHD_4Kp30_5120 = 0x17000000, + NV_DISPLAY_TV_FORMAT_UHD_4Kp48_5120 = 0x18000000, + NV_DISPLAY_TV_FORMAT_UHD_4Kp50_5120 = 0x19000000, + NV_DISPLAY_TV_FORMAT_UHD_4Kp60_5120 = 0x20000000, + NV_DISPLAY_TV_FORMAT_UHD_10Kp24_10240 = 0x21000000, + NV_DISPLAY_TV_FORMAT_UHD_10Kp25_10240 = 0x22000000, + NV_DISPLAY_TV_FORMAT_UHD_10Kp30_10240 = 0x23000000, + NV_DISPLAY_TV_FORMAT_UHD_10Kp48_10240 = 0x24000000, + NV_DISPLAY_TV_FORMAT_UHD_10Kp50_10240 = 0x25000000, + NV_DISPLAY_TV_FORMAT_UHD_10Kp60_10240 = 0x26000000, + NV_DISPLAY_TV_FORMAT_UHD_10Kp100_10240 = 0x27000000, + NV_DISPLAY_TV_FORMAT_UHD_10Kp120_10240 = 0x28000000, + + + NV_DISPLAY_TV_FORMAT_SD_OTHER = 0x30000000, + NV_DISPLAY_TV_FORMAT_ED_OTHER = 0x40000000, + NV_DISPLAY_TV_FORMAT_HD_OTHER = 0x50000000, + + NV_DISPLAY_TV_FORMAT_ANY = 0x80000000, + + } + + public enum NV_GPU_CONNECTOR_TYPE : uint + { + NVAPI_GPU_CONNECTOR_VGA_15_PIN = 0x00000000, + NVAPI_GPU_CONNECTOR_TV_COMPOSITE = 0x00000010, + NVAPI_GPU_CONNECTOR_TV_SVIDEO = 0x00000011, + NVAPI_GPU_CONNECTOR_TV_HDTV_COMPONENT = 0x00000013, + NVAPI_GPU_CONNECTOR_TV_SCART = 0x00000014, + NVAPI_GPU_CONNECTOR_TV_COMPOSITE_SCART_ON_EIAJ4120 = 0x00000016, + NVAPI_GPU_CONNECTOR_TV_HDTV_EIAJ4120 = 0x00000017, + NVAPI_GPU_CONNECTOR_PC_POD_HDTV_YPRPB = 0x00000018, + NVAPI_GPU_CONNECTOR_PC_POD_SVIDEO = 0x00000019, + NVAPI_GPU_CONNECTOR_PC_POD_COMPOSITE = 0x0000001A, + NVAPI_GPU_CONNECTOR_DVI_I_TV_SVIDEO = 0x00000020, + NVAPI_GPU_CONNECTOR_DVI_I_TV_COMPOSITE = 0x00000021, + NVAPI_GPU_CONNECTOR_DVI_I = 0x00000030, + NVAPI_GPU_CONNECTOR_DVI_D = 0x00000031, + NVAPI_GPU_CONNECTOR_ADC = 0x00000032, + NVAPI_GPU_CONNECTOR_LFH_DVI_I_1 = 0x00000038, + NVAPI_GPU_CONNECTOR_LFH_DVI_I_2 = 0x00000039, + NVAPI_GPU_CONNECTOR_SPWG = 0x00000040, + NVAPI_GPU_CONNECTOR_OEM = 0x00000041, + NVAPI_GPU_CONNECTOR_DISPLAYPORT_EXTERNAL = 0x00000046, + NVAPI_GPU_CONNECTOR_DISPLAYPORT_INTERNAL = 0x00000047, + NVAPI_GPU_CONNECTOR_DISPLAYPORT_MINI_EXT = 0x00000048, + NVAPI_GPU_CONNECTOR_HDMI_A = 0x00000061, + NVAPI_GPU_CONNECTOR_HDMI_C_MINI = 0x00000063, + NVAPI_GPU_CONNECTOR_LFH_DISPLAYPORT_1 = 0x00000064, + NVAPI_GPU_CONNECTOR_LFH_DISPLAYPORT_2 = 0x00000065, + NVAPI_GPU_CONNECTOR_VIRTUAL_WFD = 0x00000070, + NVAPI_GPU_CONNECTOR_USB_C = 0x00000071, + NVAPI_GPU_CONNECTOR_UNKNOWN = 0xFFFFFFFF, + } + + public enum NV_TIMING_OVERRIDE : uint + { + NV_TIMING_OVERRIDE_CURRENT = 0, //!< get the current timing + NV_TIMING_OVERRIDE_AUTO, //!< the timing the driver will use based the current policy + NV_TIMING_OVERRIDE_EDID, //!< EDID timing + NV_TIMING_OVERRIDE_DMT, //!< VESA DMT timing + NV_TIMING_OVERRIDE_DMT_RB, //!< VESA DMT timing with reduced blanking + NV_TIMING_OVERRIDE_CVT, //!< VESA CVT timing + NV_TIMING_OVERRIDE_CVT_RB, //!< VESA CVT timing with reduced blanking + NV_TIMING_OVERRIDE_GTF, //!< VESA GTF timing + NV_TIMING_OVERRIDE_EIA861, //!< EIA 861x pre-defined timing + NV_TIMING_OVERRIDE_ANALOG_TV, //!< analog SD/HDTV timing + NV_TIMING_OVERRIDE_CUST, //!< NV custom timings + NV_TIMING_OVERRIDE_NV_PREDEFINED, //!< NV pre-defined timing (basically the PsF timings) + NV_TIMING_OVERRIDE_NV_PSF = NV_TIMING_OVERRIDE_NV_PREDEFINED, + NV_TIMING_OVERRIDE_NV_ASPR, + NV_TIMING_OVERRIDE_SDI, //!< Override for SDI timing + + NV_TIMING_OVRRIDE_MAX, + } + + [StructLayout(LayoutKind.Sequential)] + public struct DisplayHandle + { + private readonly IntPtr ptr; + } + + [StructLayout(LayoutKind.Sequential)] + public struct UnAttachedDisplayHandle + { + public readonly IntPtr ptr; + } + + [StructLayout(LayoutKind.Sequential)] + public struct PhysicalGpuHandle + { + private readonly IntPtr ptr; + } + + + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] + public struct NV_TIMINGEXT + { + public uint flag; //!< Reserved for NVIDIA hardware-based enhancement, such as double-scan. + public ushort rr; //!< Logical refresh rate to present + public uint rrx1k; //!< Physical vertical refresh rate in 0.001Hz + public uint aspect; //!< Display aspect ratio Hi(aspect):horizontal-aspect, Low(aspect):vertical-aspect + public ushort rep; //!< Bit-wise pixel repetition factor: 0x1:no pixel repetition; 0x2:each pixel repeats twice horizontally,.. + public uint status; //!< Timing standard + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 40)] + public string name; //!< Timing name + } + + [StructLayout(LayoutKind.Sequential)] + public struct NV_TIMING + { + // VESA scan out timing parameters: + public ushort HVisible; //!< horizontal visible + public ushort HBorder; //!< horizontal border + public ushort HFrontPorch; //!< horizontal front porch + public ushort HSyncWidth; //!< horizontal sync width + public ushort HTotal; //!< horizontal total + public byte HSyncPol; //!< horizontal sync polarity: 1-negative, 0-positive + + public ushort VVisible; //!< vertical visible + public ushort VBorder; //!< vertical border + public ushort VFrontPorch; //!< vertical front porch + public ushort VSyncWidth; //!< vertical sync width + public ushort VTotal; //!< vertical total + public byte VSyncPol; //!< vertical sync polarity: 1-negative, 0-positive + + public ushort interlaced; //!< 1-interlaced, 0-progressive + public uint pclk; //!< pixel clock in 10 kHz + + //other timing related extras + NV_TIMINGEXT etc; + } + + + [StructLayout(LayoutKind.Sequential)] + public struct NV_POSITION + { + public int x; + public int y; + } + + + [StructLayout(LayoutKind.Sequential)] + public struct NV_RESOLUTION + { + public uint width; + public uint height; + public uint colorDepth; + } + + [StructLayout(LayoutKind.Sequential)] + public struct NV_VIEWPORTF + { + public float x; //!< x-coordinate of the viewport top-left point + public float y; //!< y-coordinate of the viewport top-left point + public float w; //!< Width of the viewport + public float h; //!< Height of the viewport + } + + [StructLayout(LayoutKind.Sequential)] + public struct NV_DISPLAYCONFIG_PATH_ADVANCED_TARGET_INFO + { + public uint version; + + // Rotation and Scaling + public NV_ROTATE rotation; //!< (IN) rotation setting. + public NV_SCALING scaling; //!< (IN) scaling setting. + + // Refresh Rate + public uint refreshRate1K; //!< (IN) Non-interlaced Refresh Rate of the mode, multiplied by 1000, 0 = ignored + //!< This is the value which driver reports to the OS. + // Flags + //public uint interlaced:1; //!< (IN) Interlaced mode flag, ignored if refreshRate == 0 + //public uint primary:1; //!< (IN) Declares primary display in clone configuration. This is *NOT* GDI Primary. + //!< Only one target can be primary per source. If no primary is specified, the first + //!< target will automatically be primary. + //public uint isPanAndScanTarget:1; //!< Whether on this target Pan and Scan is enabled or has to be enabled. Valid only + //!< when the target is part of clone topology. + //public uint disableVirtualModeSupport:1; + //public uint isPreferredUnscaledTarget:1; + //public uint reserved:27; + // TV format information + public NV_GPU_CONNECTOR_TYPE connector; //!< Specify connector type. For TV only, ignored if tvFormat == NV_DISPLAY_TV_FORMAT_NONE + public NV_DISPLAY_TV_FORMAT tvFormat; //!< (IN) to choose the last TV format set this value to NV_DISPLAY_TV_FORMAT_NONE + //!< In case of NvAPI_DISP_GetDisplayConfig(), this field will indicate the currently applied TV format; + //!< if no TV format is applied, this field will have NV_DISPLAY_TV_FORMAT_NONE value. + //!< In case of NvAPI_DISP_SetDisplayConfig(), this field should only be set in case of TVs; + //!< for other displays this field will be ignored and resolution & refresh rate specified in input will be used to apply the TV format. + + // Backend (raster) timing standard + public NV_TIMING_OVERRIDE timingOverride; //!< Ignored if timingOverride == NV_TIMING_OVERRIDE_CURRENT + public NV_TIMING timing; //!< Scan out timing, valid only if timingOverride == NV_TIMING_OVERRIDE_CUST + //!< The value NV_TIMING::NV_TIMINGEXT::rrx1k is obtained from the EDID. The driver may + //!< tweak this value for HDTV, stereo, etc., before reporting it to the OS. + } + + [StructLayout(LayoutKind.Sequential)] + public struct NV_DISPLAYCONFIG_PATH_TARGET_INFO_V2 + { + public uint displayId; //!< Display ID + NV_DISPLAYCONFIG_PATH_ADVANCED_TARGET_INFO[] details; //!< May be NULL if no advanced settings are required + public uint targetId; //!< Windows CCD target ID. Must be present only for non-NVIDIA adapter, for NVIDIA adapter this parameter is ignored. + } + + [StructLayout(LayoutKind.Sequential)] + public struct NV_DISPLAYCONFIG_PATH_INFO_V2 + { + public uint Version; + public uint SourceId; //!< Identifies sourceId used by Windows CCD. This can be optionally set. + + public uint TargetInfoCount; //!< Number of elements in targetInfo array + public NV_DISPLAYCONFIG_PATH_TARGET_INFO_V2[] TargetInfo; + public NV_DISPLAYCONFIG_SOURCE_MODE_INFO_V1[] sourceModeInfo; //!< May be NULL if mode info is not important + //public uint IsNonNVIDIAAdapter : 1; //!< True for non-NVIDIA adapter. + //public uint reserved : 31; //!< Must be 0 + //public LUID pOSAdapterID; //!< Used by Non-NVIDIA adapter for pointer to OS Adapter of LUID + //!< type, type casted to void *. + } + + [StructLayout(LayoutKind.Sequential)] + public struct NV_DISPLAYCONFIG_SOURCE_MODE_INFO_V1 + { + public NV_RESOLUTION resolution; + public NV_FORMAT colorFormat; //!< Ignored at present, must be NV_FORMAT_UNKNOWN (0) + public NV_POSITION position; //!< Is all positions are 0 or invalid, displays will be automatically + //!< positioned from left to right with GDI Primary at 0,0, and all + //!< other displays in the order of the path array. + //public NV_DISPLAYCONFIG_SPANNING_ORIENTATION spanningOrientation; //!< Spanning is only supported on XP + //public uint bGDIPrimary : 1; + //public uint bSLIFocus : 1; + //public uint reserved : 30; //!< Must be 0 + } + + + [StructLayout(LayoutKind.Sequential)] + public struct NV_DISPLAYCONFIG_PATH_TARGET_INFO + { + public uint displayId; //!< Display ID + public NV_DISPLAYCONFIG_PATH_ADVANCED_TARGET_INFO[] details; //!< May be NULL if no advanced settings are required + public uint targetId; //!< Windows CCD target ID. Must be present only for non-NVIDIA adapter, for NVIDIA adapter this parameter is ignored. + } + + + class NVImport + { + + public const uint NV_MAX_HEADS = 4; + public const uint NV_MAX_VID_PROFILES = 4; + public const uint NV_MAX_VID_STREAMS = 4; + public const uint NV_ADVANCED_DISPLAY_HEADS = 4; + public const uint NV_GENERIC_STRING_MAX = 4096; + public const uint NV_LONG_STRING_MAX = 256; + public const uint NV_MAX_ACPI_IDS = 16; + public const uint NV_MAX_AUDIO_DEVICES = 16; + public const uint NV_MAX_AVAILABLE_CPU_TOPOLOGIES = 256; + public const uint NV_MAX_AVAILABLE_SLI_GROUPS = 256; + public const uint NV_MAX_AVAILABLE_DISPLAY_HEADS = 2; + public const uint NV_MAX_DISPLAYS = NV_PHYSICAL_GPUS * NV_ADVANCED_DISPLAY_HEADS; + public const uint NV_MAX_GPU_PER_TOPOLOGY = 8; + public const uint NV_MAX_GPU_TOPOLOGIES = NV_MAX_PHYSICAL_GPUS; + public const uint NV_MAX_HEADS_PER_GPU = 32; + public const uint NV_MAX_LOGICAL_GPUS = 64; + public const uint NV_MAX_PHYSICAL_BRIDGES = 100; + public const uint NV_MAX_PHYSICAL_GPUS = 64; + public const uint NV_MAX_VIEW_MODES = 8; + public const uint NV_PHYSICAL_GPUS = 32; + public const uint NV_SHORT_STRING_MAX = 64; + public const uint NV_SYSTEM_HWBC_INVALID_ID = 0xffffffff; + public const uint NV_SYSTEM_MAX_DISPLAYS = NV_MAX_PHYSICAL_GPUS * NV_MAX_HEADS; + public const uint NV_SYSTEM_MAX_HWBCS = 128; + + + #region Internal Constant + /// Nvapi64_FileName + public const string NVAPI_DLL = "nvapi64.dll"; + /// Kernel32_FileName + public const string Kernel32_FileName = "kernel32.dll"; + #endregion Internal Constant + + #region DLLImport + [DllImport(Kernel32_FileName)] + public static extern HMODULE GetModuleHandle(string moduleName); + + // This function initializes the NvAPI library (if not already initialized) but always increments the ref-counter. + // This must be called before calling other NvAPI_ functions. Note: It is now mandatory to call NvAPI_Initialize before calling any other NvAPI. NvAPI_Unload should be called to unload the NVAPI Library. + [DllImport(NVAPI_DLL, CallingConvention = CallingConvention.Cdecl)] + public static extern NVAPI_STATUS NvAPI_Initialize(); + + //DESCRIPTION: Decrements the ref-counter and when it reaches ZERO, unloads NVAPI library.This must be called in pairs with NvAPI_Initialize. + // If the client wants unload functionality, it is recommended to always call NvAPI_Initialize and NvAPI_Unload in pairs. + // Unloading NvAPI library is not supported when the library is in a resource locked state. + // Some functions in the NvAPI library initiates an operation or allocates certain resources and there are corresponding functions available, to complete the operation or free the allocated resources. + // All such function pairs are designed to prevent unloading NvAPI library. For example, if NvAPI_Unload is called after NvAPI_XXX which locks a resource, it fails with NVAPI_ERROR. + // Developers need to call the corresponding NvAPI_YYY to unlock the resources, before calling NvAPI_Unload again. + [DllImport(NVAPI_DLL, CallingConvention = CallingConvention.Cdecl)] + public static extern NVAPI_STATUS NvAPI_Unload(); + + // This is used to get a string containing the NVAPI version + [DllImport(NVAPI_DLL, CallingConvention = CallingConvention.Cdecl)] + public static extern NVAPI_STATUS NvAPI_GetInterfaceVersionStringEx(out string description); + + // NVAPI SESSION HANDLING FUNCTIONS + // This is used to get a session handle to use to maintain state across multiple NVAPI calls + [DllImport(NVAPI_DLL, CallingConvention = CallingConvention.Cdecl)] + public static extern NVAPI_STATUS NvAPI_DRS_CreateSession(out IntPtr session); + + // This is used to destroy a session handle to used to maintain state across multiple NVAPI calls + [DllImport(NVAPI_DLL, CallingConvention = CallingConvention.Cdecl)] + public static extern NVAPI_STATUS NvAPI_DRS_DestorySession(IntPtr session); + + // This API lets caller retrieve the current global display configuration. + // USAGE: The caller might have to call this three times to fetch all the required configuration details as follows: + // First Pass: Caller should Call NvAPI_DISP_GetDisplayConfig() with pathInfo set to NULL to fetch pathInfoCount. + // Second Pass: Allocate memory for pathInfo with respect to the number of pathInfoCount(from First Pass) to fetch targetInfoCount. If sourceModeInfo is needed allocate memory or it can be initialized to NULL. + // Third Pass(Optional, only required if target information is required): Allocate memory for targetInfo with respect to number of targetInfoCount(from Second Pass). + [DllImport(NVAPI_DLL, CallingConvention = CallingConvention.Cdecl)] + public static extern NVAPI_STATUS NvAPI_DISP_GetDisplayConfig(ref ulong pathInfoCount, out NV_DISPLAYCONFIG_PATH_TARGET_INFO_V2 pathInfo); + + + + + #endregion DLLImport + + /*public static ADL_Main_Memory_Alloc_Delegate ADL_Main_Memory_Alloc = ADL_Main_Memory_Alloc_Function; + /// Build in memory allocation function + /// input size + /// return the memory buffer + public static IntPtr ADL_Main_Memory_Alloc_Function(int size) + { + //Console.WriteLine($"\nCallback called with param: {size}"); + IntPtr result = Marshal.AllocCoTaskMem(size); + return result; + }*/ + + } +} \ No newline at end of file diff --git a/DisplayMagicianShared/NVIDIA/NVIDIALibrary.cs b/DisplayMagicianShared/NVIDIA/NVIDIALibrary.cs index 75ab297..6afcab6 100644 --- a/DisplayMagicianShared/NVIDIA/NVIDIALibrary.cs +++ b/DisplayMagicianShared/NVIDIA/NVIDIALibrary.cs @@ -1,85 +1,187 @@ using System; using System.Collections.Generic; +using System.Linq; using System.Runtime.InteropServices; -using ATI.ADL; +using System.Text; using Microsoft.Win32.SafeHandles; +using DisplayMagicianShared; +using System.ComponentModel; +using DisplayMagicianShared.Windows; namespace DisplayMagicianShared.NVIDIA { - public class NVIDIALibrary : IDisposable + [StructLayout(LayoutKind.Sequential)] + public struct NVIDIA_ADAPTER_CONFIG : IEquatable { + public int AdapterDeviceNumber; + public int AdapterBusNumber; + public int AdapterIndex; + public bool IsPrimaryAdapter; + //public ADL_DISPLAY_MAP[] DisplayMaps; + //public ADL_DISPLAY_TARGET[] DisplayTargets; + public int SLSMapIndex; + public bool IsSLSEnabled; + //public ADL_SLS_MAP[] SLSMap; + + public bool Equals(NVIDIA_ADAPTER_CONFIG other) + => AdapterIndex == other.AdapterIndex && + AdapterBusNumber == other.AdapterBusNumber && + AdapterDeviceNumber == other.AdapterDeviceNumber && + IsPrimaryAdapter == other.IsPrimaryAdapter && + //DisplayMaps.SequenceEqual(other.DisplayMaps) && + //DisplayTargets.SequenceEqual(other.DisplayTargets); + SLSMapIndex == other.SLSMapIndex && + IsSLSEnabled == other.IsSLSEnabled; + + public override int GetHashCode() + { + return (AdapterIndex, AdapterBusNumber, AdapterDeviceNumber, IsPrimaryAdapter, SLSMapIndex, IsSLSEnabled).GetHashCode(); + } + } + + [StructLayout(LayoutKind.Sequential)] + public struct NVIDIA_DISPLAY_CONFIG : IEquatable + { + //public Dictionary DisplayAdapters; + public List AdapterConfigs; + //public DISPLAYCONFIG_MODE_INFO[] DisplayConfigModes; + //public ADVANCED_HDR_INFO_PER_PATH[] DisplayHDRStates; + public WINDOWS_DISPLAY_CONFIG WindowsDisplayConfig; + + public bool Equals(NVIDIA_DISPLAY_CONFIG other) + => AdapterConfigs.SequenceEqual(other.AdapterConfigs) && + //DisplayConfigPaths.SequenceEqual(other.DisplayConfigPaths) && + //DisplayConfigModes.SequenceEqual(other.DisplayConfigModes) && + //DisplayHDRStates.SequenceEqual(other.DisplayHDRStates) && + WindowsDisplayConfig.Equals(other.WindowsDisplayConfig); + + public override int GetHashCode() + { + return (AdapterConfigs, WindowsDisplayConfig).GetHashCode(); + } + } + + class NVIDIALibrary : IDisposable + { + // Static members are 'eagerly initialized', that is, // immediately when class is loaded for the first time. // .NET guarantees thread safety for static initialization private static NVIDIALibrary _instance = new NVIDIALibrary(); + private static WinLibrary _winLibrary = new WinLibrary(); + private bool _initialised = false; + private bool _haveSessionHandle = false; // To detect redundant calls private bool _disposed = false; // Instantiate a SafeHandle instance. private SafeHandle _safeHandle = new SafeFileHandle(IntPtr.Zero, true); - private IntPtr _adlContextHandle = IntPtr.Zero; - - // Struct to be used as the NVIDIA Profile - public struct NVIDIAProfile - { - public List Adapters; - } - - // Struct to store the Display - public struct NVIDIAAdapter - { - internal ADLAdapterInfoX2 AdapterInfoX2; - internal List Displays; - } - - // Struct to store the Display - public struct NVIDIADisplay - { - internal List DisplayModes; - } - + private IntPtr _nvapiSessionHandle = IntPtr.Zero; static NVIDIALibrary() { } public NVIDIALibrary() { - int ADLRet = ADL.ADL_ERR; - SharedLogger.logger.Trace("NVIDIALibrary/NVIDIALibrary: Intialising ADL2 library interface"); try { - if (ADL.ADL2_Main_Control_Create != null) + SharedLogger.logger.Trace($"NVIDIALibrary/NVIDIALibrary: Attempting to load the NVIDIA NVAPI DLL {NVImport.NVAPI_DLL}"); + // Attempt to prelink all of the NVAPI functions + Marshal.PrelinkAll(typeof(NVImport)); + + // If we get here then we definitely have the NVIDIA driver available. + NVAPI_STATUS NVStatus; + SharedLogger.logger.Trace("NVIDIALibrary/NVIDIALibrary: Intialising NVIDIA NVAPI library interface"); + // Step 1: Initialise the NVAPI + try { - // Second parameter is 1: Get only the present adapters - ADLRet = ADL.ADL2_Main_Control_Create(ADL.ADL_Main_Memory_Alloc, 1, out _adlContextHandle); + NVStatus = NVImport.NvAPI_Initialize(); + if (NVStatus == NVAPI_STATUS.NVAPI_OK) + { + _initialised = true; + SharedLogger.logger.Trace($"NVIDIALibrary/NVIDIALibrary: NVIDIA NVAPI library was initialised successfully"); + } + else + { + SharedLogger.logger.Trace($"NVIDIALibrary/NVIDIALibrary: Error intialising NVIDIA NVAPI library. NvAPI_Initialize() returned error code {NVStatus}"); + } + } + catch (Exception ex) + { + SharedLogger.logger.Trace(ex, $"NVIDIALibrary/NVIDIALibrary: Exception intialising NVIDIA NVAPI library. NvAPI_Initialize() caused an exception."); } - if (ADLRet == ADL.ADL_OK) + // Step 2: Get a session handle that we can use for all other interactions + try { - _initialised = true; - SharedLogger.logger.Trace("NVIDIALibrary/NVIDIALibrary: ADL2 library was initialised successfully"); + NVStatus = NVImport.NvAPI_DRS_CreateSession(out _nvapiSessionHandle); + if (NVStatus == NVAPI_STATUS.NVAPI_OK) + { + _haveSessionHandle = true; + SharedLogger.logger.Trace($"NVIDIALibrary/NVIDIALibrary: NVIDIA NVAPI library DRS session handle was created successfully"); + } + else + { + SharedLogger.logger.Trace($"NVIDIALibrary/NVIDIALibrary: Error creating a NVAPI library DRS session handle. NvAPI_DRS_CreateSession() returned error code {NVStatus}"); + } } - else + catch (Exception ex) { - SharedLogger.logger.Error("NVIDIALibrary/NVIDIALibrary: Error intialising ADL2 library. ADL2_Main_Control_Create() returned error code " + ADL.ConvertADLReturnValueIntoWords(ADLRet)); + SharedLogger.logger.Trace(ex, $"NVIDIALibrary/NVIDIALibrary: Exception creating a NVAPI library DRS session handle. NvAPI_DRS_CreateSession() caused an exception."); } + + _winLibrary = WinLibrary.GetLibrary(); + } - catch (Exception ex) + catch (DllNotFoundException ex) { - SharedLogger.logger.Error(ex, "NVIDIALibrary/NVIDIALibrary: Exception intialising ADL2 library. ADL2_Main_Control_Create() caused an exception"); + // If this fires, then the DLL isn't available, so we need don't try to do anything else + SharedLogger.logger.Info(ex, $"NVIDIALibrary/NVIDIALibrary: Exception trying to load the NVIDIA NVAPI DLL {NVImport.NVAPI_DLL}. This generally means you don't have the NVIDIA driver installed."); } } ~NVIDIALibrary() { - // If the ADL2 library was initialised, then we need to free it up. + SharedLogger.logger.Trace("NVIDIALibrary/~NVIDIALibrary: Destroying NVIDIA NVAPI library interface"); + // If the NVAPI library was initialised, then we need to free it up. if (_initialised) { - if (null != ADL.ADL2_Main_Control_Destroy) - ADL.ADL2_Main_Control_Destroy(_adlContextHandle); + NVAPI_STATUS NVStatus; + // If we have a session handle we need to free it up first + if (_haveSessionHandle) + { + try + { + NVStatus = NVImport.NvAPI_DRS_DestorySession(_nvapiSessionHandle); + if (NVStatus == NVAPI_STATUS.NVAPI_OK) + { + _haveSessionHandle = true; + SharedLogger.logger.Trace($"NVIDIALibrary/NVIDIALibrary: NVIDIA NVAPI library DRS session handle was successfully destroyed"); + } + else + { + SharedLogger.logger.Trace($"NVIDIALibrary/NVIDIALibrary: Error destroying the NVAPI library DRS session handle. NvAPI_DRS_DestorySession() returned error code {NVStatus}"); + } + } + catch (Exception ex) + { + SharedLogger.logger.Trace(ex, $"NVIDIALibrary/NVIDIALibrary: Exception destroying the NVIDIA NVAPI library. NvAPI_DRS_DestorySession() caused an exception."); + } + } + + try + { + NVImport.NvAPI_Unload(); + SharedLogger.logger.Trace($"NVIDIALibrary/NVIDIALibrary: NVIDIA NVAPI library was unloaded successfully"); + } + catch (Exception ex) + { + SharedLogger.logger.Trace(ex, $"NVIDIALibrary/NVIDIALibrary: Exception unloading the NVIDIA NVAPI library. NvAPI_Unload() caused an exception."); + } + } } @@ -96,8 +198,8 @@ namespace DisplayMagicianShared.NVIDIA if (disposing) { - if (null != ADL.ADL_Main_Control_Destroy) - ADL.ADL_Main_Control_Destroy(); + + //NVImport.ADL_Main_Control_Destroy(); // Dispose managed state (managed objects). _safeHandle?.Dispose(); @@ -109,7 +211,10 @@ namespace DisplayMagicianShared.NVIDIA public bool IsInstalled { - get { return _initialised; } + get + { + return _initialised; + } } public static NVIDIALibrary GetLibrary() @@ -117,1427 +222,763 @@ namespace DisplayMagicianShared.NVIDIA return _instance; } - public List GenerateProfileDisplayIdentifiers() + + + public NVIDIA_DISPLAY_CONFIG GetActiveConfig() { - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateProfileDisplayIdentifiers: Getting NVIDIA active adapter count"); + SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveConfig: Getting the currently active config"); + bool allDisplays = true; + return GetNVIDIADisplayConfig(allDisplays); + } - int ADLRet = ADL.ADL_ERR; - int NumberOfAdapters = 0; + private NVIDIA_DISPLAY_CONFIG GetNVIDIADisplayConfig(bool allDisplays = false) + { + NVIDIA_DISPLAY_CONFIG myDisplayConfig = new NVIDIA_DISPLAY_CONFIG(); + myDisplayConfig.AdapterConfigs = new List(); - List displayIdentifiers = new List(); - - if (null != ADL.ADL2_Adapter_NumberOfAdapters_Get) + if (_initialised) { - ADL.ADL2_Adapter_NumberOfAdapters_Get(_adlContextHandle, ref NumberOfAdapters); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateProfileDisplayIdentifiers: Number Of Adapters: {NumberOfAdapters.ToString()} "); - } - - if (NumberOfAdapters > 0) - { - - IntPtr AdapterBuffer = IntPtr.Zero; - if (ADL.ADL2_Adapter_AdapterInfoX4_Get != null) - { - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateProfileDisplayIdentifiers: ADL2_Adapter_AdapterInfoX4_Get DLL function exists."); - - // Get the Adapter info and put it in the AdapterBuffer - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateProfileDisplayIdentifiers: Running ADL2_Adapter_AdapterInfoX4_Get to find all known NVIDIA adapters."); - //ADLRet = ADL.ADL2_Adapter_AdapterInfoX4_Get(_adlContextHandle, AdapterBuffer, size); - int numAdapters = 0; - ADLRet = ADL.ADL2_Adapter_AdapterInfoX4_Get(_adlContextHandle, ADL.ADL_ADAPTER_INDEX_ALL, out numAdapters, out AdapterBuffer); - if (ADLRet == ADL.ADL_OK) - { - - int IsActive = ADL.ADL_TRUE; // We only want to search for active adapters - - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateProfileDisplayIdentifiers: Successfully run ADL2_Adapter_AdapterInfoX4_Get to find information about all known NVIDIA adapters."); - - ADLAdapterInfoX2 oneAdapter = new ADLAdapterInfoX2(); - // Go through each adapter - for (int adapterLoop = 0; adapterLoop < numAdapters; adapterLoop++) - { - oneAdapter = (ADLAdapterInfoX2)Marshal.PtrToStructure(new IntPtr(AdapterBuffer.ToInt64() + (adapterLoop * Marshal.SizeOf(oneAdapter))), oneAdapter.GetType()); - - if (oneAdapter.Exist != 1) - { - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateProfileDisplayIdentifiers: NVIDIA Adapter #{oneAdapter.AdapterIndex.ToString()} doesn't exist at present so skipping detection for this adapter."); - continue; - } - - if (oneAdapter.Present != 1) - { - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateProfileDisplayIdentifiers: NVIDIA Adapter #{oneAdapter.AdapterIndex.ToString()} isn't enabled at present so skipping detection for this adapter."); - continue; - } - - // Check if the adapter is active - if (ADL.ADL2_Adapter_Active_Get != null) - ADLRet = ADL.ADL2_Adapter_Active_Get(_adlContextHandle, oneAdapter.AdapterIndex, ref IsActive); - - if (ADLRet == ADL.ADL_OK) - { - // Only continue if the adapter is enabled - if (IsActive != ADL.ADL_TRUE) - { - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateProfileDisplayIdentifiers: NVIDIA Adapter #{oneAdapter.AdapterIndex.ToString()} isn't active ({oneAdapter.AdapterName})."); - continue; - } - - // Only continue if the adapter index is > 0 - if (oneAdapter.AdapterIndex < 0) - { - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateProfileDisplayIdentifiers: NVIDIA Adapter has an adapter index of {oneAdapter.AdapterIndex.ToString()} which indicates it is not a real adapter."); - continue; - } - - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateProfileDisplayIdentifiers: NVIDIA Adapter #{oneAdapter.AdapterIndex.ToString()} is active! ({oneAdapter.AdapterName})."); - - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateProfileDisplayIdentifiers: ### Adapter Info for Adapter #{oneAdapter.AdapterIndex} ###"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateProfileDisplayIdentifiers: Adapter AdapterIndex = {oneAdapter.AdapterIndex}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateProfileDisplayIdentifiers: Adapter AdapterName = {oneAdapter.AdapterName}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateProfileDisplayIdentifiers: Adapter BusNumber = {oneAdapter.BusNumber}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateProfileDisplayIdentifiers: Adapter DeviceNumber = {oneAdapter.DeviceNumber}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateProfileDisplayIdentifiers: Adapter DisplayName = {oneAdapter.DisplayName}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateProfileDisplayIdentifiers: Adapter DriverPath = {oneAdapter.DriverPath}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateProfileDisplayIdentifiers: Adapter DriverPathExt = {oneAdapter.DriverPathExt}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateProfileDisplayIdentifiers: Adapter Exist = {oneAdapter.Exist}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateProfileDisplayIdentifiers: Adapter FunctionNumber = {oneAdapter.FunctionNumber}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateProfileDisplayIdentifiers: Adapter InfoMask = {oneAdapter.InfoMask}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateProfileDisplayIdentifiers: Adapter InfoValue = {oneAdapter.InfoValue}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateProfileDisplayIdentifiers: Adapter OSDisplayIndex = {oneAdapter.OSDisplayIndex}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateProfileDisplayIdentifiers: Adapter PNPString = {oneAdapter.PNPString}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateProfileDisplayIdentifiers: Adapter Present = {oneAdapter.Present}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateProfileDisplayIdentifiers: Adapter Size = {oneAdapter.Size}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateProfileDisplayIdentifiers: Adapter UDID = {oneAdapter.UDID}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateProfileDisplayIdentifiers: Adapter VendorID = {oneAdapter.VendorID}"); - - // Get the Adapter Capabilities - ADLAdapterCapsX2 AdapterCapabilities = new ADLAdapterCapsX2(); - if (ADL.ADL2_AdapterX2_Caps != null) - { - ADLRet = ADL.ADL2_AdapterX2_Caps(_adlContextHandle, oneAdapter.AdapterIndex, out AdapterCapabilities); - } - - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateProfileDisplayIdentifiers: ### Adapter Capabilities for Adapter #{oneAdapter.AdapterIndex} ###"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateProfileDisplayIdentifiers: Adapter ID = {AdapterCapabilities.AdapterID}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateProfileDisplayIdentifiers: Adapter Capabilities Mask = {AdapterCapabilities.CapsMask}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateProfileDisplayIdentifiers: Adapter Capabilities Value = {AdapterCapabilities.CapsValue}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateProfileDisplayIdentifiers: Adapter Num of Connectors = {AdapterCapabilities.NumConnectors}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateProfileDisplayIdentifiers: Adapter Num of Controllers = {AdapterCapabilities.NumControllers}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateProfileDisplayIdentifiers: Adapter Num of Displays = {AdapterCapabilities.NumDisplays}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateProfileDisplayIdentifiers: Adapter Num of GL Sync Connectors = {AdapterCapabilities.NumOfGLSyncConnectors}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateProfileDisplayIdentifiers: Adapter Num of Overlays = {AdapterCapabilities.NumOverlays}"); - - // Obtain information about displays - //ADLDisplayInfoArray displayInfoArray = new ADLDisplayInfoArray(); - - if (ADL.ADL2_Display_DisplayInfo_Get != null) - { - IntPtr DisplayBuffer = IntPtr.Zero; - int numDisplays = 0; - // Force the display detection and get the Display Info. Use 0 as last parameter to NOT force detection - ADLRet = ADL.ADL2_Display_DisplayInfo_Get(_adlContextHandle, oneAdapter.AdapterIndex, ref numDisplays, out DisplayBuffer, 0); - if (ADLRet == ADL.ADL_OK) - { - - try - { - ADLDisplayInfo oneDisplayInfo = new ADLDisplayInfo(); - - for (int displayLoop = 0; displayLoop < numDisplays; displayLoop++) - { - oneDisplayInfo = (ADLDisplayInfo)Marshal.PtrToStructure(new IntPtr(DisplayBuffer.ToInt64() + (displayLoop * Marshal.SizeOf(oneDisplayInfo))), oneDisplayInfo.GetType()); - - // Is the display mapped to this adapter? If not we skip it! - if (oneDisplayInfo.DisplayID.DisplayLogicalAdapterIndex != oneAdapter.AdapterIndex) - { - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateProfileDisplayIdentifiers: NVIDIA Adapter #{oneAdapter.AdapterIndex.ToString()} ({oneAdapter.AdapterName}) AdapterID display ID#{oneDisplayInfo.DisplayID.DisplayLogicalIndex} is not a real display as its DisplayID.DisplayLogicalAdapterIndex is -1"); - continue; - } - - // Convert the displayInfoValue to something usable using a library function I made - ConvertedDisplayInfoValue displayInfoValue = ADL.ConvertDisplayInfoValue(oneDisplayInfo.DisplayInfoValue); - - if (!displayInfoValue.DISPLAYCONNECTED) - { - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateProfileDisplayIdentifiers: NVIDIA Adapter #{oneAdapter.AdapterIndex.ToString()} ({oneAdapter.AdapterName}) AdapterID display ID#{oneDisplayInfo.DisplayID.DisplayLogicalIndex} is not connected"); - continue; - } - - // Skip connected but non-mapped displays (not mapped in windows) - we want all displays currently visible in the OS - if (!displayInfoValue.DISPLAYMAPPED) - { - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateProfileDisplayIdentifiers: NVIDIA Adapter #{oneAdapter.AdapterIndex.ToString()} ({oneAdapter.AdapterName}) AdapterID display ID#{oneDisplayInfo.DisplayID.DisplayLogicalIndex} is not mapped in Windows OS"); - continue; - } - - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateProfileDisplayIdentifiers: NVIDIA Adapter #{oneAdapter.AdapterIndex.ToString()} ({oneAdapter.AdapterName}) AdapterID display ID#{oneDisplayInfo.DisplayID.DisplayLogicalIndex} is connected and mapped in Windows OS"); - - ADL.ADLDisplayConnectionType displayConnector = (ADL.ADLDisplayConnectionType)oneDisplayInfo.DisplayConnector; - - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateProfileDisplayIdentifiers: ### Display Info for Display #{oneDisplayInfo.DisplayID.DisplayLogicalIndex} on Adapter #{oneAdapter.AdapterIndex} ###"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateProfileDisplayIdentifiers: Display Connector = {displayConnector.ToString("G")}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateProfileDisplayIdentifiers: Display Controller Index = {oneDisplayInfo.DisplayControllerIndex}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateProfileDisplayIdentifiers: Display Logical Adapter Index = {oneDisplayInfo.DisplayID.DisplayLogicalAdapterIndex}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateProfileDisplayIdentifiers: Display Logical Index = {oneDisplayInfo.DisplayID.DisplayLogicalIndex}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateProfileDisplayIdentifiers: Display Physical Adapter Index = {oneDisplayInfo.DisplayID.DisplayPhysicalAdapterIndex}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateProfileDisplayIdentifiers: Display Physical Index = {oneDisplayInfo.DisplayID.DisplayPhysicalIndex}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateProfileDisplayIdentifiers: Display Info Mask = {oneDisplayInfo.DisplayInfoMask}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateProfileDisplayIdentifiers: Display Info Value = {oneDisplayInfo.DisplayInfoValue}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateProfileDisplayIdentifiers: Display Manufacturer Name = {oneDisplayInfo.DisplayManufacturerName}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateProfileDisplayIdentifiers: Display Name = {oneDisplayInfo.DisplayName}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateProfileDisplayIdentifiers: Display Output Type = {oneDisplayInfo.DisplayOutputType}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateProfileDisplayIdentifiers: Display Type = {oneDisplayInfo.DisplayType}"); - - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateProfileDisplayIdentifiers: Display Info Value DISPLAYCONNECTED = {displayInfoValue.DISPLAYCONNECTED}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateProfileDisplayIdentifiers: Display Info Value DISPLAYMAPPED = {displayInfoValue.DISPLAYMAPPED}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateProfileDisplayIdentifiers: Display Info Value FORCIBLESUPPORTED = {displayInfoValue.FORCIBLESUPPORTED}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateProfileDisplayIdentifiers: Display Info Value GENLOCKSUPPORTED = {displayInfoValue.GENLOCKSUPPORTED}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateProfileDisplayIdentifiers: Display Info Value LDA_DISPLAY = {displayInfoValue.LDA_DISPLAY}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateProfileDisplayIdentifiers: Display Info Value MANNER_SUPPORTED_2HSTRETCH = {displayInfoValue.MANNER_SUPPORTED_2HSTRETCH}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateProfileDisplayIdentifiers: Display Info Value MANNER_SUPPORTED_2VSTRETCH = {displayInfoValue.MANNER_SUPPORTED_2VSTRETCH}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateProfileDisplayIdentifiers: Display Info Value MANNER_SUPPORTED_CLONE = {displayInfoValue.MANNER_SUPPORTED_CLONE}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateProfileDisplayIdentifiers: Display Info Value MANNER_SUPPORTED_EXTENDED = {displayInfoValue.MANNER_SUPPORTED_EXTENDED}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateProfileDisplayIdentifiers: Display Info Value MANNER_SUPPORTED_NSTRETCH1GPU = {displayInfoValue.MANNER_SUPPORTED_NSTRETCH1GPU}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateProfileDisplayIdentifiers: Display Info Value MANNER_SUPPORTED_NSTRETCHNGPU = {displayInfoValue.MANNER_SUPPORTED_NSTRETCHNGPU}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateProfileDisplayIdentifiers: Display Info Value MANNER_SUPPORTED_SINGLE = {displayInfoValue.MANNER_SUPPORTED_SINGLE}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateProfileDisplayIdentifiers: Display Info Value MODETIMING_OVERRIDESSUPPORTED = {displayInfoValue.MODETIMING_OVERRIDESSUPPORTED}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateProfileDisplayIdentifiers: Display Info Value MULTIVPU_SUPPORTED = {displayInfoValue.MULTIVPU_SUPPORTED}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateProfileDisplayIdentifiers: Display Info Value NONLOCAL = {displayInfoValue.NONLOCAL}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateProfileDisplayIdentifiers: Display Info Value SHOWTYPE_PROJECTOR = {displayInfoValue.SHOWTYPE_PROJECTOR}"); - - ADL.ADLDisplayConnectionType displayConnectionType = ADL.ADLDisplayConnectionType.Unknown; - ADLDisplayConfig displayConfig = new ADLDisplayConfig(); - displayConfig.Size = Marshal.SizeOf(displayConfig); - if (ADL.ADL2_Display_DeviceConfig_Get != null) - { - // Get the DisplayConfig from the Display - ADLRet = ADL.ADL2_Display_DeviceConfig_Get(_adlContextHandle, oneAdapter.AdapterIndex, oneDisplayInfo.DisplayID.DisplayPhysicalIndex, out displayConfig); - if (ADLRet == ADL.ADL_OK) - { - displayConnectionType = (ADL.ADLDisplayConnectionType)displayConfig.ConnectorType; - - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateProfileDisplayIdentifiers: ### Display Device Config for Display #{oneDisplayInfo.DisplayID.DisplayLogicalIndex} on Adapter #{oneAdapter.AdapterIndex} ###"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateProfileDisplayIdentifiers: Display Connector Type = {displayConnectionType.ToString("G")}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateProfileDisplayIdentifiers: Display Device Data = {displayConfig.DeviceData}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateProfileDisplayIdentifiers: Display Overridded Device Data = {displayConfig.OverriddedDeviceData}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateProfileDisplayIdentifiers: Display Reserved Data = {displayConfig.Reserved}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateProfileDisplayIdentifiers: Display Size = {displayConfig.Size}"); - } - else - { - SharedLogger.logger.Warn($"NVIDIALibrary/GenerateProfileDisplayIdentifiers: Error running ADL2_Display_DeviceConfig_Get on Display #{oneDisplayInfo.DisplayID.DisplayLogicalIndex} on Adapter #{oneAdapter.AdapterIndex}: {ADL.ConvertADLReturnValueIntoWords(ADLRet)}"); - } - } - - ADLDDCInfo2 displayDDCInfo2 = new ADLDDCInfo2(); - displayDDCInfo2.Size = Marshal.SizeOf(displayDDCInfo2); - // Create a stringbuilder buffer that EDID can be loaded into - //displayEDIDData.EDIDData = new StringBuilder(256); - - if (ADL.ADL2_Display_DDCInfo2_Get != null) - { - // Get the DDC Data from the Display - ADLRet = ADL.ADL2_Display_DDCInfo2_Get(_adlContextHandle, oneAdapter.AdapterIndex, oneDisplayInfo.DisplayID.DisplayPhysicalIndex, out displayDDCInfo2); - if (ADLRet == ADL.ADL_OK) - { - - // Convert the DDCInfoFlag to something usable using a library function I made - ConvertedDDCInfoFlag DDCInfoFlag = ADL.ConvertDDCInfoFlag(displayDDCInfo2.DDCInfoFlag); - - // Convert the DDCInfoFlag to something usable using a library function I made - ConvertedSupportedHDR supportedHDR = ADL.ConvertSupportedHDR(displayDDCInfo2.SupportedHDR); - - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateProfileDisplayIdentifiers: ### Display DDCInfo2 for Display #{oneDisplayInfo.DisplayID.DisplayLogicalIndex} on Adapter #{oneAdapter.AdapterIndex} ###"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateProfileDisplayIdentifiers: Display AvgLuminanceData = {displayDDCInfo2.AvgLuminanceData}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateProfileDisplayIdentifiers: Display DDCInfoFlag = {displayDDCInfo2.DDCInfoFlag}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateProfileDisplayIdentifiers: Display DiffuseScreenReflectance = {displayDDCInfo2.DiffuseScreenReflectance}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateProfileDisplayIdentifiers: Display DisplayName = {displayDDCInfo2.DisplayName}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateProfileDisplayIdentifiers: Display FreesyncFlags = {displayDDCInfo2.FreesyncFlags}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateProfileDisplayIdentifiers: Display ManufacturerID = {displayDDCInfo2.ManufacturerID}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateProfileDisplayIdentifiers: Display MaxBacklightMaxLuminanceData = {displayDDCInfo2.MaxBacklightMaxLuminanceData}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateProfileDisplayIdentifiers: Display MaxBacklightMinLuminanceData = {displayDDCInfo2.MaxBacklightMinLuminanceData}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateProfileDisplayIdentifiers: Display MaxHResolution = {displayDDCInfo2.MaxHResolution}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateProfileDisplayIdentifiers: Display MaxLuminanceData = {displayDDCInfo2.MaxLuminanceData}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateProfileDisplayIdentifiers: Display MaxRefresh = {displayDDCInfo2.MaxRefresh}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateProfileDisplayIdentifiers: Display MaxVResolution = {displayDDCInfo2.MaxVResolution}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateProfileDisplayIdentifiers: Display MinBacklightMaxLuminanceData = {displayDDCInfo2.MinBacklightMaxLuminanceData}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateProfileDisplayIdentifiers: Display MinBacklightMinLuminanceData = {displayDDCInfo2.MinBacklightMinLuminanceData}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateProfileDisplayIdentifiers: Display MinLuminanceData = {displayDDCInfo2.MinLuminanceData}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateProfileDisplayIdentifiers: Display MinLuminanceNoDimmingData = {displayDDCInfo2.MinLuminanceNoDimmingData}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateProfileDisplayIdentifiers: Display NativeDisplayChromaticityBlueX = {displayDDCInfo2.NativeDisplayChromaticityBlueX}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateProfileDisplayIdentifiers: Display NativeDisplayChromaticityBlueY = {displayDDCInfo2.NativeDisplayChromaticityBlueY}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateProfileDisplayIdentifiers: Display NativeDisplayChromaticityGreenX = {displayDDCInfo2.NativeDisplayChromaticityGreenX}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateProfileDisplayIdentifiers: Display NativeDisplayChromaticityGreenY = {displayDDCInfo2.NativeDisplayChromaticityGreenY}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateProfileDisplayIdentifiers: Display NativeDisplayChromaticityRedX = {displayDDCInfo2.NativeDisplayChromaticityRedX}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateProfileDisplayIdentifiers: Display NativeDisplayChromaticityRedY = {displayDDCInfo2.NativeDisplayChromaticityRedY}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateProfileDisplayIdentifiers: Display NativeDisplayChromaticityWhiteX = {displayDDCInfo2.NativeDisplayChromaticityWhiteX}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateProfileDisplayIdentifiers: Display NativeDisplayChromaticityWhiteY = {displayDDCInfo2.NativeDisplayChromaticityWhiteY}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateProfileDisplayIdentifiers: Display PackedPixelSupported = {displayDDCInfo2.PackedPixelSupported}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateProfileDisplayIdentifiers: Display PanelPixelFormat = {displayDDCInfo2.PanelPixelFormat}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateProfileDisplayIdentifiers: Display ProductID = {displayDDCInfo2.ProductID}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateProfileDisplayIdentifiers: Display PTMCx = {displayDDCInfo2.PTMCx}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateProfileDisplayIdentifiers: Display PTMCy = {displayDDCInfo2.PTMCy}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateProfileDisplayIdentifiers: Display PTMRefreshRate = {displayDDCInfo2.PTMRefreshRate}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateProfileDisplayIdentifiers: Display SerialID = {displayDDCInfo2.SerialID}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateProfileDisplayIdentifiers: Display Size = {displayDDCInfo2.Size}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateProfileDisplayIdentifiers: Display SpecularScreenReflectance = {displayDDCInfo2.SpecularScreenReflectance}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateProfileDisplayIdentifiers: Display SupportedColorSpace = {displayDDCInfo2.SupportedColorSpace}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateProfileDisplayIdentifiers: Display SupportedHDR = {displayDDCInfo2.SupportedHDR}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateProfileDisplayIdentifiers: Display SupportedTransferFunction = {displayDDCInfo2.SupportedTransferFunction}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateProfileDisplayIdentifiers: Display SupportsDDC = {displayDDCInfo2.SupportsDDC}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateProfileDisplayIdentifiers: Display DDCInfoFlag Digital Device = {DDCInfoFlag.DIGITALDEVICE}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateProfileDisplayIdentifiers: Display DDCInfoFlag EDID Extension = {DDCInfoFlag.EDIDEXTENSION}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateProfileDisplayIdentifiers: Display DDCInfoFlag HDMI Audio Device = {DDCInfoFlag.HDMIAUDIODEVICE}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateProfileDisplayIdentifiers: Display DDCInfoFlag Projector Device = {DDCInfoFlag.PROJECTORDEVICE}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateProfileDisplayIdentifiers: Display DDCInfoFlag Supports AI = {DDCInfoFlag.SUPPORTS_AI}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateProfileDisplayIdentifiers: Display DDCInfoFlag Supports xvYCC601 = {DDCInfoFlag.SUPPORT_xvYCC601}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateProfileDisplayIdentifiers: Display DDCInfoFlag Supports xvYCC709 = {DDCInfoFlag.SUPPORT_xvYCC709}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateProfileDisplayIdentifiers: Display SupportedHDR Supports CEA861_3 = {supportedHDR.CEA861_3}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateProfileDisplayIdentifiers: Display SupportedHDR Supports DOLBYVISION = {supportedHDR.DOLBYVISION}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateProfileDisplayIdentifiers: Display SupportedHDR Supports FREESYNC_HDR = {supportedHDR.FREESYNC_HDR}"); - } - else - { - SharedLogger.logger.Warn($"NVIDIALibrary/GenerateProfileDisplayIdentifiers: Error running ADL2_Display_DDCInfo2_Get on Display #{oneDisplayInfo.DisplayID.DisplayLogicalIndex} on Adapter #{oneAdapter.AdapterIndex}: {ADL.ConvertADLReturnValueIntoWords(ADLRet)}"); - } - } - - int HDRSupported = 0; - int HDREnabled = 0; - if (ADL.ADL2_Display_HDRState_Get != null) - { - // Get the HDR State from the Display - ADLRet = ADL.ADL2_Display_HDRState_Get(_adlContextHandle, oneAdapter.AdapterIndex, oneDisplayInfo.DisplayID, out HDRSupported, out HDREnabled); - if (ADLRet == ADL.ADL_OK) - { - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateProfileDisplayIdentifiers: ### Display HDR State for Display #{oneDisplayInfo.DisplayID.DisplayLogicalIndex} on Adapter #{oneAdapter.AdapterIndex} ###"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateProfileDisplayIdentifiers: Display HDR Supported = {HDRSupported}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateProfileDisplayIdentifiers: Display HDR Enabled = {HDREnabled}"); - } - else - { - SharedLogger.logger.Warn($"NVIDIALibrary/GenerateProfileDisplayIdentifiers: Error running ADL2_Display_HDRState_Get on Display #{oneDisplayInfo.DisplayID.DisplayLogicalIndex} on Adapter #{oneAdapter.AdapterIndex}: {ADL.ConvertADLReturnValueIntoWords(ADLRet)}"); - } - } - - - // Create an array of all the important display info we need to record - List displayInfoIdentifierSection = new List(); - displayInfoIdentifierSection.Add("NVIDIA"); - try - { - displayInfoIdentifierSection.Add(oneAdapter.VendorID.ToString()); - } - catch (Exception ex) - { - SharedLogger.logger.Warn(ex, $"NVIDIALibrary/GenerateProfileDisplayIdentifiers: Exception getting NVIDIA Vendor ID from video card. Substituting with a # instead"); - displayInfoIdentifierSection.Add("#"); - } - - try - { - displayInfoIdentifierSection.Add(oneAdapter.AdapterName); - } - catch (Exception ex) - { - SharedLogger.logger.Warn(ex, $"NVIDIALibrary/GenerateProfileDisplayIdentifiers: Exception getting NVIDIA Adapter Name from video card. Substituting with a # instead"); - displayInfoIdentifierSection.Add("#"); - } - - try - { - displayInfoIdentifierSection.Add(oneAdapter.VendorID.ToString()); - } - catch (Exception ex) - { - SharedLogger.logger.Warn(ex, $"NVIDIALibrary/GenerateProfileDisplayIdentifiers: Exception getting NVIDIA VendorID from video card. Substituting with a # instead"); - displayInfoIdentifierSection.Add("1002"); - } - - try - { - displayInfoIdentifierSection.Add(AdapterCapabilities.AdapterID.ToString()); - } - catch (Exception ex) - { - SharedLogger.logger.Warn(ex, $"NVIDIALibrary/GenerateProfileDisplayIdentifiers: Exception getting NVIDIA AdapterID from video card. Substituting with a # instead"); - displayInfoIdentifierSection.Add("#"); - } - - try - { - displayInfoIdentifierSection.Add(displayConnector.ToString("G")); - } - catch (Exception ex) - { - SharedLogger.logger.Warn(ex, $"NVIDIALibrary/GenerateProfileDisplayIdentifiers: Exception getting NVIDIA Display Connector from video card to display. Substituting with a # instead"); - displayInfoIdentifierSection.Add("#"); - } - - try - { - displayInfoIdentifierSection.Add(oneDisplayInfo.DisplayName); - } - catch (Exception ex) - { - SharedLogger.logger.Warn(ex, $"NVIDIALibrary/GenerateProfileDisplayIdentifiers: Exception getting Display Name from display connected to NVIDIA video card. Substituting with a # instead"); - displayInfoIdentifierSection.Add("#"); - } - - try - { - displayInfoIdentifierSection.Add(displayDDCInfo2.ManufacturerID.ToString()); - } - catch (Exception ex) - { - SharedLogger.logger.Warn(ex, $"NVIDIALibrary/GenerateProfileDisplayIdentifiers: Exception getting Manufacturer ID from display connected to NVIDIA video card. Substituting with a # instead"); - displayInfoIdentifierSection.Add("#"); - } - - try - { - displayInfoIdentifierSection.Add(displayDDCInfo2.ProductID.ToString()); - } - catch (Exception ex) - { - SharedLogger.logger.Warn(ex, $"NVIDIALibrary/GenerateProfileDisplayIdentifiers: Exception getting Product ID from display connected to NVIDIA video card. Substituting with a # instead"); - displayInfoIdentifierSection.Add("#"); - } - - try - { - displayInfoIdentifierSection.Add(displayDDCInfo2.SerialID.ToString()); - } - catch (Exception ex) - { - SharedLogger.logger.Warn(ex, $"NVIDIALibrary/GenerateProfileDisplayIdentifiers: Exception getting Serial ID from display connected to NVIDIA video card. Substituting with a # instead"); - displayInfoIdentifierSection.Add("#"); - } - - // Create a display identifier out of it - string displayIdentifier = String.Join("|", displayInfoIdentifierSection); - - // Check first to see if there is already an existing display identifier the same! - // This appears to be a bug with the NVIDIA driver, or with the install on my test machine - // Either way, it is potentially going to happen in the wild, so I will filter it out if it does - if (displayIdentifiers.Contains(displayIdentifier)) - { - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateProfileDisplayIdentifiers: Your NVIDIA driver reported the following Display Identifier multiple times, so ignoring it as we already have it: {displayIdentifier}"); - continue; - } - - // Add it to the list of display identifiers so we can return it - displayIdentifiers.Add(displayIdentifier); - - SharedLogger.logger.Debug($"ProfileRepository/GenerateProfileDisplayIdentifiers: DisplayIdentifier: {displayIdentifier}"); - } - } - catch (Exception ex) - { - SharedLogger.logger.Warn(ex, $"ProfileRepository/GenerateProfileDisplayIdentifiers: Exception caused trying to access attached displays"); - continue; - } - } - else - { - SharedLogger.logger.Warn($"NVIDIALibrary/GenerateProfileDisplayIdentifiers: Error running ADL2_Display_DisplayInfo_Get on Adapter #{oneAdapter.AdapterIndex}: {ADL.ConvertADLReturnValueIntoWords(ADLRet)}"); - } - // Release the memory for the DisplayInfo structure - if (IntPtr.Zero != DisplayBuffer) - Marshal.FreeCoTaskMem(DisplayBuffer); - } - } - else - { - SharedLogger.logger.Warn($"NVIDIALibrary/GenerateProfileDisplayIdentifiers: Error running ADL2_Adapter_Active_Get on Adapter #{oneAdapter.AdapterIndex}: {ADL.ConvertADLReturnValueIntoWords(ADLRet)}"); - } - } - } - else - { - SharedLogger.logger.Warn($"NVIDIALibrary/GenerateProfileDisplayIdentifiers: Error running ADL2_Adapter_AdapterInfoX4_Get on NVIDIA Video card: {ADL.ConvertADLReturnValueIntoWords(ADLRet)}"); - } - } - // Release the memory for the AdapterInfo structure - if (IntPtr.Zero != AdapterBuffer) - { - Marshal.FreeCoTaskMem(AdapterBuffer); - } - - // Return all the identifiers we've found - return displayIdentifiers; + // We want to get the Windows CCD information and store it for later so that we record + // display sizes, and screen positions and the like. + //myDisplayConfig.WindowsDisplayConfig = _winLibrary.GetActiveConfig(); } else { - SharedLogger.logger.Warn($"NVIDIALibrary/GenerateProfileDisplayIdentifiers: There were no NVIDIA adapters found by NVIDIA ADL."); - return null; + SharedLogger.logger.Error($"NVIDIALibrary/GetNVIDIADisplayConfig: ERROR - Tried to run GetNVIDIADisplayConfig but the NVIDIA ADL library isn't initialised!"); + throw new NVIDIALibraryException($"Tried to run GetNVIDIADisplayConfig but the NVIDIA ADL library isn't initialised!"); } + + // Return the configuration + return myDisplayConfig; } - public List GenerateAllAvailableDisplayIdentifiers() + + public string PrintActiveConfig() { - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: Getting NVIDIA active adapter count"); + string stringToReturn = ""; - int ADLRet = ADL.ADL_ERR; - int NumberOfAdapters = 0; - - List displayIdentifiers = new List(); - - if (null != ADL.ADL2_Adapter_NumberOfAdapters_Get) + // Get the size of the largest Active Paths and Modes arrays + int pathCount = 0; + int modeCount = 0; + WIN32STATUS err = CCDImport.GetDisplayConfigBufferSizes(QDC.QDC_ONLY_ACTIVE_PATHS, out pathCount, out modeCount); + if (err != WIN32STATUS.ERROR_SUCCESS) { - ADL.ADL2_Adapter_NumberOfAdapters_Get(_adlContextHandle, ref NumberOfAdapters); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: Number Of Adapters: {NumberOfAdapters.ToString()} "); + SharedLogger.logger.Error($"NVIDIALibrary/PrintActiveConfig: ERROR - GetDisplayConfigBufferSizes returned WIN32STATUS {err} when trying to get the maximum path and mode sizes"); + throw new NVIDIALibraryException($"GetDisplayConfigBufferSizes returned WIN32STATUS {err} when trying to get the maximum path and mode sizes"); } - if (NumberOfAdapters > 0) + SharedLogger.logger.Trace($"NVIDIALibrary/PrintActiveConfig: Getting the current Display Config path and mode arrays"); + var paths = new DISPLAYCONFIG_PATH_INFO[pathCount]; + var modes = new DISPLAYCONFIG_MODE_INFO[modeCount]; + err = CCDImport.QueryDisplayConfig(QDC.QDC_ONLY_ACTIVE_PATHS, ref pathCount, paths, ref modeCount, modes, IntPtr.Zero); + if (err == WIN32STATUS.ERROR_INSUFFICIENT_BUFFER) + { + SharedLogger.logger.Warn($"NVIDIALibrary/PrintActiveConfig: The displays were modified between GetDisplayConfigBufferSizes and QueryDisplayConfig so we need to get the buffer sizes again."); + SharedLogger.logger.Trace($"NVIDIALibrary/PrintActiveConfig: Getting the size of the largest Active Paths and Modes arrays"); + // Screen changed in between GetDisplayConfigBufferSizes and QueryDisplayConfig, so we need to get buffer sizes again + // as per https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-querydisplayconfig + err = CCDImport.GetDisplayConfigBufferSizes(QDC.QDC_ONLY_ACTIVE_PATHS, out pathCount, out modeCount); + if (err != WIN32STATUS.ERROR_SUCCESS) + { + SharedLogger.logger.Error($"NVIDIALibrary/PrintActiveConfig: ERROR - GetDisplayConfigBufferSizes returned WIN32STATUS {err} when trying to get the maximum path and mode sizes again"); + throw new NVIDIALibraryException($"GetDisplayConfigBufferSizes returned WIN32STATUS {err} when trying to get the maximum path and mode sizes again"); + } + SharedLogger.logger.Trace($"NVIDIALibrary/PrintActiveConfig: Getting the current Display Config path and mode arrays"); + paths = new DISPLAYCONFIG_PATH_INFO[pathCount]; + modes = new DISPLAYCONFIG_MODE_INFO[modeCount]; + err = CCDImport.QueryDisplayConfig(QDC.QDC_ONLY_ACTIVE_PATHS, ref pathCount, paths, ref modeCount, modes, IntPtr.Zero); + if (err == WIN32STATUS.ERROR_INSUFFICIENT_BUFFER) + { + SharedLogger.logger.Error($"NVIDIALibrary/PrintActiveConfig: ERROR - The displays were still modified between GetDisplayConfigBufferSizes and QueryDisplayConfig, even though we tried twice. Something is wrong."); + throw new NVIDIALibraryException($"The displays were still modified between GetDisplayConfigBufferSizes and QueryDisplayConfig, even though we tried twice. Something is wrong."); + } + else if (err != WIN32STATUS.ERROR_SUCCESS) + { + SharedLogger.logger.Error($"NVIDIALibrary/PrintActiveConfig: ERROR - QueryDisplayConfig returned WIN32STATUS {err} when trying to query all available displays again"); + throw new NVIDIALibraryException($"QueryDisplayConfig returned WIN32STATUS {err} when trying to query all available displays again."); + } + } + else if (err != WIN32STATUS.ERROR_SUCCESS) + { + SharedLogger.logger.Error($"NVIDIALibrary/PrintActiveConfig: ERROR - QueryDisplayConfig returned WIN32STATUS {err} when trying to query all available displays"); + throw new NVIDIALibraryException($"QueryDisplayConfig returned WIN32STATUS {err} when trying to query all available displays."); + } + + foreach (var path in paths) + { + stringToReturn += $"----++++==== Path ====++++----\n"; + + // get display source name + var sourceInfo = new DISPLAYCONFIG_SOURCE_DEVICE_NAME(); + sourceInfo.Header.Type = DISPLAYCONFIG_DEVICE_INFO_TYPE.DISPLAYCONFIG_DEVICE_INFO_GET_SOURCE_NAME; + sourceInfo.Header.Size = (uint)Marshal.SizeOf(); + sourceInfo.Header.AdapterId = path.SourceInfo.AdapterId; + sourceInfo.Header.Id = path.SourceInfo.Id; + err = CCDImport.DisplayConfigGetDeviceInfo(ref sourceInfo); + if (err == WIN32STATUS.ERROR_SUCCESS) + { + SharedLogger.logger.Trace($"NVIDIALibrary/PrintActiveConfig: Found Display Source {sourceInfo.ViewGdiDeviceName} for source {path.SourceInfo.Id}."); + stringToReturn += $"****** Interrogating Display Source {path.SourceInfo.Id} *******\n"; + stringToReturn += $"Found Display Source {sourceInfo.ViewGdiDeviceName}\n"; + stringToReturn += $"\n"; + } + else + { + SharedLogger.logger.Warn($"NVIDIALibrary/PrintActiveConfig: WARNING - DisplayConfigGetDeviceInfo returned WIN32STATUS {err} when trying to get the source info for source adapter #{path.SourceInfo.AdapterId}"); + } + + + // get display target name + var targetInfo = new DISPLAYCONFIG_TARGET_DEVICE_NAME(); + targetInfo.Header.Type = DISPLAYCONFIG_DEVICE_INFO_TYPE.DISPLAYCONFIG_DEVICE_INFO_GET_TARGET_NAME; + targetInfo.Header.Size = (uint)Marshal.SizeOf(); + targetInfo.Header.AdapterId = path.TargetInfo.AdapterId; + targetInfo.Header.Id = path.TargetInfo.Id; + err = CCDImport.DisplayConfigGetDeviceInfo(ref targetInfo); + if (err == WIN32STATUS.ERROR_SUCCESS) + { + SharedLogger.logger.Trace($"NVIDIALibrary/PrintActiveConfig: Connector Instance: {targetInfo.ConnectorInstance} for source {path.TargetInfo.Id}."); + SharedLogger.logger.Trace($"NVIDIALibrary/PrintActiveConfig: EDID Manufacturer ID: {targetInfo.EdidManufactureId} for source {path.TargetInfo.Id}."); + SharedLogger.logger.Trace($"NVIDIALibrary/PrintActiveConfig: EDID Product Code ID: {targetInfo.EdidProductCodeId} for source {path.TargetInfo.Id}."); + SharedLogger.logger.Trace($"NVIDIALibrary/PrintActiveConfig: Flags Friendly Name from EDID: {targetInfo.Flags.FriendlyNameFromEdid} for source {path.TargetInfo.Id}."); + SharedLogger.logger.Trace($"NVIDIALibrary/PrintActiveConfig: Flags Friendly Name Forced: {targetInfo.Flags.FriendlyNameForced} for source {path.TargetInfo.Id}."); + SharedLogger.logger.Trace($"NVIDIALibrary/PrintActiveConfig: Flags EDID ID is Valid: {targetInfo.Flags.EdidIdsValid} for source {path.TargetInfo.Id}."); + SharedLogger.logger.Trace($"NVIDIALibrary/PrintActiveConfig: Monitor Device Path: {targetInfo.MonitorDevicePath} for source {path.TargetInfo.Id}."); + SharedLogger.logger.Trace($"NVIDIALibrary/PrintActiveConfig: Monitor Friendly Device Name: {targetInfo.MonitorFriendlyDeviceName} for source {path.TargetInfo.Id}."); + SharedLogger.logger.Trace($"NVIDIALibrary/PrintActiveConfig: Output Technology: {targetInfo.OutputTechnology} for source {path.TargetInfo.Id}."); + + stringToReturn += $"****** Interrogating Display Target {targetInfo.MonitorFriendlyDeviceName} *******\n"; + stringToReturn += $" Connector Instance: {targetInfo.ConnectorInstance}\n"; + stringToReturn += $" EDID Manufacturer ID: {targetInfo.EdidManufactureId}\n"; + stringToReturn += $" EDID Product Code ID: {targetInfo.EdidProductCodeId}\n"; + stringToReturn += $" Flags Friendly Name from EDID: {targetInfo.Flags.FriendlyNameFromEdid}\n"; + stringToReturn += $" Flags Friendly Name Forced: {targetInfo.Flags.FriendlyNameForced}\n"; + stringToReturn += $" Flags EDID ID is Valid: {targetInfo.Flags.EdidIdsValid}\n"; + stringToReturn += $" Monitor Device Path: {targetInfo.MonitorDevicePath}\n"; + stringToReturn += $" Monitor Friendly Device Name: {targetInfo.MonitorFriendlyDeviceName}\n"; + stringToReturn += $" Output Technology: {targetInfo.OutputTechnology}\n"; + stringToReturn += $"\n"; + } + else + { + SharedLogger.logger.Warn($"NVIDIALibrary/PrintActiveConfig: WARNING - DisplayConfigGetDeviceInfo returned WIN32STATUS {err} when trying to get the target info for display #{path.TargetInfo.Id}"); + } + + + // get display adapter name + var adapterInfo = new DISPLAYCONFIG_ADAPTER_NAME(); + adapterInfo.Header.Type = DISPLAYCONFIG_DEVICE_INFO_TYPE.DISPLAYCONFIG_DEVICE_INFO_GET_ADAPTER_NAME; + adapterInfo.Header.Size = (uint)Marshal.SizeOf(); + adapterInfo.Header.AdapterId = path.TargetInfo.AdapterId; + adapterInfo.Header.Id = path.TargetInfo.Id; + err = CCDImport.DisplayConfigGetDeviceInfo(ref adapterInfo); + if (err == WIN32STATUS.ERROR_SUCCESS) + { + SharedLogger.logger.Trace($"NVIDIALibrary/PrintActiveConfig: Found Adapter Device Path {adapterInfo.AdapterDevicePath} for source {path.TargetInfo.AdapterId}."); + stringToReturn += $"****** Interrogating Display Adapter {adapterInfo.AdapterDevicePath} *******\n"; + stringToReturn += $" Display Adapter {adapterInfo.AdapterDevicePath}\n"; + stringToReturn += $"\n"; + } + else + { + SharedLogger.logger.Warn($"NVIDIALibrary/GetWindowsDisplayConfig: WARNING - DisplayConfigGetDeviceInfo returned WIN32STATUS {err} when trying to get the adapter device path for target #{path.TargetInfo.AdapterId}"); + } + + // get display target preferred mode + var targetPreferredInfo = new DISPLAYCONFIG_TARGET_PREFERRED_MODE(); + targetPreferredInfo.Header.Type = DISPLAYCONFIG_DEVICE_INFO_TYPE.DISPLAYCONFIG_DEVICE_INFO_GET_TARGET_PREFERRED_MODE; + targetPreferredInfo.Header.Size = (uint)Marshal.SizeOf(); + targetPreferredInfo.Header.AdapterId = path.TargetInfo.AdapterId; + targetPreferredInfo.Header.Id = path.TargetInfo.Id; + err = CCDImport.DisplayConfigGetDeviceInfo(ref targetPreferredInfo); + if (err == WIN32STATUS.ERROR_SUCCESS) + { + SharedLogger.logger.Trace($"NVIDIALibrary/GetWindowsDisplayConfig: Found Target Preferred Width {targetPreferredInfo.Width} for target {path.TargetInfo.Id}."); + SharedLogger.logger.Trace($"NVIDIALibrary/GetWindowsDisplayConfig: Found Target Preferred Height {targetPreferredInfo.Height} for target {path.TargetInfo.Id}."); + SharedLogger.logger.Trace($"NVIDIALibrary/GetWindowsDisplayConfig: Found Target Video Signal Info Active Size: ({targetPreferredInfo.TargetMode.TargetVideoSignalInfo.ActiveSize.Cx}x{targetPreferredInfo.TargetMode.TargetVideoSignalInfo.ActiveSize.Cy} for target {path.TargetInfo.Id}."); + SharedLogger.logger.Trace($"NVIDIALibrary/GetWindowsDisplayConfig: Found Target Video Signal Info Total Size: ({targetPreferredInfo.TargetMode.TargetVideoSignalInfo.TotalSize.Cx}x{targetPreferredInfo.TargetMode.TargetVideoSignalInfo.TotalSize.Cy} for target {path.TargetInfo.Id}."); + SharedLogger.logger.Trace($"NVIDIALibrary/GetWindowsDisplayConfig: Found Target Video Signal Info HSync Frequency: {targetPreferredInfo.TargetMode.TargetVideoSignalInfo.HSyncFreq} for target {path.TargetInfo.Id}."); + SharedLogger.logger.Trace($"NVIDIALibrary/GetWindowsDisplayConfig: Found Target Video Signal Info VSync Frequency: {targetPreferredInfo.TargetMode.TargetVideoSignalInfo.VSyncFreq} for target {path.TargetInfo.Id}."); + SharedLogger.logger.Trace($"NVIDIALibrary/GetWindowsDisplayConfig: Found Target Video Signal Info Pixel Rate: {targetPreferredInfo.TargetMode.TargetVideoSignalInfo.PixelRate} for target {path.TargetInfo.Id}."); + SharedLogger.logger.Trace($"NVIDIALibrary/GetWindowsDisplayConfig: Found Target Video Signal Info Scan Line Ordering: {targetPreferredInfo.TargetMode.TargetVideoSignalInfo.ScanLineOrdering} for target {path.TargetInfo.Id}."); + SharedLogger.logger.Trace($"NVIDIALibrary/GetWindowsDisplayConfig: Found Target Video Signal Info Video Standard: {targetPreferredInfo.TargetMode.TargetVideoSignalInfo.VideoStandard} for target {path.TargetInfo.Id}."); + + stringToReturn += $"****** Interrogating Target Preferred Mode for Display {path.TargetInfo.Id} *******\n"; + stringToReturn += $" Target Preferred Width {targetPreferredInfo.Width} for target {path.TargetInfo.Id}\n"; + stringToReturn += $" Target Preferred Height {targetPreferredInfo.Height} for target {path.TargetInfo.Id}\n"; + stringToReturn += $" Target Video Signal Info Active Size: ({targetPreferredInfo.TargetMode.TargetVideoSignalInfo.ActiveSize.Cx}x{targetPreferredInfo.TargetMode.TargetVideoSignalInfo.ActiveSize.Cy}\n"; + stringToReturn += $" Target Video Signal Info Total Size: ({targetPreferredInfo.TargetMode.TargetVideoSignalInfo.TotalSize.Cx}x{targetPreferredInfo.TargetMode.TargetVideoSignalInfo.TotalSize.Cy}\n"; + stringToReturn += $" Target Video Signal Info HSync Frequency: {targetPreferredInfo.TargetMode.TargetVideoSignalInfo.HSyncFreq}\n"; + stringToReturn += $" Target Video Signal Info VSync Frequency: {targetPreferredInfo.TargetMode.TargetVideoSignalInfo.VSyncFreq}\n"; + stringToReturn += $" Target Video Signal Info Pixel Rate: {targetPreferredInfo.TargetMode.TargetVideoSignalInfo.PixelRate}\n"; + stringToReturn += $" Target Video Signal Info Scan Line Ordering: {targetPreferredInfo.TargetMode.TargetVideoSignalInfo.ScanLineOrdering}\n"; + stringToReturn += $" Target Video Signal Info Video Standard: {targetPreferredInfo.TargetMode.TargetVideoSignalInfo.VideoStandard}\n"; + stringToReturn += $"\n"; + } + else + { + SharedLogger.logger.Warn($"NVIDIALibrary/GetWindowsDisplayConfig: WARNING - DisplayConfigGetDeviceInfo returned WIN32STATUS {err} when trying to get the preferred target name for display #{path.TargetInfo.Id}"); + } + + // get display target base type + var targetBaseTypeInfo = new DISPLAYCONFIG_TARGET_BASE_TYPE(); + targetBaseTypeInfo.Header.Type = DISPLAYCONFIG_DEVICE_INFO_TYPE.DISPLAYCONFIG_DEVICE_INFO_GET_TARGET_BASE_TYPE; + targetBaseTypeInfo.Header.Size = (uint)Marshal.SizeOf(); + targetBaseTypeInfo.Header.AdapterId = path.TargetInfo.AdapterId; + targetBaseTypeInfo.Header.Id = path.TargetInfo.Id; + err = CCDImport.DisplayConfigGetDeviceInfo(ref targetBaseTypeInfo); + if (err == WIN32STATUS.ERROR_SUCCESS) + { + SharedLogger.logger.Trace($"NVIDIALibrary/GetWindowsDisplayConfig: Found Virtual Resolution is Disabled: {targetBaseTypeInfo.BaseOutputTechnology} for target {path.TargetInfo.Id}."); + + stringToReturn += $"****** Interrogating Target Base Type for Display {path.TargetInfo.Id} *******\n"; + stringToReturn += $" Base Output Technology: {targetBaseTypeInfo.BaseOutputTechnology}\n"; + stringToReturn += $"\n"; + } + else + { + SharedLogger.logger.Warn($"NVIDIALibrary/GetWindowsDisplayConfig: WARNING - DisplayConfigGetDeviceInfo returned WIN32STATUS {err} when trying to get the target base type for display #{path.TargetInfo.Id}"); + } + + // get display support virtual resolution + var supportVirtResInfo = new DISPLAYCONFIG_SUPPORT_VIRTUAL_RESOLUTION(); + supportVirtResInfo.Header.Type = DISPLAYCONFIG_DEVICE_INFO_TYPE.DISPLAYCONFIG_DEVICE_INFO_GET_SUPPORT_VIRTUAL_RESOLUTION; + supportVirtResInfo.Header.Size = (uint)Marshal.SizeOf(); + supportVirtResInfo.Header.AdapterId = path.TargetInfo.AdapterId; + supportVirtResInfo.Header.Id = path.TargetInfo.Id; + err = CCDImport.DisplayConfigGetDeviceInfo(ref supportVirtResInfo); + if (err == WIN32STATUS.ERROR_SUCCESS) + { + SharedLogger.logger.Trace($"NVIDIALibrary/GetWindowsDisplayConfig: Found Base Output Technology: {supportVirtResInfo.IsMonitorVirtualResolutionDisabled} for target {path.TargetInfo.Id}."); + stringToReturn += $"****** Interrogating Target Supporting virtual resolution for Display {path.TargetInfo.Id} *******\n"; + stringToReturn += $" Virtual Resolution is Disabled: {supportVirtResInfo.IsMonitorVirtualResolutionDisabled}\n"; + stringToReturn += $"\n"; + } + else + { + SharedLogger.logger.Warn($"NVIDIALibrary/GetWindowsDisplayConfig: WARNING - DisplayConfigGetDeviceInfo returned WIN32STATUS {err} when trying to find out the virtual resolution support for display #{path.TargetInfo.Id}"); + } + + //get advanced color info + var colorInfo = new DISPLAYCONFIG_GET_ADVANCED_COLOR_INFO(); + colorInfo.Header.Type = DISPLAYCONFIG_DEVICE_INFO_TYPE.DISPLAYCONFIG_DEVICE_INFO_GET_ADVANCED_COLOR_INFO; + colorInfo.Header.Size = (uint)Marshal.SizeOf(); + colorInfo.Header.AdapterId = path.TargetInfo.AdapterId; + colorInfo.Header.Id = path.TargetInfo.Id; + err = CCDImport.DisplayConfigGetDeviceInfo(ref colorInfo); + if (err == WIN32STATUS.ERROR_SUCCESS) + { + SharedLogger.logger.Trace($"NVIDIALibrary/GetWindowsDisplayConfig: Found Advanced Color Supported: {colorInfo.AdvancedColorSupported} for target {path.TargetInfo.Id}."); + SharedLogger.logger.Trace($"NVIDIALibrary/GetWindowsDisplayConfig: Found Advanced Color Enabled: {colorInfo.AdvancedColorEnabled} for target {path.TargetInfo.Id}."); + SharedLogger.logger.Trace($"NVIDIALibrary/GetWindowsDisplayConfig: Found Advanced Color Force Disabled: {colorInfo.AdvancedColorForceDisabled} for target {path.TargetInfo.Id}."); + SharedLogger.logger.Trace($"NVIDIALibrary/GetWindowsDisplayConfig: Found Bits per Color Channel: {colorInfo.BitsPerColorChannel} for target {path.TargetInfo.Id}."); + SharedLogger.logger.Trace($"NVIDIALibrary/GetWindowsDisplayConfig: Found Color Encoding: {colorInfo.ColorEncoding} for target {path.TargetInfo.Id}."); + SharedLogger.logger.Trace($"NVIDIALibrary/GetWindowsDisplayConfig: Found Wide Color Enforced: {colorInfo.WideColorEnforced} for target {path.TargetInfo.Id}."); + + stringToReturn += $"****** Interrogating Advanced Color Info for Display {path.TargetInfo.Id} *******\n"; + stringToReturn += $" Advanced Color Supported: {colorInfo.AdvancedColorSupported}\n"; + stringToReturn += $" Advanced Color Enabled: {colorInfo.AdvancedColorEnabled}\n"; + stringToReturn += $" Advanced Color Force Disabled: {colorInfo.AdvancedColorForceDisabled}\n"; + stringToReturn += $" Bits per Color Channel: {colorInfo.BitsPerColorChannel}\n"; + stringToReturn += $" Color Encoding: {colorInfo.ColorEncoding}\n"; + stringToReturn += $" Wide Color Enforced: {colorInfo.WideColorEnforced}\n"; + stringToReturn += $"\n"; + } + else + { + SharedLogger.logger.Warn($"NVIDIALibrary/GetWindowsDisplayConfig: WARNING - DisplayConfigGetDeviceInfo returned WIN32STATUS {err} when trying to find out the virtual resolution support for display #{path.TargetInfo.Id}"); + } + + // get SDR white levels + var whiteLevelInfo = new DISPLAYCONFIG_SDR_WHITE_LEVEL(); + whiteLevelInfo.Header.Type = DISPLAYCONFIG_DEVICE_INFO_TYPE.DISPLAYCONFIG_DEVICE_INFO_GET_SDR_WHITE_LEVEL; + whiteLevelInfo.Header.Size = (uint)Marshal.SizeOf(); + whiteLevelInfo.Header.AdapterId = path.TargetInfo.AdapterId; + whiteLevelInfo.Header.Id = path.TargetInfo.Id; + err = CCDImport.DisplayConfigGetDeviceInfo(ref whiteLevelInfo); + if (err == WIN32STATUS.ERROR_SUCCESS) + { + SharedLogger.logger.Trace($"NVIDIALibrary/GetWindowsDisplayConfig: Found SDR White Level: {whiteLevelInfo.SDRWhiteLevel} for target {path.TargetInfo.Id}."); + + stringToReturn += $"****** Interrogating SDR Whilte Level for Display {path.TargetInfo.Id} *******\n"; + stringToReturn += $" SDR White Level: {whiteLevelInfo.SDRWhiteLevel}\n"; + stringToReturn += $"\n"; + } + else + { + SharedLogger.logger.Warn($"NVIDIALibrary/GetWindowsDisplayConfig: WARNING - DisplayConfigGetDeviceInfo returned WIN32STATUS {err} when trying to find out the SDL white level for display #{path.TargetInfo.Id}"); + } + } + return stringToReturn; + } + + public bool SetActiveConfig(NVIDIA_DISPLAY_CONFIG displayConfig) + { + + if (_initialised) { - IntPtr AdapterBuffer = IntPtr.Zero; - if (ADL.ADL2_Adapter_AdapterInfoX4_Get != null) + NVAPI_STATUS NVStatus = 0; + // We want to get the current config + //NVIDIA_DISPLAY_CONFIG currentDisplayConfig = GetNVIDIADisplayConfig(QDC.QDC_ALL_PATHS); + + // We want to check the NVIDIA Eyefinity (SLS) config is valid + SharedLogger.logger.Trace($"NVIDIALibrary/SetActiveConfig: Testing whether the display configuration is valid"); + //ADL2_Display_SLSMapConfig_Valid(ADL_CONTEXT_HANDLE context, int iAdapterIndex, ADLSLSMap slsMap, int iNumDisplayTarget, ADLSLSTarget * lpSLSTarget, int * lpSupportedSLSLayoutImageMode, int * lpReasonForNotSupportSLS, int iOption) + foreach (var adapter in displayConfig.AdapterConfigs) { - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: ADL2_Adapter_AdapterInfoX4_Get DLL function exists."); - - // Get the Adapter info and put it in the AdapterBuffer - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: Running ADL2_Adapter_AdapterInfoX4_Get to find all known NVIDIA adapters."); - //ADLRet = ADL.ADL2_Adapter_AdapterInfoX4_Get(_adlContextHandle, AdapterBuffer, size); - int numAdapters = 0; - ADLRet = ADL.ADL2_Adapter_AdapterInfoX4_Get(_adlContextHandle, ADL.ADL_ADAPTER_INDEX_ALL, out numAdapters, out AdapterBuffer); - if (ADLRet == ADL.ADL_OK) + // set the display locations + if (adapter.IsSLSEnabled) { - - int IsActive = ADL.ADL_TRUE; // We only want to search for active adapters - - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: Successfully run ADL2_Adapter_AdapterInfoX4_Get to find information about all known NVIDIA adapters."); - - ADLAdapterInfoX2 oneAdapter = new ADLAdapterInfoX2(); - // Go through each adapter - for (int adapterLoop = 0; adapterLoop < numAdapters; adapterLoop++) + // Turn the SLS based display map on + //NVStatus = NVImport.ADL2_Display_SLSMapConfig_SetState(_adlContextHandle, adapter.AdapterIndex, adapter.SLSMapIndex, NVImport.ADL_TRUE); + if (NVStatus == NVAPI_STATUS.NVAPI_OK) { - oneAdapter = (ADLAdapterInfoX2)Marshal.PtrToStructure(new IntPtr(AdapterBuffer.ToInt64() + (adapterLoop * Marshal.SizeOf(oneAdapter))), oneAdapter.GetType()); - - if (oneAdapter.Exist != 1) - { - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: NVIDIA Adapter #{oneAdapter.AdapterIndex.ToString()} doesn't exist at present so skipping detection for this adapter."); - continue; - } - - if (oneAdapter.Present != 1) - { - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: NVIDIA Adapter #{oneAdapter.AdapterIndex.ToString()} isn't enabled at present so skipping detection for this adapter."); - continue; - } - - // Check if the adapter is active - if (ADL.ADL2_Adapter_Active_Get != null) - ADLRet = ADL.ADL2_Adapter_Active_Get(_adlContextHandle, oneAdapter.AdapterIndex, ref IsActive); - - if (ADLRet == ADL.ADL_OK) - { - // Only continue if the adapter is enabled - if (IsActive != ADL.ADL_TRUE) - { - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: NVIDIA Adapter #{oneAdapter.AdapterIndex.ToString()} isn't active ({oneAdapter.AdapterName})."); - continue; - } - - // Only continue if the adapter index is > 0 - if (oneAdapter.AdapterIndex < 0) - { - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: NVIDIA Adapter has an adapter index of {oneAdapter.AdapterIndex.ToString()} which indicates it is not a real adapter."); - continue; - } - - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: NVIDIA Adapter #{oneAdapter.AdapterIndex.ToString()} is active! ({oneAdapter.AdapterName})."); - - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: ### Adapter Info for Adapter #{oneAdapter.AdapterIndex} ###"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: Adapter AdapterIndex = {oneAdapter.AdapterIndex}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: Adapter AdapterName = {oneAdapter.AdapterName}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: Adapter BusNumber = {oneAdapter.BusNumber}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: Adapter DeviceNumber = {oneAdapter.DeviceNumber}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: Adapter DisplayName = {oneAdapter.DisplayName}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: Adapter DriverPath = {oneAdapter.DriverPath}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: Adapter DriverPathExt = {oneAdapter.DriverPathExt}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: Adapter Exist = {oneAdapter.Exist}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: Adapter FunctionNumber = {oneAdapter.FunctionNumber}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: Adapter InfoMask = {oneAdapter.InfoMask}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: Adapter InfoValue = {oneAdapter.InfoValue}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: Adapter OSDisplayIndex = {oneAdapter.OSDisplayIndex}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: Adapter PNPString = {oneAdapter.PNPString}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: Adapter Present = {oneAdapter.Present}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: Adapter Size = {oneAdapter.Size}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: Adapter UDID = {oneAdapter.UDID}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: Adapter VendorID = {oneAdapter.VendorID}"); - - // Get the Adapter Capabilities - ADLAdapterCapsX2 AdapterCapabilities = new ADLAdapterCapsX2(); - if (ADL.ADL2_AdapterX2_Caps != null) - { - ADLRet = ADL.ADL2_AdapterX2_Caps(_adlContextHandle, oneAdapter.AdapterIndex, out AdapterCapabilities); - } - - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: ### Adapter Capabilities for Adapter #{oneAdapter.AdapterIndex} ###"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: Adapter ID = {AdapterCapabilities.AdapterID}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: Adapter Capabilities Mask = {AdapterCapabilities.CapsMask}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: Adapter Capabilities Value = {AdapterCapabilities.CapsValue}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: Adapter Num of Connectors = {AdapterCapabilities.NumConnectors}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: Adapter Num of Controllers = {AdapterCapabilities.NumControllers}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: Adapter Num of Displays = {AdapterCapabilities.NumDisplays}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: Adapter Num of GL Sync Connectors = {AdapterCapabilities.NumOfGLSyncConnectors}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: Adapter Num of Overlays = {AdapterCapabilities.NumOverlays}"); - - if (ADL.ADL2_Display_DisplayInfo_Get != null) - { - IntPtr DisplayBuffer = IntPtr.Zero; - int numDisplays = 0; - // Force the display detection and get the Display Info. Use 0 as last parameter to NOT force detection - ADLRet = ADL.ADL2_Display_DisplayInfo_Get(_adlContextHandle, oneAdapter.AdapterIndex, ref numDisplays, out DisplayBuffer, 1); - if (ADLRet == ADL.ADL_OK) - { - - try - { - ADLDisplayInfo oneDisplayInfo = new ADLDisplayInfo(); - - for (int displayLoop = 0; displayLoop < numDisplays; displayLoop++) - { - oneDisplayInfo = (ADLDisplayInfo)Marshal.PtrToStructure(new IntPtr(DisplayBuffer.ToInt64() + (displayLoop * Marshal.SizeOf(oneDisplayInfo))), oneDisplayInfo.GetType()); - - // Is the display mapped to this adapter? If not we skip it! - if (oneDisplayInfo.DisplayID.DisplayLogicalAdapterIndex != oneAdapter.AdapterIndex) - { - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: NVIDIA Adapter #{oneAdapter.AdapterIndex.ToString()} ({oneAdapter.AdapterName}) AdapterID display ID#{oneDisplayInfo.DisplayID.DisplayLogicalIndex} is not a real display as its DisplayID.DisplayLogicalAdapterIndex is -1"); - continue; - } - - // Convert the displayInfoValue to something usable using a library function I made - ConvertedDisplayInfoValue displayInfoValue = ADL.ConvertDisplayInfoValue(oneDisplayInfo.DisplayInfoValue); - - // Is the display mapped to this adapter? If not we skip it! - if (!displayInfoValue.DISPLAYCONNECTED) - { - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: NVIDIA Adapter #{oneAdapter.AdapterIndex.ToString()} ({oneAdapter.AdapterName}) AdapterID display ID#{oneDisplayInfo.DisplayID.DisplayLogicalIndex} is not connected"); - continue; - } - - // We want connected displays whether they are mapped or not mapped in Windows OS - - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: NVIDIA Adapter #{oneAdapter.AdapterIndex.ToString()} ({oneAdapter.AdapterName}) AdapterID display ID#{oneDisplayInfo.DisplayID.DisplayLogicalIndex} is connected and mapped in Windows OS"); - - ADL.ADLDisplayConnectionType displayConnector = (ADL.ADLDisplayConnectionType)oneDisplayInfo.DisplayConnector; - - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: ### Display Info for Display #{oneDisplayInfo.DisplayID.DisplayLogicalIndex} on Adapter #{oneAdapter.AdapterIndex} ###"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: Display Connector = {displayConnector.ToString("G")}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: Display Controller Index = {oneDisplayInfo.DisplayControllerIndex}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: Display Logical Adapter Index = {oneDisplayInfo.DisplayID.DisplayLogicalAdapterIndex}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: Display Logical Index = {oneDisplayInfo.DisplayID.DisplayLogicalIndex}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: Display Physical Adapter Index = {oneDisplayInfo.DisplayID.DisplayPhysicalAdapterIndex}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: Display Physical Index = {oneDisplayInfo.DisplayID.DisplayPhysicalIndex}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: Display Info Mask = {oneDisplayInfo.DisplayInfoMask}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: Display Info Value = {oneDisplayInfo.DisplayInfoValue}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: Display Manufacturer Name = {oneDisplayInfo.DisplayManufacturerName}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: Display Name = {oneDisplayInfo.DisplayName}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: Display Output Type = {oneDisplayInfo.DisplayOutputType}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: Display Type = {oneDisplayInfo.DisplayType}"); - - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: Display Info Value DISPLAYCONNECTED = {displayInfoValue.DISPLAYCONNECTED}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: Display Info Value DISPLAYMAPPED = {displayInfoValue.DISPLAYMAPPED}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: Display Info Value FORCIBLESUPPORTED = {displayInfoValue.FORCIBLESUPPORTED}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: Display Info Value GENLOCKSUPPORTED = {displayInfoValue.GENLOCKSUPPORTED}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: Display Info Value LDA_DISPLAY = {displayInfoValue.LDA_DISPLAY}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: Display Info Value MANNER_SUPPORTED_2HSTRETCH = {displayInfoValue.MANNER_SUPPORTED_2HSTRETCH}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: Display Info Value MANNER_SUPPORTED_2VSTRETCH = {displayInfoValue.MANNER_SUPPORTED_2VSTRETCH}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: Display Info Value MANNER_SUPPORTED_CLONE = {displayInfoValue.MANNER_SUPPORTED_CLONE}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: Display Info Value MANNER_SUPPORTED_EXTENDED = {displayInfoValue.MANNER_SUPPORTED_EXTENDED}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: Display Info Value MANNER_SUPPORTED_NSTRETCH1GPU = {displayInfoValue.MANNER_SUPPORTED_NSTRETCH1GPU}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: Display Info Value MANNER_SUPPORTED_NSTRETCHNGPU = {displayInfoValue.MANNER_SUPPORTED_NSTRETCHNGPU}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: Display Info Value MANNER_SUPPORTED_SINGLE = {displayInfoValue.MANNER_SUPPORTED_SINGLE}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: Display Info Value MODETIMING_OVERRIDESSUPPORTED = {displayInfoValue.MODETIMING_OVERRIDESSUPPORTED}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: Display Info Value MULTIVPU_SUPPORTED = {displayInfoValue.MULTIVPU_SUPPORTED}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: Display Info Value NONLOCAL = {displayInfoValue.NONLOCAL}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: Display Info Value SHOWTYPE_PROJECTOR = {displayInfoValue.SHOWTYPE_PROJECTOR}"); - - ADL.ADLDisplayConnectionType displayConnectionType = ADL.ADLDisplayConnectionType.Unknown; - ADLDisplayConfig displayConfig = new ADLDisplayConfig(); - displayConfig.Size = Marshal.SizeOf(displayConfig); - if (ADL.ADL2_Display_DeviceConfig_Get != null) - { - // Get the DisplayConfig from the Display - ADLRet = ADL.ADL2_Display_DeviceConfig_Get(_adlContextHandle, oneAdapter.AdapterIndex, oneDisplayInfo.DisplayID.DisplayPhysicalIndex, out displayConfig); - if (ADLRet == ADL.ADL_OK) - { - displayConnectionType = (ADL.ADLDisplayConnectionType)displayConfig.ConnectorType; - - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: ### Display Device Config for Display #{oneDisplayInfo.DisplayID.DisplayLogicalIndex} on Adapter #{oneAdapter.AdapterIndex} ###"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: Display Connector Type = {displayConnectionType.ToString("G")}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: Display Device Data = {displayConfig.DeviceData}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: Display Overridded Device Data = {displayConfig.OverriddedDeviceData}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: Display Reserved Data = {displayConfig.Reserved}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: Display Size = {displayConfig.Size}"); - } - else - { - SharedLogger.logger.Warn($"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: Error running ADL2_Display_DeviceConfig_Get on Display #{oneDisplayInfo.DisplayID.DisplayLogicalIndex} on Adapter #{oneAdapter.AdapterIndex}: {ADL.ConvertADLReturnValueIntoWords(ADLRet)}"); - } - } - - ADLDDCInfo2 displayDDCInfo2 = new ADLDDCInfo2(); - displayDDCInfo2.Size = Marshal.SizeOf(displayDDCInfo2); - // Create a stringbuilder buffer that EDID can be loaded into - //displayEDIDData.EDIDData = new StringBuilder(256); - - if (ADL.ADL2_Display_DDCInfo2_Get != null) - { - // Get the DDC Data from the Display - ADLRet = ADL.ADL2_Display_DDCInfo2_Get(_adlContextHandle, oneAdapter.AdapterIndex, oneDisplayInfo.DisplayID.DisplayPhysicalIndex, out displayDDCInfo2); - if (ADLRet == ADL.ADL_OK) - { - - // Convert the DDCInfoFlag to something usable using a library function I made - ConvertedDDCInfoFlag DDCInfoFlag = ADL.ConvertDDCInfoFlag(displayDDCInfo2.DDCInfoFlag); - - // Convert the DDCInfoFlag to something usable using a library function I made - ConvertedSupportedHDR supportedHDR = ADL.ConvertSupportedHDR(displayDDCInfo2.SupportedHDR); - - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: ### Display DDCInfo2 for Display #{oneDisplayInfo.DisplayID.DisplayLogicalIndex} on Adapter #{oneAdapter.AdapterIndex} ###"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: Display AvgLuminanceData = {displayDDCInfo2.AvgLuminanceData}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: Display DDCInfoFlag = {displayDDCInfo2.DDCInfoFlag}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: Display DiffuseScreenReflectance = {displayDDCInfo2.DiffuseScreenReflectance}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: Display DisplayName = {displayDDCInfo2.DisplayName}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: Display FreesyncFlags = {displayDDCInfo2.FreesyncFlags}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: Display ManufacturerID = {displayDDCInfo2.ManufacturerID}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: Display MaxBacklightMaxLuminanceData = {displayDDCInfo2.MaxBacklightMaxLuminanceData}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: Display MaxBacklightMinLuminanceData = {displayDDCInfo2.MaxBacklightMinLuminanceData}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: Display MaxHResolution = {displayDDCInfo2.MaxHResolution}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: Display MaxLuminanceData = {displayDDCInfo2.MaxLuminanceData}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: Display MaxRefresh = {displayDDCInfo2.MaxRefresh}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: Display MaxVResolution = {displayDDCInfo2.MaxVResolution}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: Display MinBacklightMaxLuminanceData = {displayDDCInfo2.MinBacklightMaxLuminanceData}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: Display MinBacklightMinLuminanceData = {displayDDCInfo2.MinBacklightMinLuminanceData}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: Display MinLuminanceData = {displayDDCInfo2.MinLuminanceData}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: Display MinLuminanceNoDimmingData = {displayDDCInfo2.MinLuminanceNoDimmingData}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: Display NativeDisplayChromaticityBlueX = {displayDDCInfo2.NativeDisplayChromaticityBlueX}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: Display NativeDisplayChromaticityBlueY = {displayDDCInfo2.NativeDisplayChromaticityBlueY}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: Display NativeDisplayChromaticityGreenX = {displayDDCInfo2.NativeDisplayChromaticityGreenX}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: Display NativeDisplayChromaticityGreenY = {displayDDCInfo2.NativeDisplayChromaticityGreenY}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: Display NativeDisplayChromaticityRedX = {displayDDCInfo2.NativeDisplayChromaticityRedX}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: Display NativeDisplayChromaticityRedY = {displayDDCInfo2.NativeDisplayChromaticityRedY}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: Display NativeDisplayChromaticityWhiteX = {displayDDCInfo2.NativeDisplayChromaticityWhiteX}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: Display NativeDisplayChromaticityWhiteY = {displayDDCInfo2.NativeDisplayChromaticityWhiteY}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: Display PackedPixelSupported = {displayDDCInfo2.PackedPixelSupported}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: Display PanelPixelFormat = {displayDDCInfo2.PanelPixelFormat}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: Display ProductID = {displayDDCInfo2.ProductID}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: Display PTMCx = {displayDDCInfo2.PTMCx}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: Display PTMCy = {displayDDCInfo2.PTMCy}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: Display PTMRefreshRate = {displayDDCInfo2.PTMRefreshRate}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: Display SerialID = {displayDDCInfo2.SerialID}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: Display Size = {displayDDCInfo2.Size}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: Display SpecularScreenReflectance = {displayDDCInfo2.SpecularScreenReflectance}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: Display SupportedColorSpace = {displayDDCInfo2.SupportedColorSpace}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: Display SupportedHDR = {displayDDCInfo2.SupportedHDR}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: Display SupportedTransferFunction = {displayDDCInfo2.SupportedTransferFunction}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: Display SupportsDDC = {displayDDCInfo2.SupportsDDC}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: Display DDCInfoFlag Digital Device = {DDCInfoFlag.DIGITALDEVICE}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: Display DDCInfoFlag EDID Extension = {DDCInfoFlag.EDIDEXTENSION}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: Display DDCInfoFlag HDMI Audio Device = {DDCInfoFlag.HDMIAUDIODEVICE}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: Display DDCInfoFlag Projector Device = {DDCInfoFlag.PROJECTORDEVICE}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: Display DDCInfoFlag Supports AI = {DDCInfoFlag.SUPPORTS_AI}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: Display DDCInfoFlag Supports xvYCC601 = {DDCInfoFlag.SUPPORT_xvYCC601}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: Display DDCInfoFlag Supports xvYCC709 = {DDCInfoFlag.SUPPORT_xvYCC709}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: Display SupportedHDR Supports CEA861_3 = {supportedHDR.CEA861_3}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: Display SupportedHDR Supports DOLBYVISION = {supportedHDR.DOLBYVISION}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: Display SupportedHDR Supports FREESYNC_HDR = {supportedHDR.FREESYNC_HDR}"); - } - else - { - SharedLogger.logger.Warn($"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: Error running ADL2_Display_DDCInfo2_Get on Display #{oneDisplayInfo.DisplayID.DisplayLogicalIndex} on Adapter #{oneAdapter.AdapterIndex}: {ADL.ConvertADLReturnValueIntoWords(ADLRet)}"); - } - } - - int HDRSupported = 0; - int HDREnabled = 0; - if (ADL.ADL2_Display_HDRState_Get != null) - { - // Get the HDR State from the Display - ADLRet = ADL.ADL2_Display_HDRState_Get(_adlContextHandle, oneAdapter.AdapterIndex, oneDisplayInfo.DisplayID, out HDRSupported, out HDREnabled); - if (ADLRet == ADL.ADL_OK) - { - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: ### Display HDR State for Display #{oneDisplayInfo.DisplayID.DisplayLogicalIndex} on Adapter #{oneAdapter.AdapterIndex} ###"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: Display HDR Supported = {HDRSupported}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: Display HDR Enabled = {HDREnabled}"); - } - else - { - SharedLogger.logger.Warn($"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: Error running ADL2_Display_HDRState_Get on Display #{oneDisplayInfo.DisplayID.DisplayLogicalIndex} on Adapter #{oneAdapter.AdapterIndex}: {ADL.ConvertADLReturnValueIntoWords(ADLRet)}"); - } - } - - - // Create an array of all the important display info we need to record - List displayInfoIdentifierSection = new List(); - displayInfoIdentifierSection.Add("NVIDIA"); - try - { - displayInfoIdentifierSection.Add(oneAdapter.VendorID.ToString()); - } - catch (Exception ex) - { - SharedLogger.logger.Warn(ex, $"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: Exception getting NVIDIA Vendor ID from video card. Substituting with a # instead"); - displayInfoIdentifierSection.Add("#"); - } - - try - { - displayInfoIdentifierSection.Add(oneAdapter.AdapterName); - } - catch (Exception ex) - { - SharedLogger.logger.Warn(ex, $"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: Exception getting NVIDIA Adapter Name from video card. Substituting with a # instead"); - displayInfoIdentifierSection.Add("#"); - } - - try - { - displayInfoIdentifierSection.Add(oneAdapter.VendorID.ToString()); - } - catch (Exception ex) - { - SharedLogger.logger.Warn(ex, $"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: Exception getting NVIDIA VendorID from video card. Substituting with a # instead"); - displayInfoIdentifierSection.Add("1002"); - } - - try - { - displayInfoIdentifierSection.Add(AdapterCapabilities.AdapterID.ToString()); - } - catch (Exception ex) - { - SharedLogger.logger.Warn(ex, $"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: Exception getting NVIDIA AdapterID from video card. Substituting with a # instead"); - displayInfoIdentifierSection.Add("#"); - } - - try - { - displayInfoIdentifierSection.Add(displayConnector.ToString("G")); - } - catch (Exception ex) - { - SharedLogger.logger.Warn(ex, $"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: Exception getting NVIDIA Display Connector from video card to display. Substituting with a # instead"); - displayInfoIdentifierSection.Add("#"); - } - - try - { - displayInfoIdentifierSection.Add(oneDisplayInfo.DisplayName); - } - catch (Exception ex) - { - SharedLogger.logger.Warn(ex, $"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: Exception getting Display Name from display connected to NVIDIA video card. Substituting with a # instead"); - displayInfoIdentifierSection.Add("#"); - } - - try - { - displayInfoIdentifierSection.Add(displayDDCInfo2.ManufacturerID.ToString()); - } - catch (Exception ex) - { - SharedLogger.logger.Warn(ex, $"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: Exception getting Manufacturer ID from display connected to NVIDIA video card. Substituting with a # instead"); - displayInfoIdentifierSection.Add("#"); - } - - try - { - displayInfoIdentifierSection.Add(displayDDCInfo2.ProductID.ToString()); - } - catch (Exception ex) - { - SharedLogger.logger.Warn(ex, $"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: Exception getting Product ID from display connected to NVIDIA video card. Substituting with a # instead"); - displayInfoIdentifierSection.Add("#"); - } - - try - { - displayInfoIdentifierSection.Add(displayDDCInfo2.SerialID.ToString()); - } - catch (Exception ex) - { - SharedLogger.logger.Warn(ex, $"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: Exception getting Serial ID from display connected to NVIDIA video card. Substituting with a # instead"); - displayInfoIdentifierSection.Add("#"); - } - - // Create a display identifier out of it - string displayIdentifier = String.Join("|", displayInfoIdentifierSection); - - // Check first to see if there is already an existing display identifier the same! - // This appears to be a bug with the NVIDIA driver, or with the install on my test machine - // Either way, it is potentially going to happen in the wild, so I will filter it out if it does - if (displayIdentifiers.Contains(displayIdentifier)) - { - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: Your NVIDIA driver reported the following Display Identifier multiple times, so ignoring it as we already have it: {displayIdentifier}"); - continue; - } - - // Add it to the list of display identifiers so we can return it - displayIdentifiers.Add(displayIdentifier); - - SharedLogger.logger.Debug($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: DisplayIdentifier: {displayIdentifier}"); - } - } - catch (Exception ex) - { - SharedLogger.logger.Warn(ex, $"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: Exception caused trying to access attached displays"); - continue; - } - } - else - { - SharedLogger.logger.Warn($"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: Error running ADL2_Display_DisplayInfo_Get on Adapter #{oneAdapter.AdapterIndex}: {ADL.ConvertADLReturnValueIntoWords(ADLRet)}"); - } - // Release the memory for the DisplayInfo structure - if (IntPtr.Zero != DisplayBuffer) - Marshal.FreeCoTaskMem(DisplayBuffer); - } - } - else - { - SharedLogger.logger.Warn($"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: Error running ADL2_Adapter_Active_Get on Adapter #{oneAdapter.AdapterIndex}: {ADL.ConvertADLReturnValueIntoWords(ADLRet)}"); - } + SharedLogger.logger.Trace($"NVIDIALibrary/SetActiveConfig: ADL2_Display_SLSMapConfig_SetState successfully set the SLSMAP with index {adapter.SLSMapIndex} to TRUE for adapter {adapter.AdapterIndex}."); } - } - else - { - SharedLogger.logger.Warn($"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: Error running ADL2_Adapter_AdapterInfoX4_Get on NVIDIA Video card: {ADL.ConvertADLReturnValueIntoWords(ADLRet)}"); - } - } - // Release the memory for the AdapterInfo structure - if (IntPtr.Zero != AdapterBuffer) - { - Marshal.FreeCoTaskMem(AdapterBuffer); - } - - // Return all the identifiers we've found - return displayIdentifiers; - } - else - { - SharedLogger.logger.Warn($"NVIDIALibrary/GenerateAllAvailableDisplayIdentifiers: There were no NVIDIA adapters found by NVIDIA ADL."); - return null; - } - } - - public NVIDIAProfile GetActiveProfile() - { - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveProfile: Getting NVIDIA active adapter count"); - - int ADLRet = ADL.ADL_ERR; - int NumberOfAdapters = 0; - - List displayIdentifiers = new List(); - NVIDIAProfile profileToCreate = new NVIDIAProfile(); - - - if (null != ADL.ADL2_Adapter_NumberOfAdapters_Get) - { - ADL.ADL2_Adapter_NumberOfAdapters_Get(_adlContextHandle, ref NumberOfAdapters); - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveProfile: Number Of Adapters: {NumberOfAdapters.ToString()} "); - } - - if (NumberOfAdapters > 0) - { - profileToCreate.Adapters = new List(); - IntPtr AdapterBuffer = IntPtr.Zero; - if (ADL.ADL2_Adapter_AdapterInfoX4_Get != null) - { - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveProfile: ADL2_Adapter_AdapterInfoX4_Get DLL function exists."); - - // Get the Adapter info and put it in the AdapterBuffer - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveProfile: Running ADL2_Adapter_AdapterInfoX4_Get to find all known NVIDIA adapters."); - //ADLRet = ADL.ADL2_Adapter_AdapterInfoX4_Get(_adlContextHandle, AdapterBuffer, size); - int numAdapters = 0; - ADLRet = ADL.ADL2_Adapter_AdapterInfoX4_Get(_adlContextHandle, ADL.ADL_ADAPTER_INDEX_ALL, out numAdapters, out AdapterBuffer); - if (ADLRet == ADL.ADL_OK) - { - - int IsActive = ADL.ADL_TRUE; // We only want to search for active adapters - - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveProfile: Successfully run ADL2_Adapter_AdapterInfoX4_Get to find information about all known NVIDIA adapters."); - - ADLAdapterInfoX2 oneAdapter = new ADLAdapterInfoX2(); - // Go through each adapter - for (int adapterLoop = 0; adapterLoop < numAdapters; adapterLoop++) + else { - oneAdapter = (ADLAdapterInfoX2)Marshal.PtrToStructure(new IntPtr(AdapterBuffer.ToInt64() + (adapterLoop * Marshal.SizeOf(oneAdapter))), oneAdapter.GetType()); + SharedLogger.logger.Error($"NVIDIALibrary/SetActiveConfig: ERROR - ADL2_Display_SLSMapConfig_SetState returned NVAPI_STATUS {NVStatus} when trying to set the SLSMAP with index {adapter.SLSMapIndex} to TRUE for adapter {adapter.AdapterIndex}."); + throw new NVIDIALibraryException($"ADL2_Display_SLSMapConfig_SetState returned NVAPI_STATUS {NVStatus} when trying to set the SLSMAP with index {adapter.SLSMapIndex} to TRUE for adapter {adapter.AdapterIndex}"); + } + /* - if (oneAdapter.Exist != 1) - { - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveProfile: NVIDIA Adapter #{oneAdapter.AdapterIndex.ToString()} doesn't exist at present so skipping detection for this adapter."); - continue; - } - - if (oneAdapter.Present != 1) - { - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveProfile: NVIDIA Adapter #{oneAdapter.AdapterIndex.ToString()} isn't enabled at present so skipping detection for this adapter."); - continue; - } - - // Check if the adapter is active - if (ADL.ADL2_Adapter_Active_Get != null) - ADLRet = ADL.ADL2_Adapter_Active_Get(_adlContextHandle, oneAdapter.AdapterIndex, ref IsActive); - - if (ADLRet == ADL.ADL_OK) - { - // Only continue if the adapter is enabled - if (IsActive != ADL.ADL_TRUE) - { - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveProfile: NVIDIA Adapter #{oneAdapter.AdapterIndex.ToString()} isn't active ({oneAdapter.AdapterName})."); - continue; - } - - // Only continue if the adapter index is > 0 - if (oneAdapter.AdapterIndex < 0) - { - SharedLogger.logger.Trace($"NVIDIALibrary/GenerateAllAGetActiveProfilevailableDisplayIdentifiers: NVIDIA Adapter has an adapter index of {oneAdapter.AdapterIndex.ToString()} which indicates it is not a real adapter."); - continue; - } - - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveProfile: NVIDIA Adapter #{oneAdapter.AdapterIndex.ToString()} is active! ({oneAdapter.AdapterName})."); - - // Store the Adapter information for later - NVIDIAAdapter adapterToCreate = new NVIDIAAdapter(); - adapterToCreate.AdapterInfoX2 = oneAdapter; - adapterToCreate.Displays = new List(); - - - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveProfile: ### Adapter Info for Adapter #{oneAdapter.AdapterIndex} ###"); - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveProfile: Adapter AdapterIndex = {oneAdapter.AdapterIndex}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveProfile: Adapter AdapterName = {oneAdapter.AdapterName}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveProfile: Adapter BusNumber = {oneAdapter.BusNumber}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveProfile: Adapter DeviceNumber = {oneAdapter.DeviceNumber}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveProfile: Adapter DisplayName = {oneAdapter.DisplayName}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveProfile: Adapter DriverPath = {oneAdapter.DriverPath}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveProfile: Adapter DriverPathExt = {oneAdapter.DriverPathExt}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveProfile: Adapter Exist = {oneAdapter.Exist}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveProfile: Adapter FunctionNumber = {oneAdapter.FunctionNumber}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveProfile: Adapter InfoMask = {oneAdapter.InfoMask}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveProfile: Adapter InfoValue = {oneAdapter.InfoValue}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveProfile: Adapter OSDisplayIndex = {oneAdapter.OSDisplayIndex}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveProfile: Adapter PNPString = {oneAdapter.PNPString}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveProfile: Adapter Present = {oneAdapter.Present}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveProfile: Adapter Size = {oneAdapter.Size}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveProfile: Adapter UDID = {oneAdapter.UDID}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveProfile: Adapter VendorID = {oneAdapter.VendorID}"); - - // Get the Adapter Capabilities - ADLAdapterCapsX2 AdapterCapabilities = new ADLAdapterCapsX2(); - if (ADL.ADL2_AdapterX2_Caps != null) - { - ADLRet = ADL.ADL2_AdapterX2_Caps(_adlContextHandle, oneAdapter.AdapterIndex, out AdapterCapabilities); - } - - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveProfile: ### Adapter Capabilities for Adapter #{oneAdapter.AdapterIndex} ###"); - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveProfile: Adapter ID = {AdapterCapabilities.AdapterID}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveProfile: Adapter Capabilities Mask = {AdapterCapabilities.CapsMask}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveProfile: Adapter Capabilities Value = {AdapterCapabilities.CapsValue}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveProfile: Adapter Num of Connectors = {AdapterCapabilities.NumConnectors}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveProfile: Adapter Num of Controllers = {AdapterCapabilities.NumControllers}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveProfile: Adapter Num of Displays = {AdapterCapabilities.NumDisplays}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveProfile: Adapter Num of GL Sync Connectors = {AdapterCapabilities.NumOfGLSyncConnectors}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveProfile: Adapter Num of Overlays = {AdapterCapabilities.NumOverlays}"); - - // Store the Adapters Info for later - profileToCreate.Adapters.Add(adapterToCreate); - - if (ADL.ADL2_Display_DisplayInfo_Get != null) - { - IntPtr DisplayBuffer = IntPtr.Zero; - int numDisplays = 0; - // Force the display detection and get the Display Info. Use 0 as last parameter to NOT force detection - ADLRet = ADL.ADL2_Display_DisplayInfo_Get(_adlContextHandle, oneAdapter.AdapterIndex, ref numDisplays, out DisplayBuffer, 1); - if (ADLRet == ADL.ADL_OK) - { - - try - { - - for (int displayLoop = 0; displayLoop < numDisplays; displayLoop++) - { - ADLDisplayInfo oneDisplayInfo = new ADLDisplayInfo(); - oneDisplayInfo = (ADLDisplayInfo)Marshal.PtrToStructure(new IntPtr(DisplayBuffer.ToInt64() + (displayLoop * Marshal.SizeOf(oneDisplayInfo))), oneDisplayInfo.GetType()); - - // Is the display mapped to this adapter? If not we skip it! - if (oneDisplayInfo.DisplayID.DisplayLogicalAdapterIndex != oneAdapter.AdapterIndex) + foreach (var slsMap in adapter.SLSMap) { - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveProfile: NVIDIA Adapter #{oneAdapter.AdapterIndex.ToString()} ({oneAdapter.AdapterName}) AdapterID display ID#{oneDisplayInfo.DisplayID.DisplayLogicalIndex} is not a real display as its DisplayID.DisplayLogicalAdapterIndex is -1"); - continue; - } - - // Convert the displayInfoValue to something usable using a library function I made - ConvertedDisplayInfoValue displayInfoValue = ADL.ConvertDisplayInfoValue(oneDisplayInfo.DisplayInfoValue); - - if (!displayInfoValue.DISPLAYCONNECTED) - { - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveProfile: NVIDIA Adapter #{oneAdapter.AdapterIndex.ToString()} ({oneAdapter.AdapterName}) AdapterID display ID#{oneDisplayInfo.DisplayID.DisplayLogicalIndex} is not connected"); - continue; - } - - // Skip connected but non-mapped displays (not mapped in windows) - we only want displays currently visible in the OS because they're in use - if (!displayInfoValue.DISPLAYMAPPED) - { - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveProfile: NVIDIA Adapter #{oneAdapter.AdapterIndex.ToString()} ({oneAdapter.AdapterName}) AdapterID display ID#{oneDisplayInfo.DisplayID.DisplayLogicalIndex} is not mapped in Windows OS"); - continue; - } - - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveProfile: NVIDIA Adapter #{oneAdapter.AdapterIndex.ToString()} ({oneAdapter.AdapterName}) AdapterID display ID#{oneDisplayInfo.DisplayID.DisplayLogicalIndex} is connected and mapped in Windows OS"); - - // Store the Display information for later - - NVIDIADisplay displayToCreate = new NVIDIADisplay(); - displayToCreate.DisplayModes = new List(); - - ADL.ADLDisplayConnectionType displayConnector = (ADL.ADLDisplayConnectionType)oneDisplayInfo.DisplayConnector; - - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveprofile: ### Display Info for Display #{oneDisplayInfo.DisplayID.DisplayLogicalIndex} on Adapter #{oneAdapter.AdapterIndex} ###"); - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveprofile: Display Connector = {displayConnector.ToString("G")}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveprofile: Display Controller Index = {oneDisplayInfo.DisplayControllerIndex}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveprofile: Display Logical Adapter Index = {oneDisplayInfo.DisplayID.DisplayLogicalAdapterIndex}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveprofile: Display Logical Index = {oneDisplayInfo.DisplayID.DisplayLogicalIndex}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveprofile: Display Physical Adapter Index = {oneDisplayInfo.DisplayID.DisplayPhysicalAdapterIndex}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveprofile: Display Physical Index = {oneDisplayInfo.DisplayID.DisplayPhysicalIndex}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveprofile: Display Info Mask = {oneDisplayInfo.DisplayInfoMask}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveprofile: Display Info Value = {oneDisplayInfo.DisplayInfoValue}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveprofile: Display Manufacturer Name = {oneDisplayInfo.DisplayManufacturerName}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveprofile: Display Name = {oneDisplayInfo.DisplayName}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveprofile: Display Output Type = {oneDisplayInfo.DisplayOutputType}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveprofile: Display Type = {oneDisplayInfo.DisplayType}"); - - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveprofile: Display Info Value DISPLAYCONNECTED = {displayInfoValue.DISPLAYCONNECTED}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveprofile: Display Info Value DISPLAYMAPPED = {displayInfoValue.DISPLAYMAPPED}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveprofile: Display Info Value FORCIBLESUPPORTED = {displayInfoValue.FORCIBLESUPPORTED}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveprofile: Display Info Value GENLOCKSUPPORTED = {displayInfoValue.GENLOCKSUPPORTED}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveprofile: Display Info Value LDA_DISPLAY = {displayInfoValue.LDA_DISPLAY}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveprofile: Display Info Value MANNER_SUPPORTED_2HSTRETCH = {displayInfoValue.MANNER_SUPPORTED_2HSTRETCH}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveprofile: Display Info Value MANNER_SUPPORTED_2VSTRETCH = {displayInfoValue.MANNER_SUPPORTED_2VSTRETCH}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveprofile: Display Info Value MANNER_SUPPORTED_CLONE = {displayInfoValue.MANNER_SUPPORTED_CLONE}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveprofile: Display Info Value MANNER_SUPPORTED_EXTENDED = {displayInfoValue.MANNER_SUPPORTED_EXTENDED}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveprofile: Display Info Value MANNER_SUPPORTED_NSTRETCH1GPU = {displayInfoValue.MANNER_SUPPORTED_NSTRETCH1GPU}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveprofile: Display Info Value MANNER_SUPPORTED_NSTRETCHNGPU = {displayInfoValue.MANNER_SUPPORTED_NSTRETCHNGPU}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveprofile: Display Info Value MANNER_SUPPORTED_SINGLE = {displayInfoValue.MANNER_SUPPORTED_SINGLE}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveprofile: Display Info Value MODETIMING_OVERRIDESSUPPORTED = {displayInfoValue.MODETIMING_OVERRIDESSUPPORTED}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveprofile: Display Info Value MULTIVPU_SUPPORTED = {displayInfoValue.MULTIVPU_SUPPORTED}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveprofile: Display Info Value NONLOCAL = {displayInfoValue.NONLOCAL}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveprofile: Display Info Value SHOWTYPE_PROJECTOR = {displayInfoValue.SHOWTYPE_PROJECTOR}"); - - IntPtr displayModeBuffer = IntPtr.Zero; - int numModes = 0; - if (ADL.ADL2_Display_Modes_Get != null) - { - // Get the ADLModes from the Display - ADLRet = ADL.ADL2_Display_Modes_Get(_adlContextHandle, oneAdapter.AdapterIndex, oneDisplayInfo.DisplayID.DisplayPhysicalIndex, out numModes, out displayModeBuffer); - if (ADLRet == ADL.ADL_OK) + // Check the SLS config is valid + int numDisplayTargets = 0; + int supportedSLSLayoutImageMode = 0; + int reasonForNotSupportingSLS = 0; + ADL_DISPLAY_TARGET[] displayTargetArray = { new ADL_DISPLAY_TARGET() }; + IntPtr displayTargetBuffer = IntPtr.Zero; + int option = NVImport.ADL_DISPLAY_SLSGRID_CAP_OPTION_RELATIVETO_LANDSCAPE; + NVStatus = NVImport.ADL2_Display_SLSMapConfig_Valid(_adlContextHandle, adapter.AdapterIndex, slsMap, slsMap.NumSLSTarget, displayTargetArray, out supportedSLSLayoutImageMode, out reasonForNotSupportingSLS, option); + if (NVStatus == NVAPI_STATUS.NVAPI_OK) { - for (int displayModeLoop = 0; displayModeLoop < numModes; displayModeLoop++) + SharedLogger.logger.Trace($"NVIDIALibrary/GetNVIDIADisplayConfig: ADL2_Display_SLSMapConfig_Valid confirmed the SLS configuration is valid for NVIDIA adapter {adapter.AdapterIndex}."); + } + else + { + SharedLogger.logger.Error($"NVIDIALibrary/GetNVIDIADisplayConfig: ERROR - ADL2_Display_SLSMapConfig_Valid returned NVAPI_STATUS {NVStatus} when trying to validate the SLS configuration for NVIDIA adapter {adapter.AdapterIndex} in the computer."); + throw new NVIDIALibraryException($"ADL2_Display_SLSMapConfig_Valid returned NVAPI_STATUS {NVStatus}when trying to validate the SLS configuration for NVIDIA adapter {adapter.AdapterIndex} in the computer"); + } + + if (numDisplayTargets > 0) + { + IntPtr currentDisplayTargetBuffer = displayTargetBuffer; + displayTargetArray = new ADL_DISPLAY_TARGET[numDisplayTargets]; + for (int i = 0; i < numDisplayTargets; i++) { - ADLMode oneDisplayMode = new ADLMode(); - oneDisplayMode = (ADLMode)Marshal.PtrToStructure(new IntPtr(displayModeBuffer.ToInt64() + (displayModeLoop * Marshal.SizeOf(oneDisplayMode))), oneDisplayMode.GetType()); - - displayToCreate.DisplayModes.Add(oneDisplayMode); - - //displayConnectionType = (ADL.ADLDisplayConnectionType)displayConfig.ConnectorType; - ConvertedDisplayModeFlags displayModeFlag = ADL.ConvertDisplayModeFlags(oneDisplayMode.ModeFlag); - ConvertedDisplayModeFlags displayModeMask = ADL.ConvertDisplayModeFlags(oneDisplayMode.ModeMask); - ConvertedDisplayModeFlags displayModeValue = ADL.ConvertDisplayModeFlags(oneDisplayMode.ModeValue); - - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveprofile: ### Display Modes for Display #{oneDisplayInfo.DisplayID.DisplayLogicalIndex} on Adapter #{oneAdapter.AdapterIndex} ###"); - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveprofile: DisplayMode Colour Depth = {oneDisplayMode.ColourDepth}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveprofile: DisplayMode Mode Flag = {oneDisplayMode.ModeFlag}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveprofile: DisplayMode Mode Flag ColourFormat 565 = {displayModeFlag.COLOURFORMAT_565}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveprofile: DisplayMode Mode Flag ColourFormat 8888 = {displayModeFlag.COLOURFORMAT_8888}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveprofile: DisplayMode Mode Flag ORIENTATION_SUPPORTED_000 = {displayModeFlag.ORIENTATION_SUPPORTED_000}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveprofile: DisplayMode Mode Flag ORIENTATION_SUPPORTED_090 = {displayModeFlag.ORIENTATION_SUPPORTED_090}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveprofile: DisplayMode Mode Flag ORIENTATION_SUPPORTED_180 = {displayModeFlag.ORIENTATION_SUPPORTED_180}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveprofile: DisplayMode Mode Flag ORIENTATION_SUPPORTED_270 = {displayModeFlag.ORIENTATION_SUPPORTED_270}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveprofile: DisplayMode Mode Flag REFRESHRATE_ROUNDED = {displayModeFlag.REFRESHRATE_ROUNDED}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveprofile: DisplayMode Mode Flag REFRESHRATE_ONLY = {displayModeFlag.REFRESHRATE_ONLY}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveprofile: DisplayMode Mode Mask = {oneDisplayMode.ModeMask}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveprofile: DisplayMode Mode Value = {oneDisplayMode.ModeValue}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveprofile: DisplayMode Orientation = {oneDisplayMode.Orientation}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveprofile: DisplayMode Refresh Rate = {oneDisplayMode.RefreshRate}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveprofile: DisplayMode X Position = {oneDisplayMode.XPos}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveprofile: DisplayMode X Resolution = {oneDisplayMode.XRes}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveprofile: DisplayMode Y Position = {oneDisplayMode.YPos}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveprofile: DisplayMode Y Resolution = {oneDisplayMode.YRes}"); - } + // build a structure in the array slot + displayTargetArray[i] = new ADL_DISPLAY_TARGET(); + // fill the array slot structure with the data from the buffer + displayTargetArray[i] = (ADL_DISPLAY_TARGET)Marshal.PtrToStructure(currentDisplayTargetBuffer, typeof(ADL_DISPLAY_TARGET)); + // destroy the bit of memory we no longer need + Marshal.DestroyStructure(currentDisplayTargetBuffer, typeof(ADL_DISPLAY_TARGET)); + // advance the buffer forwards to the next object + currentDisplayTargetBuffer = (IntPtr)((long)currentDisplayTargetBuffer + Marshal.SizeOf(displayTargetArray[i])); + } + // Free the memory used by the buffer + Marshal.FreeCoTaskMem(displayTargetBuffer); } - else - { - SharedLogger.logger.Warn($"NVIDIALibrary/GetActiveprofile: Error running ADL2_Display_DeviceConfig_Get on Display #{oneDisplayInfo.DisplayID.DisplayLogicalIndex} on Adapter #{oneAdapter.AdapterIndex}: {ADL.ConvertADLReturnValueIntoWords(ADLRet)}"); - } - } + }*/ - ADLDDCInfo2 displayDDCInfo2 = new ADLDDCInfo2(); - displayDDCInfo2.Size = Marshal.SizeOf(displayDDCInfo2); - // Create a stringbuilder buffer that EDID can be loaded into - //displayEDIDData.EDIDData = new StringBuilder(256); + } + /*else + { + *//*// Do the non-SLS based display setup + NVIDIA_ADAPTER_CONFIG NVIDIAAdapterConfig = adapter; + //int numPossibleMapResult = 0; + //IntPtr possibleMapResultBuffer = IntPtr.Zero; + NVStatus = NVImport.ADL2_Display_DisplayMapConfig_Set(_adlContextHandle, NVIDIAAdapterConfig.AdapterIndex, NVIDIAAdapterConfig.DisplayMaps.Length, NVIDIAAdapterConfig.DisplayMaps, NVIDIAAdapterConfig.DisplayTargets.Length, NVIDIAAdapterConfig.DisplayTargets); + if (NVStatus == NVAPI_STATUS.NVAPI_OK) + { + SharedLogger.logger.Trace($"NVIDIALibrary/GetNVIDIADisplayConfig: ADL2_Display_DisplayMapConfig_Set returned information about all displaytargets connected to NVIDIA adapter {NVIDIAAdapterConfig.AdapterIndex}."); + } + else + { + SharedLogger.logger.Error($"NVIDIALibrary/GetNVIDIADisplayConfig: ERROR - ADL2_Display_DisplayMapConfig_Get returned NVAPI_STATUS {NVStatus} when trying to get the display target info from NVIDIA adapter {NVIDIAAdapterConfig.AdapterIndex} in the computer."); + throw new NVIDIALibraryException($"ADL2_Display_DisplayMapConfig_Get returned NVAPI_STATUS {NVStatus} when trying to get the display target info from NVIDIA adapter {NVIDIAAdapterConfig.AdapterIndex} in the computer"); + }*//* + }*/ + else + { + // Turn the SLS based display map off + //NVStatus = NVImport.ADL2_Display_SLSMapConfig_SetState(_adlContextHandle, adapter.AdapterIndex, adapter.SLSMapIndex, NVImport.ADL_FALSE); + if (NVStatus == NVAPI_STATUS.NVAPI_OK) + { + SharedLogger.logger.Trace($"NVIDIALibrary/SetActiveConfig: ADL2_Display_SLSMapConfig_SetState successfully set the SLSMAP with index {adapter.SLSMapIndex} to FALSE for adapter {adapter.AdapterIndex}."); + } + else + { + SharedLogger.logger.Error($"NVIDIALibrary/SetActiveConfig: ERROR - ADL2_Display_SLSMapConfig_SetState returned NVAPI_STATUS {NVStatus} when trying to set the SLSMAP with index {adapter.SLSMapIndex} to FALSE for adapter {adapter.AdapterIndex}."); + throw new NVIDIALibraryException($"ADL2_Display_SLSMapConfig_SetState returned NVAPI_STATUS {NVStatus} when trying to set the SLSMAP with index {adapter.SLSMapIndex} to FALSE for adapter {adapter.AdapterIndex}"); + } + } - if (ADL.ADL2_Display_DDCInfo2_Get != null) - { - // Get the DDC Data from the Display - ADLRet = ADL.ADL2_Display_DDCInfo2_Get(_adlContextHandle, oneAdapter.AdapterIndex, oneDisplayInfo.DisplayID.DisplayPhysicalIndex, out displayDDCInfo2); - if (ADLRet == ADL.ADL_OK) - { + } - // Convert the DDCInfoFlag to something usable using a library function I made - ConvertedDDCInfoFlag DDCInfoFlag = ADL.ConvertDDCInfoFlag(displayDDCInfo2.DDCInfoFlag); + // We want to set the NVIDIA HDR settings - // Convert the DDCInfoFlag to something usable using a library function I made - ConvertedSupportedHDR supportedHDR = ADL.ConvertSupportedHDR(displayDDCInfo2.SupportedHDR); - - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveprofile: ### Display DDCInfo2 for Display #{oneDisplayInfo.DisplayID.DisplayLogicalIndex} on Adapter #{oneAdapter.AdapterIndex} ###"); - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveprofile: Display AvgLuminanceData = {displayDDCInfo2.AvgLuminanceData}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveprofile: Display DDCInfoFlag = {displayDDCInfo2.DDCInfoFlag}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveprofile: Display DiffuseScreenReflectance = {displayDDCInfo2.DiffuseScreenReflectance}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveprofile: Display DisplayName = {displayDDCInfo2.DisplayName}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveprofile: Display FreesyncFlags = {displayDDCInfo2.FreesyncFlags}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveprofile: Display ManufacturerID = {displayDDCInfo2.ManufacturerID}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveprofile: Display MaxBacklightMaxLuminanceData = {displayDDCInfo2.MaxBacklightMaxLuminanceData}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveprofile: Display MaxBacklightMinLuminanceData = {displayDDCInfo2.MaxBacklightMinLuminanceData}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveprofile: Display MaxHResolution = {displayDDCInfo2.MaxHResolution}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveprofile: Display MaxLuminanceData = {displayDDCInfo2.MaxLuminanceData}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveprofile: Display MaxRefresh = {displayDDCInfo2.MaxRefresh}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveprofile: Display MaxVResolution = {displayDDCInfo2.MaxVResolution}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveprofile: Display MinBacklightMaxLuminanceData = {displayDDCInfo2.MinBacklightMaxLuminanceData}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveprofile: Display MinBacklightMinLuminanceData = {displayDDCInfo2.MinBacklightMinLuminanceData}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveprofile: Display MinLuminanceData = {displayDDCInfo2.MinLuminanceData}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveprofile: Display MinLuminanceNoDimmingData = {displayDDCInfo2.MinLuminanceNoDimmingData}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveprofile: Display NativeDisplayChromaticityBlueX = {displayDDCInfo2.NativeDisplayChromaticityBlueX}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveprofile: Display NativeDisplayChromaticityBlueY = {displayDDCInfo2.NativeDisplayChromaticityBlueY}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveprofile: Display NativeDisplayChromaticityGreenX = {displayDDCInfo2.NativeDisplayChromaticityGreenX}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveprofile: Display NativeDisplayChromaticityGreenY = {displayDDCInfo2.NativeDisplayChromaticityGreenY}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveprofile: Display NativeDisplayChromaticityRedX = {displayDDCInfo2.NativeDisplayChromaticityRedX}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveprofile: Display NativeDisplayChromaticityRedY = {displayDDCInfo2.NativeDisplayChromaticityRedY}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveprofile: Display NativeDisplayChromaticityWhiteX = {displayDDCInfo2.NativeDisplayChromaticityWhiteX}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveprofile: Display NativeDisplayChromaticityWhiteY = {displayDDCInfo2.NativeDisplayChromaticityWhiteY}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveprofile: Display PackedPixelSupported = {displayDDCInfo2.PackedPixelSupported}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveprofile: Display PanelPixelFormat = {displayDDCInfo2.PanelPixelFormat}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveprofile: Display ProductID = {displayDDCInfo2.ProductID}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveprofile: Display PTMCx = {displayDDCInfo2.PTMCx}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveprofile: Display PTMCy = {displayDDCInfo2.PTMCy}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveprofile: Display PTMRefreshRate = {displayDDCInfo2.PTMRefreshRate}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveprofile: Display SerialID = {displayDDCInfo2.SerialID}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveprofile: Display Size = {displayDDCInfo2.Size}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveprofile: Display SpecularScreenReflectance = {displayDDCInfo2.SpecularScreenReflectance}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveprofile: Display SupportedColorSpace = {displayDDCInfo2.SupportedColorSpace}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveprofile: Display SupportedHDR = {displayDDCInfo2.SupportedHDR}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveprofile: Display SupportedTransferFunction = {displayDDCInfo2.SupportedTransferFunction}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveprofile: Display SupportsDDC = {displayDDCInfo2.SupportsDDC}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveprofile: Display DDCInfoFlag Digital Device = {DDCInfoFlag.DIGITALDEVICE}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveprofile: Display DDCInfoFlag EDID Extension = {DDCInfoFlag.EDIDEXTENSION}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveprofile: Display DDCInfoFlag HDMI Audio Device = {DDCInfoFlag.HDMIAUDIODEVICE}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveprofile: Display DDCInfoFlag Projector Device = {DDCInfoFlag.PROJECTORDEVICE}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveprofile: Display DDCInfoFlag Supports AI = {DDCInfoFlag.SUPPORTS_AI}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveprofile: Display DDCInfoFlag Supports xvYCC601 = {DDCInfoFlag.SUPPORT_xvYCC601}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveprofile: Display DDCInfoFlag Supports xvYCC709 = {DDCInfoFlag.SUPPORT_xvYCC709}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveprofile: Display SupportedHDR Supports CEA861_3 = {supportedHDR.CEA861_3}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveprofile: Display SupportedHDR Supports DOLBYVISION = {supportedHDR.DOLBYVISION}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveprofile: Display SupportedHDR Supports FREESYNC_HDR = {supportedHDR.FREESYNC_HDR}"); - } - else - { - SharedLogger.logger.Warn($"NVIDIALibrary/GetActiveprofile: Error running ADL2_Display_DDCInfo2_Get on Display #{oneDisplayInfo.DisplayID.DisplayLogicalIndex} on Adapter #{oneAdapter.AdapterIndex}: {ADL.ConvertADLReturnValueIntoWords(ADLRet)}"); - } + // We want to apply the Windows CCD layout info and HDR + } + else + { + SharedLogger.logger.Error($"NVIDIALibrary/SetActiveConfig: ERROR - Tried to run SetActiveConfig but the NVIDIA ADL library isn't initialised!"); + throw new NVIDIALibraryException($"Tried to run SetActiveConfig but the NVIDIA ADL library isn't initialised!"); + } - // Add the things we learnt about the Display to the NVIDIAProfile. - adapterToCreate.Displays.Add(displayToCreate); - } + /* + // Get the all possible windows display configs + SharedLogger.logger.Trace($"NVIDIALibrary/SetActiveConfig: Generating a list of all the current display configs"); + WINDOWS_DISPLAY_CONFIG allWindowsDisplayConfig = GetWindowsDisplayConfig(QDC.QDC_ALL_PATHS); - int HDRSupported = 0; - int HDREnabled = 0; - if (ADL.ADL2_Display_HDRState_Get != null) - { - // Get the HDR State from the Display - ADLRet = ADL.ADL2_Display_HDRState_Get(_adlContextHandle, oneAdapter.AdapterIndex, oneDisplayInfo.DisplayID, out HDRSupported, out HDREnabled); - if (ADLRet == ADL.ADL_OK) - { - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveprofile: ### Display HDR State for Display #{oneDisplayInfo.DisplayID.DisplayLogicalIndex} on Adapter #{oneAdapter.AdapterIndex} ###"); - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveprofile: Display HDR Supported = {HDRSupported}"); - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveprofile: Display HDR Enabled = {HDREnabled}"); - } - else - { - SharedLogger.logger.Warn($"NVIDIALibrary/GetActiveprofile: Error running ADL2_Display_HDRState_Get on Display #{oneDisplayInfo.DisplayID.DisplayLogicalIndex} on Adapter #{oneAdapter.AdapterIndex}: {ADL.ConvertADLReturnValueIntoWords(ADLRet)}"); - } - } + // Now we go through the Paths to update the LUIDs as per Soroush's suggestion + SharedLogger.logger.Trace($"NVIDIALibrary/SetActiveConfig: Patching the adapter IDs to make the saved config valid"); + PatchAdapterIDs(ref displayConfig, allWindowsDisplayConfig.displayAdapters); + SharedLogger.logger.Trace($"NVIDIALibrary/SetActiveConfig: Testing whether the display configuration is valid"); + // Test whether a specified display configuration is supported on the computer + uint myPathsCount = (uint)displayConfig.displayConfigPaths.Length; + uint myModesCount = (uint)displayConfig.displayConfigModes.Length; + WIN32STATUS err = CCDImport.SetDisplayConfig(myPathsCount, displayConfig.displayConfigPaths, myModesCount, displayConfig.displayConfigModes, SDC.DISPLAYMAGICIAN_VALIDATE); + if (err == WIN32STATUS.ERROR_SUCCESS) + { + SharedLogger.logger.Trace($"NVIDIALibrary/SetActiveConfig: Successfully validated that the display configuration supplied would work!"); + } + else + { + SharedLogger.logger.Error($"NVIDIALibrary/SetActiveConfig: ERROR - SetDisplayConfig couldn't validate the display configuration supplied. This display configuration wouldn't work."); + return false; + } - // Create an array of all the important display info we need to record - List displayInfoIdentifierSection = new List(); - displayInfoIdentifierSection.Add("NVIDIA"); - try - { - displayInfoIdentifierSection.Add(oneAdapter.VendorID.ToString()); - } - catch (Exception ex) - { - SharedLogger.logger.Warn(ex, $"NVIDIALibrary/GetActiveprofile: Exception getting NVIDIA Vendor ID from video card. Substituting with a # instead"); - displayInfoIdentifierSection.Add("#"); - } + SharedLogger.logger.Trace($"NVIDIALibrary/SetActiveConfig: Yay! The display configuration is valid! Attempting to set the Display Config now"); + // Now set the specified display configuration for this computer + err = CCDImport.SetDisplayConfig(myPathsCount, displayConfig.displayConfigPaths, myModesCount, displayConfig.displayConfigModes, SDC.DISPLAYMAGICIAN_SET); + if (err == WIN32STATUS.ERROR_SUCCESS) + { + SharedLogger.logger.Trace($"NVIDIALibrary/SetActiveConfig: Successfully set the display configuration to the settings supplied!"); + } + else + { + SharedLogger.logger.Error($"NVIDIALibrary/SetActiveConfig: ERROR - SetDisplayConfig couldn't set the display configuration using the settings supplied. Something is wrong."); + throw new NVIDIALibraryException($"SetDisplayConfig couldn't set the display configuration using the settings supplied. Something is wrong."); + } - try - { - displayInfoIdentifierSection.Add(oneAdapter.AdapterName); - } - catch (Exception ex) - { - SharedLogger.logger.Warn(ex, $"NVIDIALibrary/GetActiveprofile: Exception getting NVIDIA Adapter Name from video card. Substituting with a # instead"); - displayInfoIdentifierSection.Add("#"); - } + SharedLogger.logger.Trace($"NVIDIALibrary/SetActiveConfig: SUCCESS! The display configuration has been successfully applied"); - try - { - displayInfoIdentifierSection.Add(oneAdapter.VendorID.ToString()); - } - catch (Exception ex) - { - SharedLogger.logger.Warn(ex, $"NVIDIALibrary/GetActiveprofile: Exception getting NVIDIA VendorID from video card. Substituting with a # instead"); - displayInfoIdentifierSection.Add("1002"); - } + foreach (ADVANCED_HDR_INFO_PER_PATH myHDRstate in displayConfig.displayHDRStates) + { + SharedLogger.logger.Trace($"Trying to get information whether HDR color is in use now on Display {myHDRstate.Id}."); + // Get advanced HDR info + var colorInfo = new DISPLAYCONFIG_GET_ADVANCED_COLOR_INFO(); + colorInfo.Header.Type = DISPLAYCONFIG_DEVICE_INFO_TYPE.DISPLAYCONFIG_DEVICE_INFO_GET_ADVANCED_COLOR_INFO; + colorInfo.Header.Size = (uint)Marshal.SizeOf(); + colorInfo.Header.AdapterId = myHDRstate.AdapterId; + colorInfo.Header.Id = myHDRstate.Id; + err = CCDImport.DisplayConfigGetDeviceInfo(ref colorInfo); + if (err == WIN32STATUS.ERROR_SUCCESS) + { + SharedLogger.logger.Trace($"NVIDIALibrary/SetActiveConfig: Advanced Color Info gathered from Display {myHDRstate.Id}"); - try - { - displayInfoIdentifierSection.Add(AdapterCapabilities.AdapterID.ToString()); - } - catch (Exception ex) - { - SharedLogger.logger.Warn(ex, $"NVIDIALibrary/GetActiveprofile: Exception getting NVIDIA AdapterID from video card. Substituting with a # instead"); - displayInfoIdentifierSection.Add("#"); - } + if (myHDRstate.AdvancedColorInfo.AdvancedColorSupported && colorInfo.AdvancedColorEnabled != myHDRstate.AdvancedColorInfo.AdvancedColorEnabled) + { + SharedLogger.logger.Trace($"HDR is available for use on Display {myHDRstate.Id}, and we want it set to {myHDRstate.AdvancedColorInfo.AdvancedColorEnabled} but is currently {colorInfo.AdvancedColorEnabled}."); - try - { - displayInfoIdentifierSection.Add(displayConnector.ToString("G")); - } - catch (Exception ex) - { - SharedLogger.logger.Warn(ex, $"NVIDIALibrary/GetActiveprofile: Exception getting NVIDIA Display Connector from video card to display. Substituting with a # instead"); - displayInfoIdentifierSection.Add("#"); - } - - try - { - displayInfoIdentifierSection.Add(oneDisplayInfo.DisplayName); - } - catch (Exception ex) - { - SharedLogger.logger.Warn(ex, $"NVIDIALibrary/GetActiveprofile: Exception getting Display Name from display connected to NVIDIA video card. Substituting with a # instead"); - displayInfoIdentifierSection.Add("#"); - } - - try - { - displayInfoIdentifierSection.Add(displayDDCInfo2.ManufacturerID.ToString()); - } - catch (Exception ex) - { - SharedLogger.logger.Warn(ex, $"NVIDIALibrary/GetActiveprofile: Exception getting Manufacturer ID from display connected to NVIDIA video card. Substituting with a # instead"); - displayInfoIdentifierSection.Add("#"); - } - - try - { - displayInfoIdentifierSection.Add(displayDDCInfo2.ProductID.ToString()); - } - catch (Exception ex) - { - SharedLogger.logger.Warn(ex, $"NVIDIALibrary/GetActiveprofile: Exception getting Product ID from display connected to NVIDIA video card. Substituting with a # instead"); - displayInfoIdentifierSection.Add("#"); - } - - try - { - displayInfoIdentifierSection.Add(displayDDCInfo2.SerialID.ToString()); - } - catch (Exception ex) - { - SharedLogger.logger.Warn(ex, $"NVIDIALibrary/GetActiveprofile: Exception getting Serial ID from display connected to NVIDIA video card. Substituting with a # instead"); - displayInfoIdentifierSection.Add("#"); - } - - // Create a display identifier out of it - string displayIdentifier = String.Join("|", displayInfoIdentifierSection); - - // Check first to see if there is already an existing display identifier the same! - // This appears to be a bug with the NVIDIA driver, or with the install on my test machine - // Either way, it is potentially going to happen in the wild, so I will filter it out if it does - if (displayIdentifiers.Contains(displayIdentifier)) - { - SharedLogger.logger.Trace($"NVIDIALibrary/GetActiveprofile: Your NVIDIA driver reported the following Display Identifier multiple times, so ignoring it as we already have it: {displayIdentifier}"); - continue; - } - - // Add it to the list of display identifiers so we can return it - displayIdentifiers.Add(displayIdentifier); - - SharedLogger.logger.Debug($"ProfileRepository/GetActiveprofile: DisplayIdentifier: {displayIdentifier}"); - } - } - catch (Exception ex) - { - SharedLogger.logger.Warn(ex, $"ProfileRepository/GetActiveprofile: Exception caused trying to access attached displays"); - continue; - } + var setColorState = new DISPLAYCONFIG_SET_ADVANCED_COLOR_STATE(); + setColorState.Header.Type = DISPLAYCONFIG_DEVICE_INFO_TYPE.DISPLAYCONFIG_DEVICE_INFO_SET_ADVANCED_COLOR_STATE; + setColorState.Header.Size = (uint)Marshal.SizeOf(); + setColorState.Header.AdapterId = myHDRstate.AdapterId; + setColorState.Header.Id = myHDRstate.Id; + setColorState.EnableAdvancedColor = myHDRstate.AdvancedColorInfo.AdvancedColorEnabled; + err = CCDImport.DisplayConfigSetDeviceInfo(ref setColorState); + if (err == WIN32STATUS.ERROR_SUCCESS) + { + SharedLogger.logger.Trace($"NVIDIALibrary/SetActiveConfig: SUCCESS! Set HDR successfully to {myHDRstate.AdvancedColorInfo.AdvancedColorEnabled} on Display {myHDRstate.Id}"); } else { - SharedLogger.logger.Warn($"NVIDIALibrary/GetActiveprofile: Error running ADL2_Display_DisplayInfo_Get on Adapter #{oneAdapter.AdapterIndex}: {ADL.ConvertADLReturnValueIntoWords(ADLRet)}"); + SharedLogger.logger.Error($"NVIDIALibrary/SetActiveConfig: ERROR - DisplayConfigGetDeviceInfo returned WIN32STATUS {err} when trying to set the HDR settings for display #{myHDRstate.Id}"); + return false; } - // Release the memory for the DisplayInfo structure - if (IntPtr.Zero != DisplayBuffer) - Marshal.FreeCoTaskMem(DisplayBuffer); + } + else + { + SharedLogger.logger.Trace($"NVIDIALibrary/SetActiveConfig: Skipping setting HDR on Display {myHDRstate.Id} as it does not support HDR"); } } else { - SharedLogger.logger.Warn($"NVIDIALibrary/GetActiveprofile: Error running ADL2_Adapter_Active_Get on Adapter #{oneAdapter.AdapterIndex}: {ADL.ConvertADLReturnValueIntoWords(ADLRet)}"); + SharedLogger.logger.Warn($"NVIDIALibrary/GetWindowsDisplayConfig: WARNING - DisplayConfigGetDeviceInfo returned WIN32STATUS {err} when trying to find out if HDR is supported for display #{myHDRstate.Id}"); } - } - } - else - { - SharedLogger.logger.Warn($"NVIDIALibrary/GetActiveprofile: Error running ADL2_Adapter_AdapterInfoX4_Get on NVIDIA Video card: {ADL.ConvertADLReturnValueIntoWords(ADLRet)}"); - } - } - // Release the memory for the AdapterInfo structure - if (IntPtr.Zero != AdapterBuffer) - { - Marshal.FreeCoTaskMem(AdapterBuffer); - } + }*/ + return true; + } + + public bool IsActiveConfig(NVIDIA_DISPLAY_CONFIG displayConfig) + { + // Get the current windows display configs to compare to the one we loaded + bool allDisplays = false; + NVIDIA_DISPLAY_CONFIG currentWindowsDisplayConfig = GetNVIDIADisplayConfig(allDisplays); + + // Check whether the display config is in use now + SharedLogger.logger.Trace($"NVIDIALibrary/IsActiveConfig: Checking whether the display configuration is already being used."); + if (displayConfig.Equals(currentWindowsDisplayConfig)) + { + SharedLogger.logger.Trace($"NVIDIALibrary/IsActiveConfig: The display configuration is already being used (supplied displayConfig Equals currentWindowsDisplayConfig"); + return true; } else { - SharedLogger.logger.Warn($"NVIDIALibrary/GetActiveprofile: There were no NVIDIA adapters found by NVIDIA ADL."); - + SharedLogger.logger.Trace($"NVIDIALibrary/IsActiveConfig: The display configuration is NOT currently in use (supplied displayConfig Equals currentWindowsDisplayConfig"); + return false; } - // Return the profile - return profileToCreate; } - public bool SetActiveProfile(NVIDIAProfile profileToUse) + public bool IsPossibleConfig(NVIDIA_DISPLAY_CONFIG displayConfig) { + /*// Get the all possible windows display configs + NVIDIA_DISPLAY_CONFIG allWindowsDisplayConfig = GetNVIDIADisplayConfig(QDC.QDC_ALL_PATHS); + + SharedLogger.logger.Trace("NVIDIALibrary/PatchAdapterIDs: Going through the list of adapters we stored in the config to make sure they still exist"); + // Firstly check that the Adapter Names are still currently available (i.e. the adapter hasn't been replaced). + foreach (string savedAdapterName in displayConfig.displayAdapters.Values) + { + // If there is even one of the saved adapters that has changed, then it's no longer possible + // to use this display config! + if (!allWindowsDisplayConfig.displayAdapters.Values.Contains(savedAdapterName)) + { + SharedLogger.logger.Error($"NVIDIALibrary/PatchAdapterIDs: ERROR - Saved adapter {savedAdapterName} is not available right now! This display configuration won't work!"); + return false; + } + } + SharedLogger.logger.Trace($"NVIDIALibrary/PatchAdapterIDs: All teh adapters that the display configuration uses are still avilable to use now!"); + + // Now we go through the Paths to update the LUIDs as per Soroush's suggestion + SharedLogger.logger.Trace($"NVIDIALibrary/IsPossibleConfig: Attemptong to patch the saved display configuration's adapter IDs so that it will still work (these change at each boot)"); + PatchAdapterIDs(ref displayConfig, allWindowsDisplayConfig.displayAdapters); + + SharedLogger.logger.Trace($"NVIDIALibrary/IsPossibleConfig: Testing whether the display configuration is valid "); + // Test whether a specified display configuration is supported on the computer + uint myPathsCount = (uint)displayConfig.displayConfigPaths.Length; + uint myModesCount = (uint)displayConfig.displayConfigModes.Length; + WIN32STATUS err = CCDImport.SetDisplayConfig(myPathsCount, displayConfig.displayConfigPaths, myModesCount, displayConfig.displayConfigModes, SDC.DISPLAYMAGICIAN_VALIDATE); + if (err == WIN32STATUS.ERROR_SUCCESS) + { + SharedLogger.logger.Trace($"NVIDIALibrary/IsPossibleConfig: SetDisplayConfig validated that the display configuration is valid and can be used!"); + return true; + } + else + { + SharedLogger.logger.Trace($"NVIDIALibrary/IsPossibleConfig: SetDisplayConfig confirmed that the display configuration is invalid and cannot be used!"); + return false; + }*/ return true; } - public bool IsActiveProfile(NVIDIAProfile profileToTest) + public List GetCurrentDisplayIdentifiers() { - return true; + SharedLogger.logger.Error($"NVIDIALibrary/GetCurrentDisplayIdentifiers: Getting the current display identifiers for the displays in use now"); + return GetSomeDisplayIdentifiers(QDC.QDC_ONLY_ACTIVE_PATHS); } - public bool IsValidProfile(NVIDIAProfile profileToTest) + public List GetAllConnectedDisplayIdentifiers() { - return true; + SharedLogger.logger.Error($"NVIDIALibrary/GetAllConnectedDisplayIdentifiers: Getting all the display identifiers that can possibly be used"); + return GetSomeDisplayIdentifiers(QDC.QDC_ALL_PATHS); } + + private List GetSomeDisplayIdentifiers(QDC selector = QDC.QDC_ONLY_ACTIVE_PATHS) + { + SharedLogger.logger.Debug($"NVIDIALibrary/GetCurrentDisplayIdentifiers: Generating the unique Display Identifiers for the currently active configuration"); + + List displayIdentifiers = new List(); + + SharedLogger.logger.Trace($"NVIDIALibrary/GetCurrentDisplayIdentifiers: Testing whether the display configuration is valid (allowing tweaks)."); + // Get the size of the largest Active Paths and Modes arrays + int pathCount = 0; + int modeCount = 0; + WIN32STATUS err = CCDImport.GetDisplayConfigBufferSizes(QDC.QDC_ONLY_ACTIVE_PATHS, out pathCount, out modeCount); + if (err != WIN32STATUS.ERROR_SUCCESS) + { + SharedLogger.logger.Error($"NVIDIALibrary/PrintActiveConfig: ERROR - GetDisplayConfigBufferSizes returned WIN32STATUS {err} when trying to get the maximum path and mode sizes"); + throw new NVIDIALibraryException($"GetDisplayConfigBufferSizes returned WIN32STATUS {err} when trying to get the maximum path and mode sizes"); + } + + SharedLogger.logger.Trace($"NVIDIALibrary/GetSomeDisplayIdentifiers: Getting the current Display Config path and mode arrays"); + var paths = new DISPLAYCONFIG_PATH_INFO[pathCount]; + var modes = new DISPLAYCONFIG_MODE_INFO[modeCount]; + err = CCDImport.QueryDisplayConfig(QDC.QDC_ONLY_ACTIVE_PATHS, ref pathCount, paths, ref modeCount, modes, IntPtr.Zero); + if (err == WIN32STATUS.ERROR_INSUFFICIENT_BUFFER) + { + SharedLogger.logger.Warn($"NVIDIALibrary/GetSomeDisplayIdentifiers: The displays were modified between GetDisplayConfigBufferSizes and QueryDisplayConfig so we need to get the buffer sizes again."); + SharedLogger.logger.Trace($"NVIDIALibrary/GetSomeDisplayIdentifiers: Getting the size of the largest Active Paths and Modes arrays"); + // Screen changed in between GetDisplayConfigBufferSizes and QueryDisplayConfig, so we need to get buffer sizes again + // as per https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-querydisplayconfig + err = CCDImport.GetDisplayConfigBufferSizes(QDC.QDC_ONLY_ACTIVE_PATHS, out pathCount, out modeCount); + if (err != WIN32STATUS.ERROR_SUCCESS) + { + SharedLogger.logger.Error($"NVIDIALibrary/GetSomeDisplayIdentifiers: ERROR - GetDisplayConfigBufferSizes returned WIN32STATUS {err} when trying to get the maximum path and mode sizes again"); + throw new NVIDIALibraryException($"GetDisplayConfigBufferSizes returned WIN32STATUS {err} when trying to get the maximum path and mode sizes again"); + } + SharedLogger.logger.Trace($"NVIDIALibrary/GetSomeDisplayIdentifiers: Getting the current Display Config path and mode arrays"); + paths = new DISPLAYCONFIG_PATH_INFO[pathCount]; + modes = new DISPLAYCONFIG_MODE_INFO[modeCount]; + err = CCDImport.QueryDisplayConfig(QDC.QDC_ONLY_ACTIVE_PATHS, ref pathCount, paths, ref modeCount, modes, IntPtr.Zero); + if (err == WIN32STATUS.ERROR_INSUFFICIENT_BUFFER) + { + SharedLogger.logger.Error($"NVIDIALibrary/GetSomeDisplayIdentifiers: ERROR - The displays were still modified between GetDisplayConfigBufferSizes and QueryDisplayConfig, even though we tried twice. Something is wrong."); + throw new NVIDIALibraryException($"The displays were still modified between GetDisplayConfigBufferSizes and QueryDisplayConfig, even though we tried twice. Something is wrong."); + } + else if (err != WIN32STATUS.ERROR_SUCCESS) + { + SharedLogger.logger.Error($"NVIDIALibrary/GetSomeDisplayIdentifiers: ERROR - QueryDisplayConfig returned WIN32STATUS {err} when trying to query all available displays again"); + throw new NVIDIALibraryException($"QueryDisplayConfig returned WIN32STATUS {err} when trying to query all available displays again."); + } + } + else if (err != WIN32STATUS.ERROR_SUCCESS) + { + SharedLogger.logger.Error($"NVIDIALibrary/GetSomeDisplayIdentifiers: ERROR - QueryDisplayConfig returned WIN32STATUS {err} when trying to query all available displays"); + throw new NVIDIALibraryException($"QueryDisplayConfig returned WIN32STATUS {err} when trying to query all available displays."); + } + + foreach (var path in paths) + { + if (path.TargetInfo.TargetAvailable == false) + { + // We want to skip this one cause it's not valid + SharedLogger.logger.Trace($"NVIDIALibrary/GetSomeDisplayIdentifiers: Skipping path due to TargetAvailable not existing in display #{path.TargetInfo.Id}"); + continue; + } + + // get display source name + var sourceInfo = new DISPLAYCONFIG_SOURCE_DEVICE_NAME(); + sourceInfo.Header.Type = DISPLAYCONFIG_DEVICE_INFO_TYPE.DISPLAYCONFIG_DEVICE_INFO_GET_SOURCE_NAME; + sourceInfo.Header.Size = (uint)Marshal.SizeOf(); + sourceInfo.Header.AdapterId = path.SourceInfo.AdapterId; + sourceInfo.Header.Id = path.SourceInfo.Id; + err = CCDImport.DisplayConfigGetDeviceInfo(ref sourceInfo); + if (err == WIN32STATUS.ERROR_SUCCESS) + { + SharedLogger.logger.Trace($"NVIDIALibrary/GetSomeDisplayIdentifiers: Successfully got the source info from {path.SourceInfo.Id}."); + } + else + { + SharedLogger.logger.Warn($"NVIDIALibrary/GetSomeDisplayIdentifiers: WARNING - DisplayConfigGetDeviceInfo returned WIN32STATUS {err} when trying to get the target info for display #{path.SourceInfo.Id}"); + } + + // get display target name + var targetInfo = new DISPLAYCONFIG_TARGET_DEVICE_NAME(); + targetInfo.Header.Type = DISPLAYCONFIG_DEVICE_INFO_TYPE.DISPLAYCONFIG_DEVICE_INFO_GET_TARGET_NAME; + targetInfo.Header.Size = (uint)Marshal.SizeOf(); + targetInfo.Header.AdapterId = path.TargetInfo.AdapterId; + targetInfo.Header.Id = path.TargetInfo.Id; + err = CCDImport.DisplayConfigGetDeviceInfo(ref targetInfo); + if (err == WIN32STATUS.ERROR_SUCCESS) + { + SharedLogger.logger.Trace($"NVIDIALibrary/GetSomeDisplayIdentifiers: Successfully got the target info from {path.TargetInfo.Id}."); + } + else + { + SharedLogger.logger.Warn($"NVIDIALibrary/GetSomeDisplayIdentifiers: WARNING - DisplayConfigGetDeviceInfo returned WIN32STATUS {err} when trying to get the target info for display #{path.TargetInfo.Id}"); + } + + // get display adapter name + var adapterInfo = new DISPLAYCONFIG_ADAPTER_NAME(); + adapterInfo.Header.Type = DISPLAYCONFIG_DEVICE_INFO_TYPE.DISPLAYCONFIG_DEVICE_INFO_GET_ADAPTER_NAME; + adapterInfo.Header.Size = (uint)Marshal.SizeOf(); + adapterInfo.Header.AdapterId = path.TargetInfo.AdapterId; + adapterInfo.Header.Id = path.TargetInfo.Id; + err = CCDImport.DisplayConfigGetDeviceInfo(ref adapterInfo); + if (err == WIN32STATUS.ERROR_SUCCESS) + { + SharedLogger.logger.Trace($"NVIDIALibrary/GetSomeDisplayIdentifiers: Successfully got the display name info from {path.TargetInfo.Id}."); + } + else + { + SharedLogger.logger.Warn($"NVIDIALibrary/GetSomeDisplayIdentifiers: WARNING - DisplayConfigGetDeviceInfo returned WIN32STATUS {err} when trying to get the target info for display #{path.TargetInfo.Id}"); + } + + // Create an array of all the important display info we need to record + List displayInfo = new List(); + displayInfo.Add("WINAPI"); + try + { + displayInfo.Add(adapterInfo.AdapterDevicePath.ToString()); + } + catch (Exception ex) + { + SharedLogger.logger.Warn(ex, $"NVIDIALibrary/GetSomeDisplayIdentifiers: Exception getting Windows Display Adapter Device Path from video card. Substituting with a # instead"); + displayInfo.Add("#"); + } + try + { + displayInfo.Add(targetInfo.OutputTechnology.ToString()); + } + catch (Exception ex) + { + SharedLogger.logger.Warn(ex, $"NVIDIALibrary/GetSomeDisplayIdentifiers: Exception getting Windows Display Connector Instance from video card. Substituting with a # instead"); + displayInfo.Add("#"); + } + try + { + displayInfo.Add(targetInfo.EdidManufactureId.ToString()); + } + catch (Exception ex) + { + SharedLogger.logger.Warn(ex, $"NVIDIALibrary/GetSomeDisplayIdentifiers: Exception getting Windows Display EDID Manufacturer Code from video card. Substituting with a # instead"); + displayInfo.Add("#"); + } + try + { + displayInfo.Add(targetInfo.EdidProductCodeId.ToString()); + } + catch (Exception ex) + { + SharedLogger.logger.Warn(ex, $"NVIDIALibrary/GetSomeDisplayIdentifiers: Exception getting Windows Display EDID Product Code from video card. Substituting with a # instead"); + displayInfo.Add("#"); + } + try + { + displayInfo.Add(targetInfo.MonitorFriendlyDeviceName.ToString()); + } + catch (Exception ex) + { + SharedLogger.logger.Warn(ex, $"NVIDIALibrary/GetSomeDisplayIdentifiers: Exception getting Windows Display Target Friendly name from video card. Substituting with a # instead"); + displayInfo.Add("#"); + } + + // Create a display identifier out of it + string displayIdentifier = String.Join("|", displayInfo); + // Add it to the list of display identifiers so we can return it + // but only add it if it doesn't already exist. Otherwise we get duplicates :/ + if (!displayIdentifiers.Contains(displayIdentifier)) + { + displayIdentifiers.Add(displayIdentifier); + SharedLogger.logger.Debug($"ProfileRepository/GenerateProfileDisplayIdentifiers: DisplayIdentifier: {displayIdentifier}"); + } + + } + + // Sort the display identifiers + displayIdentifiers.Sort(); + + return displayIdentifiers; + } + } -} + + [global::System.Serializable] + public class NVIDIALibraryException : Exception + { + public NVIDIALibraryException() { } + public NVIDIALibraryException(string message) : base(message) { } + public NVIDIALibraryException(string message, Exception inner) : base(message, inner) { } + protected NVIDIALibraryException( + System.Runtime.Serialization.SerializationInfo info, + System.Runtime.Serialization.StreamingContext context) : base(info, context) { } + } +} \ No newline at end of file diff --git a/DisplayMagicianShared/NVIDIA/NVIDIAProfileItem.cs b/DisplayMagicianShared/NVIDIA/NVIDIAProfileItem.cs index 4dfca2c..6080f5a 100644 --- a/DisplayMagicianShared/NVIDIA/NVIDIAProfileItem.cs +++ b/DisplayMagicianShared/NVIDIA/NVIDIAProfileItem.cs @@ -95,7 +95,7 @@ namespace DisplayMagicianShared.NVIDIA { if (_profileDisplayIdentifiers.Count == 0) { - _profileDisplayIdentifiers = NVIDIALibrary.GetLibrary().GenerateProfileDisplayIdentifiers(); + _profileDisplayIdentifiers = NVIDIALibrary.GetLibrary().GetCurrentDisplayIdentifiers(); } return _profileDisplayIdentifiers; } @@ -168,7 +168,7 @@ namespace DisplayMagicianShared.NVIDIA // Prepare our profile data for saving if (_profileDisplayIdentifiers.Count == 0) { - _profileDisplayIdentifiers = NVIDIALibrary.GetLibrary().GenerateProfileDisplayIdentifiers(); + _profileDisplayIdentifiers = NVIDIALibrary.GetLibrary().GetCurrentDisplayIdentifiers(); } // Return if it is valid and we should continue diff --git a/DisplayMagicianShared/ProfileItem.cs b/DisplayMagicianShared/ProfileItem.cs index d0a03b5..1d51441 100644 --- a/DisplayMagicianShared/ProfileItem.cs +++ b/DisplayMagicianShared/ProfileItem.cs @@ -245,7 +245,7 @@ namespace DisplayMagicianShared { if (_profileDisplayIdentifiers.Count == 0) { - _profileDisplayIdentifiers = ProfileRepository.GenerateProfileDisplayIdentifiers(); + _profileDisplayIdentifiers = ProfileRepository.GetCurrentDisplayIdentifiers(); } return _profileDisplayIdentifiers; } @@ -363,7 +363,7 @@ namespace DisplayMagicianShared // Prepare our profile data for saving if (_profileDisplayIdentifiers.Count == 0) { - _profileDisplayIdentifiers = ProfileRepository.GenerateProfileDisplayIdentifiers(); + _profileDisplayIdentifiers = ProfileRepository.GetCurrentDisplayIdentifiers(); } // Return if it is valid and we should continue diff --git a/DisplayMagicianShared/ProfileRepository.cs b/DisplayMagicianShared/ProfileRepository.cs index 10602ac..39af9ab 100644 --- a/DisplayMagicianShared/ProfileRepository.cs +++ b/DisplayMagicianShared/ProfileRepository.cs @@ -14,6 +14,7 @@ using System.Text.RegularExpressions; using NvAPIWrapper.Native.GPU; using DisplayMagicianShared.AMD; using DisplayMagicianShared.NVIDIA; +using DisplayMagicianShared.Windows; using System.Windows.Forms; namespace DisplayMagicianShared @@ -168,7 +169,7 @@ namespace DisplayMagicianShared { if (_connectedDisplayIdentifiers.Count == 0) // Load the Profiles from storage if they need to be - _connectedDisplayIdentifiers = GenerateAllAvailableDisplayIdentifiers(); + _connectedDisplayIdentifiers = GetAllConnectedDisplayIdentifiers(); return _connectedDisplayIdentifiers; @@ -574,14 +575,28 @@ namespace DisplayMagicianShared SharedLogger.logger.Debug($"ProfileRepository/UpdateActiveProfile: Updating the profile currently active (in use now)."); - SharedLogger.logger.Debug($"ProfileRepository/UpdateActiveProfile: Trying to access things using the AMD video card driver"); - // If we're using the AMD library - AMDLibrary amdLibrary = AMDLibrary.GetLibrary(); - if (amdLibrary.IsInstalled) - { + SharedLogger.logger.Debug($"ProfileRepository/UpdateActiveProfile: Attempting to access configuration through NVIDIA, then AMD, then Windows CCD interfaces, in that order."); + if (NVIDIALibrary.GetLibrary().IsInstalled) + { + SharedLogger.logger.Debug($"ProfileRepository/UpdateActiveProfile: NVIDIA NVAPI Driver is installed, so using that for this display profile."); + NVIDIAProfileItem nvidiaProfile = new NVIDIAProfileItem + { + Name = "Current NVIDIA Display Profile", + //ProfileData = amdLibrary.GetActiveProfile(), + //Screens = amdLibrary.GenerateScreenPositions() + //ProfileDisplayIdentifiers = ProfileRepository.GenerateProfileDisplayIdentifiers() + }; + //activeProfile.ProfileIcon = new ProfileIcon(activeProfile); + //activeProfile.ProfileBitmap = activeProfile.ProfileIcon.ToBitmap(256, 256); + nvidiaProfile.CreateProfileFromCurrentDisplaySettings(); + activeProfile = nvidiaProfile; + } + else if (AMDLibrary.GetLibrary().IsInstalled) + { + SharedLogger.logger.Debug($"ProfileRepository/UpdateActiveProfile: NVIDIA is not installed but the AMD ADL Driver IS installed, so using that for this display profile."); AMDProfileItem amdProfile = new AMDProfileItem { - Name = "Current Display Profile" , + Name = "Current AMD Display Profile" , //ProfileData = amdLibrary.GetActiveProfile(), //Screens = amdLibrary.GenerateScreenPositions() //ProfileDisplayIdentifiers = ProfileRepository.GenerateProfileDisplayIdentifiers() @@ -592,16 +607,18 @@ namespace DisplayMagicianShared activeProfile = amdProfile; } else { - SharedLogger.logger.Debug($"ProfileRepository/UpdateActiveProfile: Trying to access things using the NVIDIA video card driver"); - activeProfile = new NVIDIAProfileItem + SharedLogger.logger.Debug($"ProfileRepository/UpdateActiveProfile: Neither NVIDIA NVAPI or AMD ADL Drivers are installed, so using the built in Windows CCD library interface for this display profile."); + WinProfileItem winProfile = new WinProfileItem { - Name = "Current Display Profile", - Paths = PathInfo.GetActivePaths().Select(info => new DisplayMagicianShared.Topology.Path(info)).ToArray(), + Name = "Current Windows Display Profile", + //Paths = PathInfo.GetActivePaths().Select(info => new DisplayMagicianShared.Topology.Path(info)).ToArray(), //ProfileDisplayIdentifiers = ProfileRepository.GenerateProfileDisplayIdentifiers() }; - activeProfile.ProfileIcon = new ProfileIcon(activeProfile); - activeProfile.ProfileBitmap = activeProfile.ProfileIcon.ToBitmap(256, 256); + //WinProfile.ProfileIcon = new ProfileIcon(activeProfile); + //activeProfile.ProfileBitmap = activeProfile.ProfileIcon.ToBitmap(256, 256); + winProfile.CreateProfileFromCurrentDisplaySettings(); + activeProfile = winProfile; } @@ -826,7 +843,7 @@ namespace DisplayMagicianShared { // We need to refresh the cached answer // Get the list of connected devices - ConnectedDisplayIdentifiers = GenerateAllAvailableDisplayIdentifiers(); + ConnectedDisplayIdentifiers = GetAllConnectedDisplayIdentifiers(); if (_profilesLoaded && _allProfiles.Count > 0) { @@ -837,696 +854,41 @@ namespace DisplayMagicianShared } - public static List GenerateProfileDisplayIdentifiers() + public static List GetAllConnectedDisplayIdentifiers() { - SharedLogger.logger.Debug($"ProfileRepository/GenerateProfileDisplayIdentifiers: Generating the unique Display Identifiers for the currently active profile"); - - List displayIdentifiers = new List(); - bool isNvidia = false; - //bool isAMD = false; - - // If the Video Card is an NVidia, then we should generate specific NVidia displayIdentifiers - - NvAPIWrapper.GPU.PhysicalGPU[] myPhysicalGPUs = null; - try + if (NVIDIALibrary.GetLibrary().IsInstalled) { - myPhysicalGPUs = NvAPIWrapper.GPU.PhysicalGPU.GetPhysicalGPUs(); - isNvidia = true; - SharedLogger.logger.Debug($"ProfileRepository/GenerateProfileDisplayIdentifiers: The video card is a NVIDIA video card."); + return NVIDIALibrary.GetLibrary().GetAllConnectedDisplayIdentifiers(); } - catch (Exception ex) + else if (AMDLibrary.GetLibrary().IsInstalled) { - SharedLogger.logger.Debug(ex, "ProfileRepository/GenerateProfileDisplayIdentifiers: Attemped to get GetPhysicalCPUs through NvAPIWrapper library but got exception. This means the video card isn't compatible with the NvAPIWrapper library we use. It is unlikely to be an NVIDIA video card."); + return AMDLibrary.GetLibrary().GetAllConnectedDisplayIdentifiers(); } - if (isNvidia && myPhysicalGPUs != null && myPhysicalGPUs.Length > 0) - //if (false) + else { - SharedLogger.logger.Debug($"ProfileRepository/GenerateProfileDisplayIdentifiers: We were able to GetPhysicalCPUs through NvAPIWrapper library. There are {myPhysicalGPUs.Length} Physical GPUs detected"); - - foreach (NvAPIWrapper.GPU.PhysicalGPU myPhysicalGPU in myPhysicalGPUs) - { - // get a list of all physical outputs attached to the GPUs - NvAPIWrapper.GPU.GPUOutput[] myGPUOutputs = myPhysicalGPU.ActiveOutputs; - foreach (NvAPIWrapper.GPU.GPUOutput aGPUOutput in myGPUOutputs) - { - SharedLogger.logger.Debug($"ProfileRepository/GenerateProfileDisplayIdentifiers: We were able to detect {myGPUOutputs.Length} outputs"); - // Figure out the displaydevice attached to the output - NvAPIWrapper.Display.DisplayDevice aConnectedDisplayDevice = myPhysicalGPU.GetDisplayDeviceByOutput(aGPUOutput); - - // Create an array of all the important display info we need to record - List displayInfo = new List(); - displayInfo.Add("NVIDIA"); - try - { - displayInfo.Add(myPhysicalGPU.ArchitectInformation.ShortName.ToString()); - } - catch(Exception ex) - { - SharedLogger.logger.Warn(ex,$"ProfileRepository/GenerateProfileDisplayIdentifiers: Exception getting NVIDIA Architecture ShortName from video card. Substituting with a # instead"); - displayInfo.Add("#"); - } - try - { - displayInfo.Add(myPhysicalGPU.ArchitectInformation.Revision.ToString()); - } - catch (Exception ex) - { - SharedLogger.logger.Warn(ex, $"ProfileRepository/GenerateProfileDisplayIdentifiers: Exception getting NVIDIA Architecture Revision from video card. Substituting with a # instead"); - displayInfo.Add("#"); - } - try - { - displayInfo.Add(myPhysicalGPU.Board.ToString()); - } - catch (Exception ex) - { - SharedLogger.logger.Warn(ex, $"ProfileRepository/GenerateProfileDisplayIdentifiers: Exception getting NVIDIA Board details from video card. Substituting with a # instead"); - displayInfo.Add("#"); - } - try - { - displayInfo.Add(myPhysicalGPU.Foundry.ToString()); - } - catch (Exception ex) - { - SharedLogger.logger.Warn(ex, $"ProfileRepository/GenerateProfileDisplayIdentifiers: Exception getting NVIDIA Foundry from video card. Substituting with a # instead"); - displayInfo.Add("#"); - } - try - { - displayInfo.Add(myPhysicalGPU.GPUId.ToString()); - } - catch (Exception ex) - { - SharedLogger.logger.Warn(ex, $"ProfileRepository/GenerateProfileDisplayIdentifiers: Exception getting NVIDIA GPUId from video card. Substituting with a # instead"); - displayInfo.Add("#"); - } - try - { - displayInfo.Add(myPhysicalGPU.GPUType.ToString()); - } - catch (Exception ex) - { - SharedLogger.logger.Warn(ex, $"ProfileRepository/GenerateProfileDisplayIdentifiers: Exception getting NVIDIA GPUType from video card. Substituting with a # instead"); - displayInfo.Add("#"); - } - try - { - displayInfo.Add(aConnectedDisplayDevice.ConnectionType.ToString()); - } - catch (Exception ex) - { - SharedLogger.logger.Warn(ex, $"ProfileRepository/GenerateProfileDisplayIdentifiers: Exception getting NVIDIA Connection from video card. Substituting with a # instead"); - displayInfo.Add("#"); - } - try - { - displayInfo.Add(aConnectedDisplayDevice.DisplayId.ToString()); - } - catch (Exception ex) - { - SharedLogger.logger.Warn(ex, $"ProfileRepository/GenerateProfileDisplayIdentifiers: Exception getting NVIDIA DisplayID from video card. Substituting with a # instead"); - displayInfo.Add("#"); - } - - // Create a display identifier out of it - string displayIdentifier = String.Join("|", displayInfo); - // Add it to the list of display identifiers so we can return it - displayIdentifiers.Add(displayIdentifier); - - SharedLogger.logger.Debug($"ProfileRepository/GenerateProfileDisplayIdentifiers: DisplayIdentifier: {displayIdentifier}"); - } - - } + return WinLibrary.GetLibrary().GetAllConnectedDisplayIdentifiers(); } - // else if there is an AMD video card then we use that mode - else if (AMDLibrary.IsInstalled) - { - //isAMD = true; - SharedLogger.logger.Debug($"ProfileRepository/GenerateProfileDisplayIdentifiers: The video card is an AMD video card."); - // Needs a lot of work here! We need to check if the AMD returned the right stuff, and then use Windows if there is an error. - return AMDLibrary.GenerateProfileDisplayIdentifiers(); - } - // else video card is not NVIDIA or AMD so we just use the standard WindowsAPI access method - else - { - // Then go through the adapters we have running using the WindowsDisplayAPI - List attachedDisplayDevices = Display.GetDisplays().ToList(); - - SharedLogger.logger.Debug($"ProfileRepository/GenerateProfileDisplayIdentifiers: We are using the standard Windows Display API to figure out what display devices are attached and available. There are {attachedDisplayDevices.Count} display devices detected."); - - foreach (Display attachedDisplay in attachedDisplayDevices) - { - DisplayAdapter displayAdapter = null; - PathDisplayAdapter pathDisplayAdapter = null; - PathDisplaySource pathDisplaySource = null; - PathDisplayTarget pathDisplayTarget = null; - - - try - { - // We keep these lines here to detect if there is an exception so we can report it - // nicely to the user. - displayAdapter = attachedDisplay.Adapter; - pathDisplayAdapter = displayAdapter.ToPathDisplayAdapter(); - pathDisplaySource = attachedDisplay.ToPathDisplaySource(); - pathDisplayTarget = attachedDisplay.ToPathDisplayTarget(); - - // This line is just to force an EDID lookup first up so that we can deterine if there is an issue - // with the Monitor, and then tell the user - string EDIDManufacturerId = pathDisplayTarget.EDIDManufactureId.ToString(); - - // print some trace messages so we can figure out issues if needed later - SharedLogger.logger.Trace($"ProfileRepository/GenerateProfileDisplayIdentifiers: ADDN : {attachedDisplay.DeviceName}"); - SharedLogger.logger.Trace($"ProfileRepository/GenerateProfileDisplayIdentifiers: ADDFN : {attachedDisplay.DisplayFullName}"); - SharedLogger.logger.Trace($"ProfileRepository/GenerateProfileDisplayIdentifiers: ADDIN : {attachedDisplay.DisplayName}"); - SharedLogger.logger.Trace($"ProfileRepository/GenerateProfileDisplayIdentifiers: ADDIN : {attachedDisplay.IsAvailable}"); - SharedLogger.logger.Trace($"ProfileRepository/GenerateProfileDisplayIdentifiers: ADDIGP : {attachedDisplay.IsGDIPrimary}"); - SharedLogger.logger.Trace($"ProfileRepository/GenerateProfileDisplayIdentifiers: ADDIV : {attachedDisplay.IsValid}"); - SharedLogger.logger.Trace($"ProfileRepository/GenerateProfileDisplayIdentifiers: ADCSCD : {attachedDisplay.CurrentSetting.ColorDepth}"); - SharedLogger.logger.Trace($"ProfileRepository/GenerateProfileDisplayIdentifiers: ADCSF : {attachedDisplay.CurrentSetting.Frequency}"); - SharedLogger.logger.Trace($"ProfileRepository/GenerateProfileDisplayIdentifiers: ADCSIE : {attachedDisplay.CurrentSetting.IsEnable}"); - SharedLogger.logger.Trace($"ProfileRepository/GenerateProfileDisplayIdentifiers: ADCSII : {attachedDisplay.CurrentSetting.IsInterlaced}"); - SharedLogger.logger.Trace($"ProfileRepository/GenerateProfileDisplayIdentifiers: ADCSO : {attachedDisplay.CurrentSetting.Orientation}"); - SharedLogger.logger.Trace($"ProfileRepository/GenerateProfileDisplayIdentifiers: ADCSOSM : {attachedDisplay.CurrentSetting.OutputScalingMode}"); - SharedLogger.logger.Trace($"ProfileRepository/GenerateProfileDisplayIdentifiers: ADCSP : {attachedDisplay.CurrentSetting.Position}"); - SharedLogger.logger.Trace($"ProfileRepository/GenerateProfileDisplayIdentifiers: ADCSR : {attachedDisplay.CurrentSetting.Resolution}"); - SharedLogger.logger.Trace($"ProfileRepository/GenerateProfileDisplayIdentifiers: DP : {displayAdapter.DevicePath}"); - SharedLogger.logger.Trace($"ProfileRepository/GenerateProfileDisplayIdentifiers: DK : {displayAdapter.DeviceKey}"); - SharedLogger.logger.Trace($"ProfileRepository/GenerateProfileDisplayIdentifiers: DN : {displayAdapter.DeviceName}"); - SharedLogger.logger.Trace($"ProfileRepository/GenerateProfileDisplayIdentifiers: DK : {displayAdapter.DeviceKey}"); - SharedLogger.logger.Trace($"ProfileRepository/GenerateProfileDisplayIdentifiers: AI : {pathDisplayAdapter.AdapterId}"); - SharedLogger.logger.Trace($"ProfileRepository/GenerateProfileDisplayIdentifiers: AIDP : {pathDisplayAdapter.DevicePath}"); - SharedLogger.logger.Trace($"ProfileRepository/GenerateProfileDisplayIdentifiers: AIII : {pathDisplayAdapter.IsInvalid}"); - SharedLogger.logger.Trace($"ProfileRepository/GenerateProfileDisplayIdentifiers: DDA : {displayAdapter.DeviceName}"); - SharedLogger.logger.Trace($"ProfileRepository/GenerateProfileDisplayIdentifiers: PDSA : {pathDisplaySource.Adapter}"); - SharedLogger.logger.Trace($"ProfileRepository/GenerateProfileDisplayIdentifiers: PDSCDS : {pathDisplaySource.CurrentDPIScale}"); - SharedLogger.logger.Trace($"ProfileRepository/GenerateProfileDisplayIdentifiers: PDSDN : {pathDisplaySource.DisplayName}"); - SharedLogger.logger.Trace($"ProfileRepository/GenerateProfileDisplayIdentifiers: PDSMDS : {pathDisplaySource.MaximumDPIScale}"); - SharedLogger.logger.Trace($"ProfileRepository/GenerateProfileDisplayIdentifiers: PDSRDS : {pathDisplaySource.RecommendedDPIScale}"); - SharedLogger.logger.Trace($"ProfileRepository/GenerateProfileDisplayIdentifiers: PDSSI : {pathDisplaySource.SourceId}"); - SharedLogger.logger.Trace($"ProfileRepository/GenerateProfileDisplayIdentifiers: PDTA : {pathDisplayTarget.Adapter}"); - SharedLogger.logger.Trace($"ProfileRepository/GenerateProfileDisplayIdentifiers: PDTCI : {pathDisplayTarget.ConnectorInstance}"); - SharedLogger.logger.Trace($"ProfileRepository/GenerateProfileDisplayIdentifiers: PDTDP : {pathDisplayTarget.DevicePath}"); - SharedLogger.logger.Trace($"ProfileRepository/GenerateProfileDisplayIdentifiers: PDTEMC : {pathDisplayTarget.EDIDManufactureCode}"); - SharedLogger.logger.Trace($"ProfileRepository/GenerateProfileDisplayIdentifiers: PDTEMI : {pathDisplayTarget.EDIDManufactureId}"); - SharedLogger.logger.Trace($"ProfileRepository/GenerateProfileDisplayIdentifiers: PDTEPC : {pathDisplayTarget.EDIDProductCode}"); - SharedLogger.logger.Trace($"ProfileRepository/GenerateProfileDisplayIdentifiers: PDTFN : {pathDisplayTarget.FriendlyName}"); - SharedLogger.logger.Trace($"ProfileRepository/GenerateProfileDisplayIdentifiers: PDTIA : {pathDisplayTarget.IsAvailable}"); - SharedLogger.logger.Trace($"ProfileRepository/GenerateProfileDisplayIdentifiers: PDTPR : {pathDisplayTarget.PreferredResolution}"); - SharedLogger.logger.Trace($"ProfileRepository/GenerateProfileDisplayIdentifiers: PDTPSM : {pathDisplayTarget.PreferredSignalMode}"); - SharedLogger.logger.Trace($"ProfileRepository/GenerateProfileDisplayIdentifiers: PDTTI : {pathDisplayTarget.TargetId}"); - SharedLogger.logger.Trace($"ProfileRepository/GenerateProfileDisplayIdentifiers: PDTVRS : {pathDisplayTarget.VirtualResolutionSupport}"); - } - catch (WindowsDisplayAPI.Exceptions.InvalidEDIDInformation ex) - { - SharedLogger.logger.Error(ex, $"ProfileRepository/GenerateProfileDisplayIdentifiers: Exception while trying to get information from your monitor {attachedDisplay.DisplayFullName} about it's configuration. DisplayMagician may not be able to use this monitor!"); - if (!notifiedEDIDErrorToUser) - { - MessageBox.Show( - $"Your monitor {attachedDisplay.DisplayFullName} is not responding when we ask about it's configuration. DisplayMagician may not be able to use this monitor!", @"DisplayMagician cannot talk to your monitor", - MessageBoxButtons.OK, - MessageBoxIcon.Error); - notifiedEDIDErrorToUser = true; - } - } - catch (WindowsDisplayAPI.Exceptions.TargetNotAvailableException ex) - { - SharedLogger.logger.Error(ex, $"ProfileRepository/GenerateProfileDisplayIdentifiers: Exception while we were trying to access the DisplayTarget to gather information about your display configuration."); - } - catch (Exception ex) - { - SharedLogger.logger.Warn(ex, $"ProfileRepository/GenerateProfileDisplayIdentifiers: Exception accessing one of the WindowsDisplayAPI items to print it out during a TRACE session"); - } - - // Create an array of all the important display info we need to record - List displayInfo = new List(); - displayInfo.Add("WINAPI"); - try - { - displayInfo.Add(displayAdapter.DeviceName.ToString()); - } - catch (Exception ex) - { - SharedLogger.logger.Warn(ex, $"ProfileRepository/GenerateProfileDisplayIdentifiers: Exception getting Windows Display Adapter Device name from video card. Substituting with a # instead"); - displayInfo.Add("#"); - } - try - { - displayInfo.Add(pathDisplayAdapter.AdapterId.ToString()); - } - catch (Exception ex) - { - SharedLogger.logger.Warn(ex, $"ProfileRepository/GenerateProfileDisplayIdentifiers: Exception getting Windows Display Adapter ID from video card. Substituting with a # instead"); - displayInfo.Add("#"); - } - try - { - displayInfo.Add(pathDisplayTarget.ConnectorInstance.ToString()); - } - catch (WindowsDisplayAPI.Exceptions.TargetNotAvailableException ex) - { - SharedLogger.logger.Error(ex, $"ProfileRepository/GenerateProfileDisplayIdentifiers: Exception2 while we were trying to access the DisplayTarget to gather information about your display configuration."); - } - catch (Exception ex) - { - SharedLogger.logger.Warn(ex, $"ProfileRepository/GenerateProfileDisplayIdentifiers: Exception getting Windows Display Target Connector Instance from video card. Substituting with a # instead"); - displayInfo.Add("#"); - } - try - { - displayInfo.Add(pathDisplayTarget.FriendlyName); - } - catch (Exception ex) - { - SharedLogger.logger.Warn(ex, $"ProfileRepository/GenerateProfileDisplayIdentifiers: Exception getting Windows Display Target Friendly name from video card. Substituting with a # instead"); - displayInfo.Add("#"); - } - try - { - displayInfo.Add(pathDisplayTarget.EDIDManufactureCode.ToString()); - } - catch (WindowsDisplayAPI.Exceptions.InvalidEDIDInformation ex) - { - SharedLogger.logger.Error(ex, $"ProfileRepository/GenerateProfileDisplayIdentifiers2: Exception while trying to get information from your monitor {attachedDisplay.DisplayFullName} about it's configuration. DisplayMagician may not be able to use this monitor!"); - } - catch (WindowsDisplayAPI.Exceptions.TargetNotAvailableException ex) - { - SharedLogger.logger.Error(ex, $"ProfileRepository/GenerateProfileDisplayIdentifiers2: Exception while we were trying to access the DisplayTarget to gather information about your display configuration."); - } - catch (Exception ex) - { - SharedLogger.logger.Warn(ex, $"ProfileRepository/GenerateProfileDisplayIdentifiers2: Exception getting Windows Display EDID Manufacturer Code from video card. Substituting with a # instead"); - displayInfo.Add("#"); - } - try - { - displayInfo.Add(pathDisplayTarget.EDIDManufactureId.ToString()); - } - catch (WindowsDisplayAPI.Exceptions.InvalidEDIDInformation ex) - { - SharedLogger.logger.Error(ex, $"ProfileRepository/GenerateProfileDisplayIdentifiers3: Exception while trying to get information from your monitor {attachedDisplay.DisplayFullName} about it's configuration. DisplayMagician may not be able to use this monitor!"); - } - catch (WindowsDisplayAPI.Exceptions.TargetNotAvailableException ex) - { - SharedLogger.logger.Error(ex, $"ProfileRepository/GenerateProfileDisplayIdentifiers3: Exception while we were trying to access the DisplayTarget to gather information about your display configuration."); - } - catch (Exception ex) - { - SharedLogger.logger.Warn(ex, $"ProfileRepository/GenerateProfileDisplayIdentifiers3: Exception getting Windows Display EDID Manufacturer ID from video card. Substituting with a # instead"); - displayInfo.Add("#"); - } - try - { - displayInfo.Add(pathDisplayTarget.EDIDProductCode.ToString()); - } - catch (WindowsDisplayAPI.Exceptions.InvalidEDIDInformation ex) - { - SharedLogger.logger.Error(ex, $"ProfileRepository/GenerateProfileDisplayIdentifiers4: Exception while trying to get information from your monitor {attachedDisplay.DisplayFullName} about it's configuration. DisplayMagician may not be able to use this monitor!"); - } - catch (WindowsDisplayAPI.Exceptions.TargetNotAvailableException ex) - { - SharedLogger.logger.Error(ex, $"ProfileRepository/GenerateProfileDisplayIdentifiers4: Exception while we were trying to access the DisplayTarget to gather information about your display configuration."); - } - catch (Exception ex) - { - SharedLogger.logger.Warn(ex, $"ProfileRepository/GenerateProfileDisplayIdentifiers4: Exception getting Windows Display EDID Product Code from video card. Substituting with a # instead"); - displayInfo.Add("#"); - } - try - { - displayInfo.Add(pathDisplayTarget.TargetId.ToString()); - } - catch (Exception ex) - { - SharedLogger.logger.Warn(ex, $"ProfileRepository/GenerateProfileDisplayIdentifiers: Exception getting Windows Display Target ID from video card. Substituting with a # instead"); - displayInfo.Add("#"); - } - - // Create a display identifier out of it - string displayIdentifier = String.Join("|", displayInfo); - // Add it to the list of display identifiers so we can return it - displayIdentifiers.Add(displayIdentifier); - SharedLogger.logger.Debug($"ProfileRepository/GenerateProfileDisplayIdentifiers: DisplayIdentifier: {displayIdentifier}"); - - } - - } - - // Sort the display identifiers - displayIdentifiers.Sort(); - - return displayIdentifiers; } - public static List GenerateAllAvailableDisplayIdentifiers() + public static List GetCurrentDisplayIdentifiers() { - SharedLogger.logger.Debug($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: Generating all the Display Identifiers currently active now"); - - List displayIdentifiers = new List(); - - // If the Video Card is an NVidia, then we should generate specific NVidia displayIdentifiers - bool isNvidia = false; - NvAPIWrapper.GPU.PhysicalGPU[] myPhysicalGPUs = null; - try + if (NVIDIALibrary.GetLibrary().IsInstalled) { - myPhysicalGPUs = NvAPIWrapper.GPU.PhysicalGPU.GetPhysicalGPUs(); - isNvidia = true; - SharedLogger.logger.Debug($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: The video card is a NVIDIA video card."); + return NVIDIALibrary.GetLibrary().GetCurrentDisplayIdentifiers(); } - catch (Exception ex) + else if (AMDLibrary.GetLibrary().IsInstalled) { - SharedLogger.logger.Debug(ex, "ProfileRepository/GenerateAllAvailableDisplayIdentifiers: Attemped to get GetPhysicalCPUs through NvAPIWrapper library but got exception. This means the video card isn't compatible with the NvAPIWrapper library we use. It is unlikely to be an NVIDIA video card."); + return AMDLibrary.GetLibrary().GetCurrentDisplayIdentifiers(); } - - // If the Video Card is an AMD, then we should generate specific AMD displayIdentifiers - AMD.AMDLibrary thingy = new AMD.AMDLibrary(); - - if (isNvidia && myPhysicalGPUs != null && myPhysicalGPUs.Length > 0) - //if (false) - { - SharedLogger.logger.Debug($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: We were able to GetPhysicalCPUs through NvAPIWrapper library. There are {myPhysicalGPUs.Length} Physical GPUs detected"); - - foreach (NvAPIWrapper.GPU.PhysicalGPU myPhysicalGPU in myPhysicalGPUs) - { - // get a list of all physical outputs attached to the GPUs - NvAPIWrapper.Display.DisplayDevice[] allDisplayDevices = myPhysicalGPU.GetConnectedDisplayDevices(ConnectedIdsFlag.None); - - SharedLogger.logger.Debug($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: We were able to detect {allDisplayDevices.Length} connected devices"); - foreach (NvAPIWrapper.Display.DisplayDevice aDisplayDevice in allDisplayDevices) - { - - if (aDisplayDevice.IsAvailable== true) - { - // Create an array of all the important display info we need to record - List displayInfo = new List(); - displayInfo.Add("NVIDIA"); - try - { - displayInfo.Add(myPhysicalGPU.ArchitectInformation.ShortName.ToString()); - } - catch (Exception ex) - { - SharedLogger.logger.Warn(ex, $"ProfileRepository/GenerateProfileDisplayIdentifiers: Exception getting NVIDIA Architecture ShortName from video card. Substituting with a # instead"); - displayInfo.Add("#"); - } - try - { - displayInfo.Add(myPhysicalGPU.ArchitectInformation.Revision.ToString()); - } - catch (Exception ex) - { - SharedLogger.logger.Warn(ex, $"ProfileRepository/GenerateProfileDisplayIdentifiers: Exception getting NVIDIA Architecture Revision from video card. Substituting with a # instead"); - displayInfo.Add("#"); - } - try - { - displayInfo.Add(myPhysicalGPU.Board.ToString()); - } - catch (Exception ex) - { - SharedLogger.logger.Warn(ex, $"ProfileRepository/GenerateProfileDisplayIdentifiers: Exception getting NVIDIA Board details from video card. Substituting with a # instead"); - displayInfo.Add("#"); - } - try - { - displayInfo.Add(myPhysicalGPU.Foundry.ToString()); - } - catch (Exception ex) - { - SharedLogger.logger.Warn(ex, $"ProfileRepository/GenerateProfileDisplayIdentifiers: Exception getting NVIDIA Foundry from video card. Substituting with a # instead"); - displayInfo.Add("#"); - } - try - { - displayInfo.Add(myPhysicalGPU.GPUId.ToString()); - } - catch (Exception ex) - { - SharedLogger.logger.Warn(ex, $"ProfileRepository/GenerateProfileDisplayIdentifiers: Exception getting NVIDIA GPUId from video card. Substituting with a # instead"); - displayInfo.Add("#"); - } - try - { - displayInfo.Add(myPhysicalGPU.GPUType.ToString()); - } - catch (Exception ex) - { - SharedLogger.logger.Warn(ex, $"ProfileRepository/GenerateProfileDisplayIdentifiers: Exception getting NVIDIA GPUType from video card. Substituting with a # instead"); - displayInfo.Add("#"); - } - try - { - displayInfo.Add(aDisplayDevice.ConnectionType.ToString()); - } - catch (Exception ex) - { - SharedLogger.logger.Warn(ex, $"ProfileRepository/GenerateProfileDisplayIdentifiers: Exception getting NVIDIA Connection from video card. Substituting with a # instead"); - displayInfo.Add("#"); - } - try - { - displayInfo.Add(aDisplayDevice.DisplayId.ToString()); - } - catch (Exception ex) - { - SharedLogger.logger.Warn(ex, $"ProfileRepository/GenerateProfileDisplayIdentifiers: Exception getting NVIDIA DisplayID from video card. Substituting with a # instead"); - displayInfo.Add("#"); - } - - // Create a display identifier out of it - string displayIdentifier = String.Join("|", displayInfo); - // Add it to the list of display identifiers so we can return it - displayIdentifiers.Add(displayIdentifier); - SharedLogger.logger.Debug($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: DisplayIdentifier: {displayIdentifier}"); - } - } - } - } - // else if there is an AMD video card then we use that mode - else if (AMDLibrary.IsInstalled) - { - //isAMD = true; - SharedLogger.logger.Debug($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: The video card is an AMD video card."); - // Needs a lot of work here! We need to check if the AMD returned the right stuff, and then use Windows if there is an error. - return AMDLibrary.GenerateAllAvailableDisplayIdentifiers(); - } - // else video card is not NVIDIA or AMD so we just use the standard WindowsAPI access method else { - - // Then go through the adapters we have running using the WindowsDisplayAPI - List attachedDisplayDevices = Display.GetDisplays().ToList(); - List unattachedDisplayDevices = UnAttachedDisplay.GetUnAttachedDisplays().ToList(); - - SharedLogger.logger.Debug($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: We are using the standard Windows Display API to figure out what display devices are attached and available. There are {attachedDisplayDevices.Count} display devices attached and {unattachedDisplayDevices.Count} devices unattached."); - - - foreach (Display attachedDisplay in attachedDisplayDevices) - { - DisplayAdapter displayAdapter = attachedDisplay.Adapter; - PathDisplayAdapter pathDisplayAdapter = displayAdapter.ToPathDisplayAdapter(); - PathDisplaySource pathDisplaySource = attachedDisplay.ToPathDisplaySource(); - PathDisplayTarget pathDisplayTarget = attachedDisplay.ToPathDisplayTarget(); - - try - { - SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: ADDN : {attachedDisplay.DeviceName}"); - SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: ADDFN : {attachedDisplay.DisplayFullName}"); - SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: ADDIN : {attachedDisplay.DisplayName}"); - SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: ADDIN : {attachedDisplay.IsAvailable}"); - SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: ADDIGP : {attachedDisplay.IsGDIPrimary}"); - SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: ADDIV : {attachedDisplay.IsValid}"); - SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: ADCSCD : {attachedDisplay.CurrentSetting.ColorDepth}"); - SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: ADCSF : {attachedDisplay.CurrentSetting.Frequency}"); - SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: ADCSIE : {attachedDisplay.CurrentSetting.IsEnable}"); - SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: ADCSII : {attachedDisplay.CurrentSetting.IsInterlaced}"); - SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: ADCSO : {attachedDisplay.CurrentSetting.Orientation}"); - SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: ADCSOSM : {attachedDisplay.CurrentSetting.OutputScalingMode}"); - SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: ADCSP : {attachedDisplay.CurrentSetting.Position}"); - SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: ADCSR : {attachedDisplay.CurrentSetting.Resolution}"); - SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: DP : {displayAdapter.DevicePath}"); - SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: DK : {displayAdapter.DeviceKey}"); - SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: DN : {displayAdapter.DeviceName}"); - SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: DK : {displayAdapter.DeviceKey}"); - SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: AI : {pathDisplayAdapter.AdapterId}"); - SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: AIDP : {pathDisplayAdapter.DevicePath}"); - SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: AIII : {pathDisplayAdapter.IsInvalid}"); - SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: DDA : {displayAdapter.DeviceName}"); - SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: PDSA : {pathDisplaySource.Adapter}"); - SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: PDSCDS : {pathDisplaySource.CurrentDPIScale}"); - SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: PDSDN : {pathDisplaySource.DisplayName}"); - SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: PDSMDS : {pathDisplaySource.MaximumDPIScale}"); - SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: PDSRDS : {pathDisplaySource.RecommendedDPIScale}"); - SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: PDSSI : {pathDisplaySource.SourceId}"); - SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: PDTA : {pathDisplayTarget.Adapter}"); - SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: PDTCI : {pathDisplayTarget.ConnectorInstance}"); - SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: PDTDP : {pathDisplayTarget.DevicePath}"); - SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: PDTEMC : {pathDisplayTarget.EDIDManufactureCode}"); - SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: PDTEMI : {pathDisplayTarget.EDIDManufactureId}"); - SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: PDTEPC : {pathDisplayTarget.EDIDProductCode}"); - SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: PDTFN : {pathDisplayTarget.FriendlyName}"); - SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: PDTIA : {pathDisplayTarget.IsAvailable}"); - SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: PDTPR : {pathDisplayTarget.PreferredResolution}"); - SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: PDTPSM : {pathDisplayTarget.PreferredSignalMode}"); - SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: PDTTI : {pathDisplayTarget.TargetId}"); - SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: PDTVRS : {pathDisplayTarget.VirtualResolutionSupport}"); - } - catch (Exception ex) - { - SharedLogger.logger.Warn(ex, $"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: Exception accessing one of the WindowsDisplayAPI items to print it out during a TRACE session"); - } - - // Create an array of all the important display info we need to record - List displayInfo = new List(); - displayInfo.Add("WINAPI"); - try - { - displayInfo.Add(displayAdapter.DeviceName.ToString()); - } - catch (Exception ex) - { - SharedLogger.logger.Warn(ex, $"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: Exception getting Windows Display Adapter Device name from video card. Substituting with a # instead"); - displayInfo.Add("#"); - } - try - { - displayInfo.Add(pathDisplayAdapter.AdapterId.ToString()); - } - catch (Exception ex) - { - SharedLogger.logger.Warn(ex, $"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: Exception getting Windows Display Adapter ID from video card. Substituting with a # instead"); - displayInfo.Add("#"); - } - try - { - displayInfo.Add(pathDisplayTarget.ConnectorInstance.ToString()); - } - catch (Exception ex) - { - SharedLogger.logger.Warn(ex, $"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: Exception getting Windows Display Target Connector Instance from video card. Substituting with a # instead"); - displayInfo.Add("#"); - } - try - { - displayInfo.Add(pathDisplayTarget.FriendlyName); - } - catch (Exception ex) - { - SharedLogger.logger.Warn(ex, $"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: Exception getting Windows Display Target Friendly name from video card. Substituting with a # instead"); - displayInfo.Add("#"); - } - try - { - displayInfo.Add(pathDisplayTarget.EDIDManufactureCode.ToString()); - } - catch (Exception ex) - { - SharedLogger.logger.Warn(ex, $"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: Exception getting Windows Display EDID Manufacturer Code from video card. Substituting with a # instead"); - displayInfo.Add("#"); - } - try - { - displayInfo.Add(pathDisplayTarget.EDIDManufactureId.ToString()); - } - catch (Exception ex) - { - SharedLogger.logger.Warn(ex, $"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: Exception getting Windows Display EDID Manufacturer ID from video card. Substituting with a # instead"); - displayInfo.Add("#"); - } - try - { - displayInfo.Add(pathDisplayTarget.EDIDProductCode.ToString()); - } - catch (Exception ex) - { - SharedLogger.logger.Warn(ex, $"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: Exception getting Windows Display EDID Product Code from video card. Substituting with a # instead"); - displayInfo.Add("#"); - } - try - { - displayInfo.Add(pathDisplayTarget.TargetId.ToString()); - } - catch (Exception ex) - { - SharedLogger.logger.Warn(ex, $"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: Exception getting Windows Display Target ID from video card. Substituting with a # instead"); - displayInfo.Add("#"); - } - - // Create a display identifier out of it - string displayIdentifier = String.Join("|", displayInfo); - // Add it to the list of display identifiers so we can return it - displayIdentifiers.Add(displayIdentifier); - SharedLogger.logger.Debug($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: Attached DisplayIdentifier: {displayIdentifier}"); - } - - foreach (UnAttachedDisplay unattachedDisplay in unattachedDisplayDevices) - { - DisplayAdapter displayAdapter = unattachedDisplay.Adapter; - PathDisplayAdapter pathDisplayAdapter = displayAdapter.ToPathDisplayAdapter(); - PathDisplaySource pathDisplaySource = unattachedDisplay.ToPathDisplaySource(); - PathDisplayTarget pathDisplayTarget = unattachedDisplay.ToPathDisplayTarget(); - - SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: ADDN : {unattachedDisplay.DeviceName}"); - SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: ADDFN : {unattachedDisplay.DisplayFullName}"); - SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: ADDIN : {unattachedDisplay.DisplayName}"); - SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: ADDIN : {unattachedDisplay.IsAvailable}"); - SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: ADDIV : {unattachedDisplay.IsValid}"); - SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: DP : {displayAdapter.DevicePath}"); - SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: DK : {displayAdapter.DeviceKey}"); - SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: DN : {displayAdapter.DeviceName}"); - SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: DK : {displayAdapter.DeviceKey}"); - SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: AI : {pathDisplayAdapter.AdapterId}"); - SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: AIDP : {pathDisplayAdapter.DevicePath}"); - SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: AIII : {pathDisplayAdapter.IsInvalid}"); - SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: PDSA : {pathDisplaySource.Adapter}"); - SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: PDSCDS : {pathDisplaySource.CurrentDPIScale}"); - SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: PDSDN : {pathDisplaySource.DisplayName}"); - SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: PDSMDS : {pathDisplaySource.MaximumDPIScale}"); - SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: PDSRDS : {pathDisplaySource.RecommendedDPIScale}"); - SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: PDSSI : {pathDisplaySource.SourceId}"); - SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: PDTA : {pathDisplayTarget.Adapter}"); - SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: PDTCI : {pathDisplayTarget.ConnectorInstance}"); - SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: PDTDP : {pathDisplayTarget.DevicePath}"); - SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: PDTEMC : {pathDisplayTarget.EDIDManufactureCode}"); - SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: PDTEMI : {pathDisplayTarget.EDIDManufactureId}"); - SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: PDTEPC : {pathDisplayTarget.EDIDProductCode}"); - SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: PDTFN : {pathDisplayTarget.FriendlyName}"); - SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: PDTIA : {pathDisplayTarget.IsAvailable}"); - SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: PDTPR : {pathDisplayTarget.PreferredResolution}"); - SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: PDTPSM : {pathDisplayTarget.PreferredSignalMode}"); - SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: PDTTI : {pathDisplayTarget.TargetId}"); - SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: PDTVRS : {pathDisplayTarget.VirtualResolutionSupport}"); - - // Create an array of all the important display info we need to record - string[] displayInfo = { - "WINAPI", - displayAdapter.DeviceName.ToString(), - pathDisplayAdapter.AdapterId.ToString(), - pathDisplayTarget.ConnectorInstance.ToString(), - pathDisplayTarget.FriendlyName, - pathDisplayTarget.EDIDManufactureCode.ToString(), - pathDisplayTarget.EDIDManufactureId.ToString(), - pathDisplayTarget.EDIDProductCode.ToString(), - pathDisplayTarget.TargetId.ToString(), - }; - - // Create a display identifier out of it - string displayIdentifier = String.Join("|", displayInfo); - // Add it to the list of display identifiers so we can return it - displayIdentifiers.Add(displayIdentifier); - SharedLogger.logger.Debug($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: Unattached DisplayIdentifier: {displayIdentifier}"); - } - + return WinLibrary.GetLibrary().GetCurrentDisplayIdentifiers(); } - - // Sort the display identifiers - displayIdentifiers.Sort(); - - return displayIdentifiers; } - public static bool ApplyNVIDIAGridTopology(NVIDIAProfileItem profile) + + +/* public static bool ApplyNVIDIAGridTopology(NVIDIAProfileItem profile) { SharedLogger.logger.Debug($"ProfileRepository/ApplyNVIDIAGridTopology: Attempting to apply NVIDIA Grid Topology"); @@ -1595,7 +957,7 @@ namespace DisplayMagicianShared return false; } - } + }*/ public static bool IsValidFilename(string testName) { diff --git a/DisplayMagicianShared/Windows/CCD.cs b/DisplayMagicianShared/Windows/CCD.cs index b95b763..465db2c 100644 --- a/DisplayMagicianShared/Windows/CCD.cs +++ b/DisplayMagicianShared/Windows/CCD.cs @@ -7,7 +7,8 @@ using System.Threading.Tasks; namespace DisplayMagicianShared.Windows { - public enum WIN32STATUS + + public enum WIN32STATUS : uint { ERROR_SUCCESS = 0, ERROR_ACCESS_DENIED = 5, @@ -15,10 +16,12 @@ namespace DisplayMagicianShared.Windows ERROR_GEN_FAILURE = 31, ERROR_INVALID_PARAMETER = 87, ERROR_INSUFFICIENT_BUFFER = 122, + ERROR_BAD_CONFIGURATION = 1610, } - public enum DISPLAYCONFIG_DEVICE_INFO_TYPE + public enum DISPLAYCONFIG_DEVICE_INFO_TYPE : uint { + Zero = 0, DISPLAYCONFIG_DEVICE_INFO_GET_SOURCE_NAME = 1, DISPLAYCONFIG_DEVICE_INFO_GET_TARGET_NAME = 2, DISPLAYCONFIG_DEVICE_INFO_GET_TARGET_PREFERRED_MODE = 3, @@ -32,7 +35,8 @@ namespace DisplayMagicianShared.Windows DISPLAYCONFIG_DEVICE_INFO_GET_SDR_WHITE_LEVEL = 11, } - public enum DISPLAYCONFIG_COLOR_ENCODING + [Flags] + public enum DISPLAYCONFIG_COLOR_ENCODING : uint { DISPLAYCONFIG_COLOR_ENCODING_RGB = 0, DISPLAYCONFIG_COLOR_ENCODING_YCBCR444 = 1, @@ -41,26 +45,34 @@ namespace DisplayMagicianShared.Windows DISPLAYCONFIG_COLOR_ENCODING_INTENSITY = 4, } - public enum DISPLAYCONFIG_SCALING + [Flags] + public enum DISPLAYCONFIG_SCALING : uint { + Zero = 0, DISPLAYCONFIG_SCALING_IDENTITY = 1, DISPLAYCONFIG_SCALING_CENTERED = 2, DISPLAYCONFIG_SCALING_STRETCHED = 3, DISPLAYCONFIG_SCALING_ASPECTRATIOCENTEREDMAX = 4, DISPLAYCONFIG_SCALING_CUSTOM = 5, DISPLAYCONFIG_SCALING_PREFERRED = 128, + DISPLAYCONFIG_SCALING_FORCEUINT32 = 0xFFFFFFFF, } - public enum DISPLAYCONFIG_ROTATION + [Flags] + public enum DISPLAYCONFIG_ROTATION : uint { + Zero = 0, DISPLAYCONFIG_ROTATION_IDENTITY = 1, DISPLAYCONFIG_ROTATION_ROTATE90 = 2, DISPLAYCONFIG_ROTATION_ROTATE180 = 3, + DISPLAYCONFIG_ROTATION_ROTATE270 = 4, + DISPLAYCONFIG_ROTATION_FORCEUINT32 = 0xFFFFFFFF, } - public enum DISPLAYCONFIG_VIDEO_OUTPUT_TECHNOLOGY + [Flags] + public enum DISPLAYCONFIG_VIDEO_OUTPUT_TECHNOLOGY : uint { - DISPLAYCONFIG_OUTPUT_TECHNOLOGY_OTHER = -1, + DISPLAYCONFIG_OUTPUT_TECHNOLOGY_OTHER = 4294967295, // - 1 DISPLAYCONFIG_OUTPUT_TECHNOLOGY_HD15 = 0, DISPLAYCONFIG_OUTPUT_TECHNOLOGY_SVIDEO = 1, DISPLAYCONFIG_OUTPUT_TECHNOLOGY_COMPOSITE_VIDEO = 2, @@ -78,31 +90,41 @@ namespace DisplayMagicianShared.Windows DISPLAYCONFIG_OUTPUT_TECHNOLOGY_MIRACAST = 15, DISPLAYCONFIG_OUTPUT_TECHNOLOGY_INDIRECT_WIRED = 16, DISPLAYCONFIG_OUTPUT_TECHNOLOGY_INDIRECT_VIRTUAL = 17, - DISPLAYCONFIG_OUTPUT_TECHNOLOGY_INTERNAL = unchecked((int)0x80000000), + DISPLAYCONFIG_OUTPUT_TECHNOLOGY_public = 0x80000000, + DISPLAYCONFIG_OUTPUT_TECHNOLOGY_FORCEUINT32 = 0xFFFFFFFF, } - public enum DISPLAYCONFIG_TOPOLOGY_ID + [Flags] + public enum DISPLAYCONFIG_TOPOLOGY_ID : uint { - DISPLAYCONFIG_TOPOLOGY_INTERNAL = 0x00000001, + Zero = 0x0, + DISPLAYCONFIG_TOPOLOGY_public = 0x00000001, DISPLAYCONFIG_TOPOLOGY_CLONE = 0x00000002, DISPLAYCONFIG_TOPOLOGY_EXTEND = 0x00000004, DISPLAYCONFIG_TOPOLOGY_EXTERNAL = 0x00000008, + DISPLAYCONFIG_TOPOLOGY_FORCEUINT32 = 0xFFFFFFFF, } - public enum DISPLAYCONFIG_PATH + [Flags] + public enum DISPLAYCONFIG_PATH : uint { + Zero = 0x0, DISPLAYCONFIG_PATH_ACTIVE = 0x00000001, DISPLAYCONFIG_PATH_PREFERRED_UNSCALED = 0x00000004, DISPLAYCONFIG_PATH_SUPPORT_VIRTUAL_MODE = 0x00000008, } - public enum DISPLAYCONFIG_SOURCE_FLAGS + [Flags] + public enum DISPLAYCONFIG_SOURCE_FLAGS : uint { + Zero = 0x0, DISPLAYCONFIG_SOURCE_IN_USE = 0x00000001, } - public enum DISPLAYCONFIG_TARGET_FLAGS + [Flags] + public enum DISPLAYCONFIG_TARGET_FLAGS : uint { + Zero = 0x0, DISPLAYCONFIG_TARGET_IN_USE = 0x00000001, DISPLAYCONFIG_TARGET_FORCIBLE = 0x00000002, DISPLAYCONFIG_TARGET_FORCED_AVAILABILITY_BOOT = 0x00000004, @@ -111,52 +133,139 @@ namespace DisplayMagicianShared.Windows DISPLAYCONFIG_TARGET_IS_HMD = 0x00000020, } - public enum QDC + [Flags] + public enum QDC : uint { + Zero = 0x0, QDC_ALL_PATHS = 0x00000001, // Get all paths QDC_ONLY_ACTIVE_PATHS = 0x00000002, // Get only the active paths currently in use - QDC_DATABASE_CURRENT = 0x00000004, // Get the current paths in the display database + QDC_DATABASE_CURRENT = 0x00000004, // Get the currently active paths as stored in the display database QDC_VIRTUAL_MODE_AWARE = 0x00000010, // Get the virtual mode aware paths QDC_INCLUDE_HMD = 0x00000020, } - public enum DISPLAYCONFIG_SCANLINE_ORDERING + [Flags] + public enum SDC : uint + { + Zero = 0x0, + SDC_TOPOLOGY_public = 0x00000001, + SDC_TOPOLOGY_CLONE = 0x00000002, + SDC_TOPOLOGY_EXTEND = 0x00000004, + SDC_TOPOLOGY_EXTERNAL = 0x00000008, + SDC_TOPOLOGY_SUPPLIED = 0x00000010, + SDC_USE_DATABASE_CURRENT = (SDC_TOPOLOGY_public | SDC_TOPOLOGY_CLONE | SDC_TOPOLOGY_EXTEND | SDC_TOPOLOGY_EXTERNAL), + SDC_USE_SUPPLIED_DISPLAY_CONFIG = 0x00000020, + SDC_VALIDATE = 0x00000040, + SDC_APPLY = 0x00000080, + SDC_NO_OPTIMIZATION = 0x00000100, + SDC_SAVE_TO_DATABASE = 0x00000200, + SDC_ALLOW_CHANGES = 0x00000400, + SDC_PATH_PERSIST_IF_REQUIRED = 0x00000800, + SDC_FORCE_MODE_ENUMERATION = 0x00001000, + SDC_ALLOW_PATH_ORDER_CHANGES = 0x00002000, + SDC_VIRTUAL_MODE_AWARE = 0x00008000, + + // Special common combinations (only set in this library) + TEST_IF_VALID_DISPLAYCONFIG = (SDC_VALIDATE | SDC_USE_SUPPLIED_DISPLAY_CONFIG), + TEST_IF_VALID_DISPLAYCONFIG_WITH_TWEAKS = (SDC_VALIDATE | SDC_USE_SUPPLIED_DISPLAY_CONFIG | SDC_ALLOW_CHANGES), + SET_DISPLAYCONFIG_AND_SAVE = (SDC_APPLY | SDC_USE_SUPPLIED_DISPLAY_CONFIG | SDC_SAVE_TO_DATABASE), + SET_DISPLAYCONFIG_WITH_TWEAKS_AND_SAVE = (SDC_APPLY | SDC_USE_SUPPLIED_DISPLAY_CONFIG | SDC_ALLOW_CHANGES | SDC_SAVE_TO_DATABASE), + DISPLAYMAGICIAN_SET = (SDC_APPLY | SDC_USE_SUPPLIED_DISPLAY_CONFIG | SDC_ALLOW_CHANGES | SDC_SAVE_TO_DATABASE), + DISPLAYMAGICIAN_VALIDATE = (SDC_VALIDATE | SDC_USE_SUPPLIED_DISPLAY_CONFIG | SDC_ALLOW_CHANGES | SDC_SAVE_TO_DATABASE), + //DISPLAYMAGICIAN_SET = (SDC_APPLY | SDC_TOPOLOGY_SUPPLIED | SDC_ALLOW_CHANGES | SDC_ALLOW_PATH_ORDER_CHANGES ), + //DISPLAYMAGICIAN_VALIDATE = (SDC_VALIDATE | SDC_TOPOLOGY_SUPPLIED | SDC_ALLOW_CHANGES | SDC_ALLOW_PATH_ORDER_CHANGES ), + + SET_DISPLAYCONFIG_BUT_NOT_SAVE = (SDC_APPLY | SDC_USE_SUPPLIED_DISPLAY_CONFIG), + TEST_IF_CLONE_VALID = (SDC_VALIDATE | SDC_TOPOLOGY_CLONE), + SET_CLONE_TOPOLOGY = (SDC_APPLY | SDC_TOPOLOGY_CLONE), + SET_CLONE_TOPOLOGY_WITH_PATH_PERSISTENCE = (SDC_APPLY | SDC_TOPOLOGY_CLONE | SDC_PATH_PERSIST_IF_REQUIRED), + RESET_DISPLAYCONFIG_TO_LAST_SAVED = (SDC_APPLY | SDC_USE_DATABASE_CURRENT), + SET_DISPLAYCONFIG_USING_PATHS_ONLY_AND_SAVE = (SDC_APPLY | SDC_TOPOLOGY_SUPPLIED | SDC_ALLOW_PATH_ORDER_CHANGES), + } + + [Flags] + public enum DISPLAYCONFIG_SCANLINE_ORDERING : uint { DISPLAYCONFIG_SCANLINE_ORDERING_UNSPECIFIED = 0, DISPLAYCONFIG_SCANLINE_ORDERING_PROGRESSIVE = 1, DISPLAYCONFIG_SCANLINE_ORDERING_INTERLACED = 2, DISPLAYCONFIG_SCANLINE_ORDERING_INTERLACED_UPPERFIELDFIRST = DISPLAYCONFIG_SCANLINE_ORDERING_INTERLACED, DISPLAYCONFIG_SCANLINE_ORDERING_INTERLACED_LOWERFIELDFIRST = 3, + DISPLAYCONFIG_SCANLINE_ORDERING_FORCEUINT32 = 0xFFFFFFFF, } - public enum DISPLAYCONFIG_PIXELFORMAT + [Flags] + public enum DISPLAYCONFIG_PIXELFORMAT : uint { + Zero = 0x0, DISPLAYCONFIG_PIXELFORMAT_8BPP = 1, DISPLAYCONFIG_PIXELFORMAT_16BPP = 2, DISPLAYCONFIG_PIXELFORMAT_24BPP = 3, DISPLAYCONFIG_PIXELFORMAT_32BPP = 4, DISPLAYCONFIG_PIXELFORMAT_NONGDI = 5, + DISPLAYCONFIG_PIXELFORMAT_FORCEUINT32 = 0xFFFFFFFF, } - public enum DISPLAYCONFIG_MODE_INFO_TYPE + [Flags] + public enum DISPLAYCONFIG_MODE_INFO_TYPE : uint { + Zero = 0x0, DISPLAYCONFIG_MODE_INFO_TYPE_SOURCE = 1, DISPLAYCONFIG_MODE_INFO_TYPE_TARGET = 2, DISPLAYCONFIG_MODE_INFO_TYPE_DESKTOP_IMAGE = 3, + DISPLAYCONFIG_MODE_INFO_TYPE_FORCEUINT32 = 0xFFFFFFFF, + } + + [Flags] + public enum D3D_VIDEO_SIGNAL_STANDARD : uint + { + Uninitialized = 0, + VesaDmt = 1, + VesaGtf = 2, + VesaCvt = 3, + Ibm = 4, + Apple = 5, + NtscM = 6, + NtscJ = 7, + Ntsc443 = 8, + PalB = 9, + PalB1 = 10, + PalG = 11, + PalH = 12, + PalI = 13, + PalD = 14, + PalN = 15, + PalNc = 16, + SecamB = 17, + SecamD = 18, + SecamG = 19, + SecamH = 20, + SecamK = 21, + SecamK1 = 22, + SecamL = 23, + SecamL1 = 24, + Eia861 = 25, + Eia861A = 26, + Eia861B = 27, + PalK = 28, + PalK1 = 29, + PalL = 30, + PalM = 31, + Other = 255 } [StructLayout(LayoutKind.Sequential)] public struct DISPLAYCONFIG_DEVICE_INFO_HEADER : IEquatable { public DISPLAYCONFIG_DEVICE_INFO_TYPE Type; - public int Size; + public uint Size; public LUID AdapterId; public uint Id; public bool Equals(DISPLAYCONFIG_DEVICE_INFO_HEADER other) => Type == other.Type && Size == other.Size && - AdapterId.Equals(other.AdapterId) && + // AdapterId.Equals(other.AdapterId) && // Removed the AdapterId from the Equals, as it changes after reboot. Id == other.Id; public override int GetHashCode() @@ -171,9 +280,11 @@ namespace DisplayMagicianShared.Windows public struct DISPLAYCONFIG_GET_ADVANCED_COLOR_INFO : IEquatable { public DISPLAYCONFIG_DEVICE_INFO_HEADER Header; + //[MarshalAs(UnmanagedType.U4)] public uint Value; public DISPLAYCONFIG_COLOR_ENCODING ColorEncoding; - public int BitsPerColorChannel; + //[MarshalAs(UnmanagedType.U4)] + public uint BitsPerColorChannel; public bool AdvancedColorSupported => (Value & 0x1) == 0x1; public bool AdvancedColorEnabled => (Value & 0x2) == 0x2; @@ -216,16 +327,17 @@ namespace DisplayMagicianShared.Windows public struct LUID : IEquatable { public uint LowPart; - public int HighPart; + public uint HighPart; - public long Value => ((long)HighPart << 32) | LowPart; + public ulong Value => ((ulong)HighPart << 32) | LowPart; public bool Equals(LUID other) - => Value == other.Value; + => LowPart == other.LowPart && + HighPart == other.HighPart; public override int GetHashCode() { - return Value.GetHashCode(); + return (LowPart, HighPart).GetHashCode(); } public override string ToString() => Value.ToString(); @@ -292,8 +404,8 @@ namespace DisplayMagicianShared.Windows public struct DISPLAYCONFIG_DESKTOP_IMAGE_INFO : IEquatable { public POINTL PathSourceSize; - public RECT DesktopImageRegion; - public RECT DesktopImageClip; + public RECTL DesktopImageRegion; + public RECTL DesktopImageClip; public bool Equals(DISPLAYCONFIG_DESKTOP_IMAGE_INFO other) => PathSourceSize.Equals(other.PathSourceSize) && @@ -316,7 +428,7 @@ namespace DisplayMagicianShared.Windows public DISPLAYCONFIG_RATIONAL VSyncFreq; public DISPLAYCONFIG_2DREGION ActiveSize; public DISPLAYCONFIG_2DREGION TotalSize; - public uint VideoStandard; + public D3D_VIDEO_SIGNAL_STANDARD VideoStandard; public DISPLAYCONFIG_SCANLINE_ORDERING ScanLineOrdering; public bool Equals(DISPLAYCONFIG_VIDEO_SIGNAL_INFO other) @@ -353,47 +465,31 @@ namespace DisplayMagicianShared.Windows } [StructLayout(LayoutKind.Explicit)] - public struct DISPLAYCONFIG_MODE_INFO_union : IEquatable - { - [FieldOffset(0)] - public DISPLAYCONFIG_TARGET_MODE TargetMode; - - [FieldOffset(0)] - public DISPLAYCONFIG_SOURCE_MODE SourceMode; - - [FieldOffset(0)] - public DISPLAYCONFIG_DESKTOP_IMAGE_INFO DesktopImageInfo; - - public bool Equals(DISPLAYCONFIG_MODE_INFO_union other) - => TargetMode.Equals(other.TargetMode) && - SourceMode.Equals(other.SourceMode) && - DesktopImageInfo.Equals(other.DesktopImageInfo); - - public override int GetHashCode() - { - return (TargetMode, SourceMode, DesktopImageInfo).GetHashCode(); - } - - //public override string ToString() => $"{type.ToString("G")}"; - } - - [StructLayout(LayoutKind.Sequential)] public struct DISPLAYCONFIG_PATH_SOURCE_INFO : IEquatable { + [FieldOffset(0)] public LUID AdapterId; + [FieldOffset(8)] public uint Id; + [FieldOffset(12)] public uint ModeInfoIdx; + [FieldOffset(12)] + public ushort cloneGroupId; + [FieldOffset(14)] + public ushort sourceModeInfoIdx; + [FieldOffset(16)] public DISPLAYCONFIG_SOURCE_FLAGS StatusFlags; public bool Equals(DISPLAYCONFIG_PATH_SOURCE_INFO other) - => AdapterId.Equals(other.AdapterId) && + => // AdapterId.Equals(other.AdapterId) && // Removed the AdapterId from the Equals, as it changes after a reboot. Id == other.Id && ModeInfoIdx == other.ModeInfoIdx && StatusFlags.Equals(other.StatusFlags); public override int GetHashCode() { - return (AdapterId, ModeInfoIdx, StatusFlags).GetHashCode(); + //return (AdapterId, Id, ModeInfoIdx, StatusFlags).GetHashCode(); + return (ModeInfoIdx, Id, StatusFlags).GetHashCode(); } //public override string ToString() => $"{type.ToString("G")}"; @@ -411,10 +507,25 @@ namespace DisplayMagicianShared.Windows public DISPLAYCONFIG_RATIONAL RefreshRate; public DISPLAYCONFIG_SCANLINE_ORDERING ScanLineOrdering; public bool TargetAvailable; - public DISPLAYCONFIG_TARGET_FLAGS StatusFlags; + public uint StatusFlags; + + public bool TargetInUse => (StatusFlags & 0x1) == 0x1; + public bool TargetForcible => (StatusFlags & 0x2) == 0x2; + public bool ForcedAvailabilityBoot => (StatusFlags & 0x4) == 0x4; + public bool ForcedAvailabilityPath => (StatusFlags & 0x8) == 0x8; + public bool ForcedAvailabilitySystem => (StatusFlags & 0x10) == 0x10; + public bool IsHMD => (StatusFlags & 0x20) == 0x20; + + + /* DISPLAYCONFIG_TARGET_IN_USE = 0x00000001, + DISPLAYCONFIG_TARGET_FORCIBLE = 0x00000002, + DISPLAYCONFIG_TARGET_FORCED_AVAILABILITY_BOOT = 0x00000004, + DISPLAYCONFIG_TARGET_FORCED_AVAILABILITY_PATH = 0x00000008, + DISPLAYCONFIG_TARGET_FORCED_AVAILABILITY_SYSTEM = 0x00000010, + DISPLAYCONFIG_TARGET_IS_HMD = 0x00000020,*/ public bool Equals(DISPLAYCONFIG_PATH_TARGET_INFO other) - => AdapterId.Equals(other.AdapterId) && + => // AdapterId.Equals(other.AdapterId) && // Removed the AdapterId from the Equals, as it changes after reboot. Id == other.Id && ModeInfoIdx == other.ModeInfoIdx && OutputTechnology.Equals(other.OutputTechnology) && @@ -438,7 +549,7 @@ namespace DisplayMagicianShared.Windows { public DISPLAYCONFIG_PATH_SOURCE_INFO SourceInfo; public DISPLAYCONFIG_PATH_TARGET_INFO TargetInfo; - public DISPLAYCONFIG_PATH Flags; + public uint Flags; public bool Equals(DISPLAYCONFIG_PATH_INFO other) => SourceInfo.Equals(other.SourceInfo) && @@ -453,36 +564,78 @@ namespace DisplayMagicianShared.Windows //public override string ToString() => $"{type.ToString("G")}"; } - [StructLayout(LayoutKind.Sequential)] + [StructLayout(LayoutKind.Explicit)] public struct DISPLAYCONFIG_MODE_INFO : IEquatable { + [FieldOffset((0))] public DISPLAYCONFIG_MODE_INFO_TYPE InfoType; + + [FieldOffset(4)] public uint Id; + + [FieldOffset(8)] public LUID AdapterId; - public DISPLAYCONFIG_MODE_INFO_union Info; + + // These 3 fields are all a C union in wingdi.dll + [FieldOffset(16)] + public DISPLAYCONFIG_TARGET_MODE TargetMode; + + [FieldOffset(16)] + public DISPLAYCONFIG_SOURCE_MODE SourceMode; + + [FieldOffset(16)] + public DISPLAYCONFIG_DESKTOP_IMAGE_INFO DesktopImageInfo; public bool Equals(DISPLAYCONFIG_MODE_INFO other) - => InfoType == other.InfoType && - Id == other.Id && - AdapterId.Equals(other.AdapterId) && - Info.Equals(other.Info); + { + if (InfoType != other.InfoType) + return false; + + if (InfoType == DISPLAYCONFIG_MODE_INFO_TYPE.DISPLAYCONFIG_MODE_INFO_TYPE_TARGET && + Id == other.Id && + TargetMode.Equals(other.TargetMode)) + return true; + + if (InfoType == DISPLAYCONFIG_MODE_INFO_TYPE.DISPLAYCONFIG_MODE_INFO_TYPE_SOURCE && + Id == other.Id && + SourceMode.Equals(other.SourceMode)) + return true; + + if (InfoType == DISPLAYCONFIG_MODE_INFO_TYPE.DISPLAYCONFIG_MODE_INFO_TYPE_DESKTOP_IMAGE && + Id == other.Id && + DesktopImageInfo.Equals(other.DesktopImageInfo)) + return true; + + return false; + } + public override int GetHashCode() { - return (InfoType, Id, AdapterId, Info).GetHashCode(); + if (InfoType == DISPLAYCONFIG_MODE_INFO_TYPE.DISPLAYCONFIG_MODE_INFO_TYPE_TARGET) + return (InfoType, Id, TargetMode).GetHashCode(); + + if (InfoType == DISPLAYCONFIG_MODE_INFO_TYPE.DISPLAYCONFIG_MODE_INFO_TYPE_SOURCE) + return (InfoType, Id, SourceMode).GetHashCode(); + + if (InfoType == DISPLAYCONFIG_MODE_INFO_TYPE.DISPLAYCONFIG_MODE_INFO_TYPE_DESKTOP_IMAGE) + return (InfoType, Id, DesktopImageInfo).GetHashCode(); + + // otherwise we return everything + return (InfoType, Id, TargetMode, SourceMode, DesktopImageInfo).GetHashCode(); } //public override string ToString() => $"{type.ToString("G")}"; } [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] - public struct DISPLAYCONFIG_GET_SOURCE_NAME : IEquatable + public struct DISPLAYCONFIG_SOURCE_DEVICE_NAME : IEquatable { public DISPLAYCONFIG_DEVICE_INFO_HEADER Header; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)] public string ViewGdiDeviceName; - public bool Equals(DISPLAYCONFIG_GET_SOURCE_NAME other) + public bool Equals(DISPLAYCONFIG_SOURCE_DEVICE_NAME other) => Header.Equals(other.Header) && ViewGdiDeviceName == other.ViewGdiDeviceName; @@ -502,7 +655,7 @@ namespace DisplayMagicianShared.Windows public bool Equals(DISPLAYCONFIG_TARGET_DEVICE_NAME_FLAGS other) => Value == other.Value; - public bool FriendlyNameFromEdid => (Value & 0x1) == 0x1; + public bool FriendlyNameFromEdid => (Value & 0x1) == 0x1; // Might be this broken? public bool FriendlyNameForced => (Value & 0x2) == 0x2; public bool EdidIdsValid => (Value & 0x4) == 0x4; @@ -515,7 +668,7 @@ namespace DisplayMagicianShared.Windows } [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] - public struct DISPLAYCONFIG_GET_TARGET_NAME : IEquatable + public struct DISPLAYCONFIG_TARGET_DEVICE_NAME : IEquatable { public DISPLAYCONFIG_DEVICE_INFO_HEADER Header; public DISPLAYCONFIG_TARGET_DEVICE_NAME_FLAGS Flags; @@ -528,7 +681,7 @@ namespace DisplayMagicianShared.Windows [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)] public string MonitorDevicePath; - public bool Equals(DISPLAYCONFIG_GET_TARGET_NAME other) + public bool Equals(DISPLAYCONFIG_TARGET_DEVICE_NAME other) => Header.Equals(other.Header) && Flags.Equals(other.Flags) && OutputTechnology.Equals(other.OutputTechnology) && @@ -548,14 +701,14 @@ namespace DisplayMagicianShared.Windows [StructLayout(LayoutKind.Sequential)] - internal struct DISPLAYCONFIG_GET_TARGET_PREFERRED_NAME : IEquatable + public struct DISPLAYCONFIG_TARGET_PREFERRED_MODE : IEquatable { public DISPLAYCONFIG_DEVICE_INFO_HEADER Header; public uint Width; public uint Height; public DISPLAYCONFIG_TARGET_MODE TargetMode; - public bool Equals(DISPLAYCONFIG_GET_TARGET_PREFERRED_NAME other) + public bool Equals(DISPLAYCONFIG_TARGET_PREFERRED_MODE other) => Header.Equals(other.Header) && Width == other.Width && Height == other.Height && @@ -570,13 +723,13 @@ namespace DisplayMagicianShared.Windows } [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] - internal struct DISPLAYCONFIG_GET_ADAPTER_NAME : IEquatable + public struct DISPLAYCONFIG_ADAPTER_NAME : IEquatable { public DISPLAYCONFIG_DEVICE_INFO_HEADER Header; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)] public string AdapterDevicePath; - public bool Equals(DISPLAYCONFIG_GET_ADAPTER_NAME other) + public bool Equals(DISPLAYCONFIG_ADAPTER_NAME other) => Header.Equals(other.Header) && AdapterDevicePath == other.AdapterDevicePath; @@ -589,24 +742,23 @@ namespace DisplayMagicianShared.Windows } [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] - internal struct DISPLAYCONFIG_SUPPORT_VIRTUAL_RESOLUTION : IEquatable + public struct DISPLAYCONFIG_SUPPORT_VIRTUAL_RESOLUTION : IEquatable { public DISPLAYCONFIG_DEVICE_INFO_HEADER Header; - [MarshalAs(UnmanagedType.U4)] - public uint DisableMonitorVirtualResolution; + public uint Value; public bool IsMonitorVirtualResolutionDisabled { - get => (DisableMonitorVirtualResolution & 0x1) == 0x1; + get => (Value & 0x1) == 0x1; } public bool Equals(DISPLAYCONFIG_SUPPORT_VIRTUAL_RESOLUTION other) => Header.Equals(other.Header) && - DisableMonitorVirtualResolution == other.DisableMonitorVirtualResolution; + Value == other.Value; public override int GetHashCode() { - return (Header, DisableMonitorVirtualResolution).GetHashCode(); + return (Header, Value).GetHashCode(); } //public override string ToString() => $"{type.ToString("G")}"; @@ -614,24 +766,23 @@ namespace DisplayMagicianShared.Windows } [StructLayout(LayoutKind.Sequential)] - internal struct DISPLAYCONFIG_SET_TARGET_PERSISTENCE : IEquatable + public struct DISPLAYCONFIG_SET_TARGET_PERSISTENCE : IEquatable { public DISPLAYCONFIG_DEVICE_INFO_HEADER Header; - [MarshalAs(UnmanagedType.U4)] - public uint BootPersistenceOn; + public uint Value; public bool IsBootPersistenceOn { - get => (BootPersistenceOn & 0x1) == 0x1; + get => (Value & 0x1) == 0x1; } public bool Equals(DISPLAYCONFIG_SET_TARGET_PERSISTENCE other) => Header.Equals(other.Header) && - BootPersistenceOn == other.BootPersistenceOn; + Value == other.Value; public override int GetHashCode() { - return (Header, BootPersistenceOn).GetHashCode(); + return (Header, Value).GetHashCode(); } //public override string ToString() => $"{type.ToString("G")}"; @@ -639,13 +790,13 @@ namespace DisplayMagicianShared.Windows } [StructLayout(LayoutKind.Sequential)] - internal struct DISPLAYCONFIG_GET_TARGET_BASE_TYPE : IEquatable + public struct DISPLAYCONFIG_TARGET_BASE_TYPE : IEquatable { public DISPLAYCONFIG_DEVICE_INFO_HEADER Header; - [MarshalAs(UnmanagedType.U4)] + //[MarshalAs(UnmanagedType.U4)] public DISPLAYCONFIG_VIDEO_OUTPUT_TECHNOLOGY BaseOutputTechnology; - public bool Equals(DISPLAYCONFIG_GET_TARGET_BASE_TYPE other) + public bool Equals(DISPLAYCONFIG_TARGET_BASE_TYPE other) => Header.Equals(other.Header) && BaseOutputTechnology == other.BaseOutputTechnology; @@ -659,15 +810,25 @@ namespace DisplayMagicianShared.Windows [StructLayout(LayoutKind.Sequential)] - internal struct DISPLAYCONFIG_SET_ADVANCED_COLOR_STATE : IEquatable + public struct DISPLAYCONFIG_SET_ADVANCED_COLOR_STATE : IEquatable { public DISPLAYCONFIG_DEVICE_INFO_HEADER Header; - [MarshalAs(UnmanagedType.U4)] public uint Value; public bool EnableAdvancedColor { get => (Value & 0x1) == 0x1; + set + { + if (value) + { + Value = 0x1; + } + else + { + Value = 0x0; + } + } } public bool Equals(DISPLAYCONFIG_SET_ADVANCED_COLOR_STATE other) @@ -683,13 +844,15 @@ namespace DisplayMagicianShared.Windows } [StructLayout(LayoutKind.Sequential)] - internal struct DISPLAYCONFIG_SDR_WHITE_LEVEL : IEquatable + public struct DISPLAYCONFIG_SDR_WHITE_LEVEL : IEquatable { public DISPLAYCONFIG_DEVICE_INFO_HEADER Header; // SDRWhiteLevel represents a multiplier for standard SDR white // peak value i.e. 80 nits represented as fixed point. // To get value in nits use the following conversion // SDRWhiteLevel in nits = (SDRWhiteLevel / 1000 ) * 80 + // NOTE! Weirdly this is supposed to be a ulong, but there is an error in Win10 64-bit + // where it actually returns a uint! So had to engineer in a bug :( public uint SDRWhiteLevel; public bool Equals(DISPLAYCONFIG_SDR_WHITE_LEVEL other) @@ -706,14 +869,14 @@ namespace DisplayMagicianShared.Windows } [StructLayout(LayoutKind.Sequential)] - public struct RECT : IEquatable + public struct RECTL : IEquatable { public int Left; public int Top; public int Right; public int Bottom; - public bool Equals(RECT other) + public bool Equals(RECTL other) => Left == other.Left && Top == other.Top && Right == other.Right && @@ -730,6 +893,10 @@ namespace DisplayMagicianShared.Windows class CCDImport { + // Set some useful constants + public const SDC SDC_CCD_TEST_IF_VALID = (SDC.SDC_VALIDATE | SDC.SDC_USE_SUPPLIED_DISPLAY_CONFIG); + + // GetDisplayConfigBufferSizes [DllImport("user32")] public static extern WIN32STATUS GetDisplayConfigBufferSizes(QDC flags, out int numPathArrayElements, out int numModeInfoArrayElements); @@ -743,22 +910,22 @@ namespace DisplayMagicianShared.Windows // DisplayConfigGetDeviceInfo [DllImport("user32")] - public static extern WIN32STATUS DisplayConfigGetDeviceInfo(ref DISPLAYCONFIG_GET_SOURCE_NAME requestPacket); + public static extern WIN32STATUS DisplayConfigGetDeviceInfo(ref DISPLAYCONFIG_SOURCE_DEVICE_NAME requestPacket); [DllImport("user32")] - public static extern WIN32STATUS DisplayConfigGetDeviceInfo(ref DISPLAYCONFIG_GET_TARGET_NAME requestPacket); + public static extern WIN32STATUS DisplayConfigGetDeviceInfo(ref DISPLAYCONFIG_TARGET_DEVICE_NAME requestPacket); [DllImport("user32")] - public static extern WIN32STATUS DisplayConfigGetDeviceInfo(ref DISPLAYCONFIG_GET_TARGET_PREFERRED_NAME requestPacket); + public static extern WIN32STATUS DisplayConfigGetDeviceInfo(ref DISPLAYCONFIG_TARGET_PREFERRED_MODE requestPacket); [DllImport("user32")] - public static extern WIN32STATUS DisplayConfigGetDeviceInfo(ref DISPLAYCONFIG_GET_ADAPTER_NAME requestPacket); + public static extern WIN32STATUS DisplayConfigGetDeviceInfo(ref DISPLAYCONFIG_ADAPTER_NAME requestPacket); [DllImport("user32")] public static extern WIN32STATUS DisplayConfigGetDeviceInfo(ref DISPLAYCONFIG_SET_TARGET_PERSISTENCE requestPacket); [DllImport("user32")] - public static extern WIN32STATUS DisplayConfigGetDeviceInfo(ref DISPLAYCONFIG_GET_TARGET_BASE_TYPE requestPacket); + public static extern WIN32STATUS DisplayConfigGetDeviceInfo(ref DISPLAYCONFIG_TARGET_BASE_TYPE requestPacket); [DllImport("user32")] public static extern WIN32STATUS DisplayConfigGetDeviceInfo(ref DISPLAYCONFIG_SUPPORT_VIRTUAL_RESOLUTION requestPacket); @@ -777,7 +944,11 @@ namespace DisplayMagicianShared.Windows // DisplayConfigSetDeviceInfo [DllImport("user32")] - public static extern WIN32STATUS DisplayConfigSetDeviceInfo(ref DISPLAYCONFIG_SET_TARGET_PERSISTENCE targetPersistence); + public static extern WIN32STATUS DisplayConfigSetDeviceInfo(ref DISPLAYCONFIG_SET_TARGET_PERSISTENCE requestPacket); + + [DllImport("user32")] + public static extern WIN32STATUS DisplayConfigSetDeviceInfo(ref DISPLAYCONFIG_SET_ADVANCED_COLOR_STATE requestPacket); + // Have disabled the DisplayConfigSetDeviceInfo options except for SET_TARGET_PERSISTENCE, as per the note // from https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-displayconfigsetdeviceinfo @@ -787,7 +958,7 @@ namespace DisplayMagicianShared.Windows // SetDisplayConfig [DllImport("user32")] - public static extern WIN32STATUS SetDisplayConfig([In] uint pathArrayElements, [In] DISPLAYCONFIG_PATH_INFO[] pathArray, [In] uint modeInfoArrayElements, [In] DISPLAYCONFIG_MODE_INFO[] modeInfoArray, [In] QDC flags); + public static extern WIN32STATUS SetDisplayConfig([In] uint numPathArrayElements, [In] DISPLAYCONFIG_PATH_INFO[] pathArray, [In] uint numModeInfoArrayElements, [In] DISPLAYCONFIG_MODE_INFO[] modeInfoArray, [In] SDC flags); } -} +} \ No newline at end of file diff --git a/DisplayMagicianShared/Windows/WinLibrary.cs b/DisplayMagicianShared/Windows/WinLibrary.cs new file mode 100644 index 0000000..75a79a4 --- /dev/null +++ b/DisplayMagicianShared/Windows/WinLibrary.cs @@ -0,0 +1,986 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.InteropServices; +using System.Text; +using Microsoft.Win32.SafeHandles; +using DisplayMagicianShared; +using System.ComponentModel; + +namespace DisplayMagicianShared.Windows +{ + [StructLayout(LayoutKind.Sequential)] + public struct ADVANCED_HDR_INFO_PER_PATH : IEquatable + { + public LUID AdapterId; + public uint Id; + public DISPLAYCONFIG_GET_ADVANCED_COLOR_INFO AdvancedColorInfo; + public DISPLAYCONFIG_SDR_WHITE_LEVEL SDRWhiteLevel; + + public bool Equals(ADVANCED_HDR_INFO_PER_PATH other) + => // AdapterId.Equals(other.AdapterId) && // Removed the AdapterId from the Equals, as it changes after reboot. + Id == other.Id && + AdvancedColorInfo.Equals(other.AdvancedColorInfo) && + SDRWhiteLevel.Equals(other.SDRWhiteLevel); + public override int GetHashCode() + { + return (Id, AdvancedColorInfo, SDRWhiteLevel).GetHashCode(); + } + } + + [StructLayout(LayoutKind.Sequential)] + public struct WINDOWS_DISPLAY_CONFIG : IEquatable + { + public Dictionary displayAdapters; + public DISPLAYCONFIG_PATH_INFO[] displayConfigPaths; + public DISPLAYCONFIG_MODE_INFO[] displayConfigModes; + public ADVANCED_HDR_INFO_PER_PATH[] displayHDRStates; + + public bool Equals(WINDOWS_DISPLAY_CONFIG other) + => displayConfigPaths.SequenceEqual(other.displayConfigPaths) && + displayConfigModes.SequenceEqual(other.displayConfigModes) && + displayHDRStates.SequenceEqual(other.displayHDRStates); + + public override int GetHashCode() + { + return (displayConfigPaths, displayConfigModes, displayHDRStates).GetHashCode(); + } + } + + public class WinLibrary : IDisposable + { + + // Static members are 'eagerly initialized', that is, + // immediately when class is loaded for the first time. + // .NET guarantees thread safety for static initialization + private static WinLibrary _instance = new WinLibrary(); + + private bool _initialised = false; + + // To detect redundant calls + private bool _disposed = false; + + // Instantiate a SafeHandle instance. + private SafeHandle _safeHandle = new SafeFileHandle(IntPtr.Zero, true); + private IntPtr _adlContextHandle = IntPtr.Zero; + + static WinLibrary() { } + public WinLibrary() + { + SharedLogger.logger.Trace("WinLibrary/WinLibrary: Intialising Windows CCD library interface"); + _initialised = true; + SharedLogger.logger.Trace("WinLibrary/WinLibrary: ADL2 library was initialised successfully"); + + } + + ~WinLibrary() + { + // The WinLibrary was initialised, but doesn't need to be freed. + SharedLogger.logger.Trace("WinLibrary/~WinLibrary: Destroying Windows CCD library interface"); + } + + // Public implementation of Dispose pattern callable by consumers. + public void Dispose() => Dispose(true); + + // Protected implementation of Dispose pattern. + protected virtual void Dispose(bool disposing) + { + if (_disposed) + { + return; + } + + if (disposing) + { + // Dispose managed state (managed objects). + _safeHandle?.Dispose(); + } + + _disposed = true; + } + + + public bool IsInstalled + { + get + { + return _initialised; + } + } + + public static WinLibrary GetLibrary() + { + return _instance; + } + + private void PatchAdapterIDs(ref WINDOWS_DISPLAY_CONFIG savedDisplayConfig, Dictionary currentAdapterMap) + { + + Dictionary adapterOldToNewMap = new Dictionary(); + + SharedLogger.logger.Trace("WinLibrary/PatchAdapterIDs: Going through the list of adapters we stored in the config to figure out the old adapterIDs"); + foreach (KeyValuePair savedAdapter in savedDisplayConfig.displayAdapters) + { + foreach (KeyValuePair currentAdapter in currentAdapterMap) + { + if (currentAdapter.Value.Equals(savedAdapter.Value)) + { + // we have found the new LUID Value for the same adapter + // So we want to store it + SharedLogger.logger.Trace($"WinLibrary/PatchAdapterIDs: We found that saved adapter {savedAdapter.Key} has now been assigned adapter id {currentAdapter.Key} (AdapterName is {savedAdapter.Value})"); + adapterOldToNewMap.Add(savedAdapter.Key, currentAdapter.Key); + } + } + } + + ulong newAdapterValue = 0; + // Update the paths with the current adapter id + SharedLogger.logger.Trace($"WinLibrary/PatchAdapterIDs: Going through the display config paths to update the adapter id"); + for (int i = 0; i < savedDisplayConfig.displayConfigPaths.Length; i++) + { + // Change the Path SourceInfo and TargetInfo AdapterIDs + if (adapterOldToNewMap.ContainsKey(savedDisplayConfig.displayConfigPaths[i].SourceInfo.AdapterId.Value)) + { + // We get here if there is a matching adapter + newAdapterValue = adapterOldToNewMap[savedDisplayConfig.displayConfigPaths[i].SourceInfo.AdapterId.Value]; + savedDisplayConfig.displayConfigPaths[i].SourceInfo.AdapterId = AdapterValueToLUID(newAdapterValue); + newAdapterValue = adapterOldToNewMap[savedDisplayConfig.displayConfigPaths[i].TargetInfo.AdapterId.Value]; + savedDisplayConfig.displayConfigPaths[i].TargetInfo.AdapterId = AdapterValueToLUID(newAdapterValue); + } + else + { + // if there isn't a matching adapter, then we just pick the first current one and hope that works! + // (it is highly likely to... its only if the user has multiple graphics cards with some weird config it may break) + newAdapterValue = currentAdapterMap.First().Key; + SharedLogger.logger.Warn($"WinLibrary/PatchAdapterIDs: Uh Oh. Adapter {savedDisplayConfig.displayConfigPaths[i].SourceInfo.AdapterId.Value} didn't have a current match! It's possible the adapter was swapped or disabled. Attempting to use adapter {newAdapterValue} instead."); + savedDisplayConfig.displayConfigPaths[i].SourceInfo.AdapterId = AdapterValueToLUID(newAdapterValue); + savedDisplayConfig.displayConfigPaths[i].TargetInfo.AdapterId = AdapterValueToLUID(newAdapterValue); + } + } + + SharedLogger.logger.Trace($"WinLibrary/PatchAdapterIDs: Going through the display config modes to update the adapter id"); + // Update the modes with the current adapter id + for (int i = 0; i < savedDisplayConfig.displayConfigModes.Length; i++) + { + // Change the Mode AdapterID + if (adapterOldToNewMap.ContainsKey(savedDisplayConfig.displayConfigModes[i].AdapterId.Value)) + { + // We get here if there is a matching adapter + newAdapterValue = adapterOldToNewMap[savedDisplayConfig.displayConfigModes[i].AdapterId.Value]; + savedDisplayConfig.displayConfigModes[i].AdapterId = AdapterValueToLUID(newAdapterValue); + } + else + { + // if there isn't a matching adapter, then we just pick the first current one and hope that works! + // (it is highly likely to... its only if the user has multiple graphics cards with some weird config it may break) + newAdapterValue = currentAdapterMap.First().Key; + SharedLogger.logger.Warn($"WinLibrary/PatchAdapterIDs: Uh Oh. Adapter {savedDisplayConfig.displayConfigModes[i].AdapterId.Value} didn't have a current match! It's possible the adapter was swapped or disabled. Attempting to use adapter {newAdapterValue} instead."); + savedDisplayConfig.displayConfigModes[i].AdapterId = AdapterValueToLUID(newAdapterValue); + } + } + + SharedLogger.logger.Trace($"WinLibrary/PatchAdapterIDs: Going through the display config HDR info to update the adapter id"); + // Update the HDRInfo with the current adapter id + for (int i = 0; i < savedDisplayConfig.displayHDRStates.Length; i++) + { + // Change the Mode AdapterID + if (adapterOldToNewMap.ContainsKey(savedDisplayConfig.displayHDRStates[i].AdapterId.Value)) + { + // We get here if there is a matching adapter + newAdapterValue = adapterOldToNewMap[savedDisplayConfig.displayHDRStates[i].AdapterId.Value]; + savedDisplayConfig.displayHDRStates[i].AdapterId = AdapterValueToLUID(newAdapterValue); + newAdapterValue = adapterOldToNewMap[savedDisplayConfig.displayHDRStates[i].AdvancedColorInfo.Header.AdapterId.Value]; + savedDisplayConfig.displayHDRStates[i].AdvancedColorInfo.Header.AdapterId = AdapterValueToLUID(newAdapterValue); + newAdapterValue = adapterOldToNewMap[savedDisplayConfig.displayHDRStates[i].SDRWhiteLevel.Header.AdapterId.Value]; + savedDisplayConfig.displayHDRStates[i].SDRWhiteLevel.Header.AdapterId = AdapterValueToLUID(newAdapterValue); + } + else + { + // if there isn't a matching adapter, then we just pick the first current one and hope that works! + // (it is highly likely to... its only if the user has multiple graphics cards with some weird config it may break) + newAdapterValue = currentAdapterMap.First().Key; + SharedLogger.logger.Warn($"WinLibrary/PatchAdapterIDs: Uh Oh. Adapter {savedDisplayConfig.displayHDRStates[i].AdapterId.Value} didn't have a current match! It's possible the adapter was swapped or disabled. Attempting to use adapter {newAdapterValue} instead."); + savedDisplayConfig.displayHDRStates[i].AdapterId = AdapterValueToLUID(newAdapterValue); + savedDisplayConfig.displayHDRStates[i].AdvancedColorInfo.Header.AdapterId = AdapterValueToLUID(newAdapterValue); + savedDisplayConfig.displayHDRStates[i].SDRWhiteLevel.Header.AdapterId = AdapterValueToLUID(newAdapterValue); + } + } + + } + + public WINDOWS_DISPLAY_CONFIG GetActiveConfig() + { + SharedLogger.logger.Trace($"WinLibrary/GetActiveConfig: Getting the currently active config"); + return GetWindowsDisplayConfig(QDC.QDC_ONLY_ACTIVE_PATHS); + } + + private WINDOWS_DISPLAY_CONFIG GetWindowsDisplayConfig(QDC selector = QDC.QDC_ONLY_ACTIVE_PATHS) + { + // Get the size of the largest Active Paths and Modes arrays + SharedLogger.logger.Trace($"WinLibrary/GetWindowsDisplayConfig: Getting the size of the largest Active Paths and Modes arrays"); + int pathCount = 0; + int modeCount = 0; + WIN32STATUS err = CCDImport.GetDisplayConfigBufferSizes(QDC.QDC_ONLY_ACTIVE_PATHS, out pathCount, out modeCount); + if (err != WIN32STATUS.ERROR_SUCCESS) + { + SharedLogger.logger.Error($"WinLibrary/GetWindowsDisplayConfig: ERROR - GetDisplayConfigBufferSizes returned WIN32STATUS {err} when trying to get the maximum path and mode sizes"); + throw new WinLibraryException($"GetDisplayConfigBufferSizes returned WIN32STATUS {err} when trying to get the maximum path and mode sizes"); + } + + SharedLogger.logger.Trace($"WinLibrary/GetWindowsDisplayConfig: Getting the current Display Config path and mode arrays"); + var paths = new DISPLAYCONFIG_PATH_INFO[pathCount]; + var modes = new DISPLAYCONFIG_MODE_INFO[modeCount]; + err = CCDImport.QueryDisplayConfig(QDC.QDC_ONLY_ACTIVE_PATHS, ref pathCount, paths, ref modeCount, modes, IntPtr.Zero); + if (err == WIN32STATUS.ERROR_INSUFFICIENT_BUFFER) + { + SharedLogger.logger.Warn($"WinLibrary/GetWindowsDisplayConfig: The displays were modified between GetDisplayConfigBufferSizes and QueryDisplayConfig so we need to get the buffer sizes again."); + SharedLogger.logger.Trace($"WinLibrary/GetWindowsDisplayConfig: Getting the size of the largest Active Paths and Modes arrays"); + // Screen changed in between GetDisplayConfigBufferSizes and QueryDisplayConfig, so we need to get buffer sizes again + // as per https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-querydisplayconfig + err = CCDImport.GetDisplayConfigBufferSizes(QDC.QDC_ONLY_ACTIVE_PATHS, out pathCount, out modeCount); + if (err != WIN32STATUS.ERROR_SUCCESS) + { + SharedLogger.logger.Error($"WinLibrary/GetWindowsDisplayConfig: ERROR - GetDisplayConfigBufferSizes returned WIN32STATUS {err} when trying to get the maximum path and mode sizes again"); + throw new WinLibraryException($"GetDisplayConfigBufferSizes returned WIN32STATUS {err} when trying to get the maximum path and mode sizes again"); + } + SharedLogger.logger.Trace($"WinLibrary/GetWindowsDisplayConfig: Getting the current Display Config path and mode arrays"); + paths = new DISPLAYCONFIG_PATH_INFO[pathCount]; + modes = new DISPLAYCONFIG_MODE_INFO[modeCount]; + err = CCDImport.QueryDisplayConfig(QDC.QDC_ONLY_ACTIVE_PATHS, ref pathCount, paths, ref modeCount, modes, IntPtr.Zero); + if (err == WIN32STATUS.ERROR_INSUFFICIENT_BUFFER) + { + SharedLogger.logger.Error($"WinLibrary/GetWindowsDisplayConfig: ERROR - The displays were still modified between GetDisplayConfigBufferSizes and QueryDisplayConfig, even though we tried twice. Something is wrong."); + throw new WinLibraryException($"The displays were still modified between GetDisplayConfigBufferSizes and QueryDisplayConfig, even though we tried twice. Something is wrong."); + } + else if (err != WIN32STATUS.ERROR_SUCCESS) + { + SharedLogger.logger.Error($"WinLibrary/GetWindowsDisplayConfig: ERROR - QueryDisplayConfig returned WIN32STATUS {err} when trying to query all available displays again"); + throw new WinLibraryException($"QueryDisplayConfig returned WIN32STATUS {err} when trying to query all available displays again."); + } + } + else if (err != WIN32STATUS.ERROR_SUCCESS) + { + SharedLogger.logger.Error($"WinLibrary/GetWindowsDisplayConfig: ERROR - QueryDisplayConfig returned WIN32STATUS {err} when trying to query all available displays"); + throw new WinLibraryException($"QueryDisplayConfig returned WIN32STATUS {err} when trying to query all available displays."); + } + + // Prepare the empty windows display config + WINDOWS_DISPLAY_CONFIG windowsDisplayConfig = new WINDOWS_DISPLAY_CONFIG(); + windowsDisplayConfig.displayAdapters = new Dictionary(); + windowsDisplayConfig.displayHDRStates = new ADVANCED_HDR_INFO_PER_PATH[pathCount]; + + // Now cycle through the paths and grab the HDR state information + // and map the adapter name to adapter id + var hdrInfos = new ADVANCED_HDR_INFO_PER_PATH[pathCount]; + int hdrInfoCount = 0; + foreach (var path in paths) + { + // Get adapter ID for later + SharedLogger.logger.Trace($"WinLibrary/GetWindowsDisplayConfig: Attempting to get adapter name for adapter {path.TargetInfo.AdapterId.Value}."); + if (!windowsDisplayConfig.displayAdapters.ContainsKey(path.TargetInfo.AdapterId.Value)) + { + var adapterInfo = new DISPLAYCONFIG_ADAPTER_NAME(); + adapterInfo.Header.Type = DISPLAYCONFIG_DEVICE_INFO_TYPE.DISPLAYCONFIG_DEVICE_INFO_GET_ADAPTER_NAME; + adapterInfo.Header.Size = (uint)Marshal.SizeOf(); + adapterInfo.Header.AdapterId = path.TargetInfo.AdapterId; + adapterInfo.Header.Id = path.TargetInfo.Id; + err = CCDImport.DisplayConfigGetDeviceInfo(ref adapterInfo); + if (err == WIN32STATUS.ERROR_SUCCESS) + { + // Store it for later + windowsDisplayConfig.displayAdapters.Add(path.TargetInfo.AdapterId.Value, adapterInfo.AdapterDevicePath); + SharedLogger.logger.Trace($"WinLibrary/GetWindowsDisplayConfig: Found adapter name {adapterInfo.AdapterDevicePath} for adapter {path.TargetInfo.AdapterId.Value}."); + } + else + { + SharedLogger.logger.Error($"WinLibrary/GetWindowsDisplayConfig: ERROR - DisplayConfigGetDeviceInfo returned WIN32STATUS {err} when trying to query the adapter name for adapter {path.TargetInfo.AdapterId.Value}."); + } + } + + // Get advanced color info + SharedLogger.logger.Trace($"WinLibrary/GetWindowsDisplayConfig: Attempting to get advanced color info for display {path.TargetInfo.Id}."); + var colorInfo = new DISPLAYCONFIG_GET_ADVANCED_COLOR_INFO(); + colorInfo.Header.Type = DISPLAYCONFIG_DEVICE_INFO_TYPE.DISPLAYCONFIG_DEVICE_INFO_GET_ADVANCED_COLOR_INFO; + colorInfo.Header.Size = (uint)Marshal.SizeOf(); + colorInfo.Header.AdapterId = path.TargetInfo.AdapterId; + colorInfo.Header.Id = path.TargetInfo.Id; + err = CCDImport.DisplayConfigGetDeviceInfo(ref colorInfo); + if (err == WIN32STATUS.ERROR_SUCCESS) + { + SharedLogger.logger.Trace($"WinLibrary/GetWindowsDisplayConfig: Found color info for display {path.TargetInfo.Id}."); + if (colorInfo.AdvancedColorSupported) + { + SharedLogger.logger.Trace($"WinLibrary/GetWindowsDisplayConfig: HDR is supported for display {path.TargetInfo.Id}."); + } + else + { + SharedLogger.logger.Trace($"WinLibrary/GetWindowsDisplayConfig: HDR is NOT supported for display {path.TargetInfo.Id}."); + } + if (colorInfo.AdvancedColorEnabled) + { + SharedLogger.logger.Trace($"WinLibrary/GetWindowsDisplayConfig: HDR is enabled for display {path.TargetInfo.Id}."); + } + else + { + SharedLogger.logger.Trace($"WinLibrary/GetWindowsDisplayConfig: HDR is NOT enabled for display {path.TargetInfo.Id}."); + } + } + else + { + SharedLogger.logger.Warn($"WinLibrary/GetWindowsDisplayConfig: WARNING - Unabled to get advanced color settings for display {path.TargetInfo.Id}."); + } + + // get SDR white levels + SharedLogger.logger.Trace($"WinLibrary/GetWindowsDisplayConfig: Attempting to get SDR white levels for adapter {path.TargetInfo.AdapterId.Value}."); + var whiteLevelInfo = new DISPLAYCONFIG_SDR_WHITE_LEVEL(); + whiteLevelInfo.Header.Type = DISPLAYCONFIG_DEVICE_INFO_TYPE.DISPLAYCONFIG_DEVICE_INFO_GET_SDR_WHITE_LEVEL; + whiteLevelInfo.Header.Size = (uint)Marshal.SizeOf(); + whiteLevelInfo.Header.AdapterId = path.TargetInfo.AdapterId; + whiteLevelInfo.Header.Id = path.TargetInfo.Id; + err = CCDImport.DisplayConfigGetDeviceInfo(ref whiteLevelInfo); + if (err == WIN32STATUS.ERROR_SUCCESS) + { + SharedLogger.logger.Trace($"WinLibrary/GetWindowsDisplayConfig: Found SDR White levels for display {path.TargetInfo.Id}."); + } + else + { + SharedLogger.logger.Warn($"WinLibrary/GetWindowsDisplayConfig: WARNING - Unabled to get SDR White levels for display {path.TargetInfo.Id}."); + } + + hdrInfos[hdrInfoCount] = new ADVANCED_HDR_INFO_PER_PATH(); + hdrInfos[hdrInfoCount].AdapterId = path.TargetInfo.AdapterId; + hdrInfos[hdrInfoCount].Id = path.TargetInfo.Id; + hdrInfos[hdrInfoCount].AdvancedColorInfo = colorInfo; + hdrInfos[hdrInfoCount].SDRWhiteLevel = whiteLevelInfo; + hdrInfoCount++; + } + + // Store the active paths and modes in our display config object + windowsDisplayConfig.displayConfigPaths = paths; + windowsDisplayConfig.displayConfigModes = modes; + windowsDisplayConfig.displayHDRStates = hdrInfos; + + return windowsDisplayConfig; + } + + + private LUID AdapterValueToLUID(ulong adapterValue) + { + LUID luid = new LUID(); + luid.LowPart = (uint)(adapterValue & uint.MaxValue); + luid.HighPart = (uint)(adapterValue >> 32); + return luid; + } + + public string PrintActiveConfig() + { + string stringToReturn = ""; + + // Get the size of the largest Active Paths and Modes arrays + int pathCount = 0; + int modeCount = 0; + WIN32STATUS err = CCDImport.GetDisplayConfigBufferSizes(QDC.QDC_ONLY_ACTIVE_PATHS, out pathCount, out modeCount); + if (err != WIN32STATUS.ERROR_SUCCESS) + { + SharedLogger.logger.Error($"WinLibrary/PrintActiveConfig: ERROR - GetDisplayConfigBufferSizes returned WIN32STATUS {err} when trying to get the maximum path and mode sizes"); + throw new WinLibraryException($"GetDisplayConfigBufferSizes returned WIN32STATUS {err} when trying to get the maximum path and mode sizes"); + } + + SharedLogger.logger.Trace($"WinLibrary/PrintActiveConfig: Getting the current Display Config path and mode arrays"); + var paths = new DISPLAYCONFIG_PATH_INFO[pathCount]; + var modes = new DISPLAYCONFIG_MODE_INFO[modeCount]; + err = CCDImport.QueryDisplayConfig(QDC.QDC_ONLY_ACTIVE_PATHS, ref pathCount, paths, ref modeCount, modes, IntPtr.Zero); + if (err == WIN32STATUS.ERROR_INSUFFICIENT_BUFFER) + { + SharedLogger.logger.Warn($"WinLibrary/PrintActiveConfig: The displays were modified between GetDisplayConfigBufferSizes and QueryDisplayConfig so we need to get the buffer sizes again."); + SharedLogger.logger.Trace($"WinLibrary/PrintActiveConfig: Getting the size of the largest Active Paths and Modes arrays"); + // Screen changed in between GetDisplayConfigBufferSizes and QueryDisplayConfig, so we need to get buffer sizes again + // as per https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-querydisplayconfig + err = CCDImport.GetDisplayConfigBufferSizes(QDC.QDC_ONLY_ACTIVE_PATHS, out pathCount, out modeCount); + if (err != WIN32STATUS.ERROR_SUCCESS) + { + SharedLogger.logger.Error($"WinLibrary/PrintActiveConfig: ERROR - GetDisplayConfigBufferSizes returned WIN32STATUS {err} when trying to get the maximum path and mode sizes again"); + throw new WinLibraryException($"GetDisplayConfigBufferSizes returned WIN32STATUS {err} when trying to get the maximum path and mode sizes again"); + } + SharedLogger.logger.Trace($"WinLibrary/PrintActiveConfig: Getting the current Display Config path and mode arrays"); + paths = new DISPLAYCONFIG_PATH_INFO[pathCount]; + modes = new DISPLAYCONFIG_MODE_INFO[modeCount]; + err = CCDImport.QueryDisplayConfig(QDC.QDC_ONLY_ACTIVE_PATHS, ref pathCount, paths, ref modeCount, modes, IntPtr.Zero); + if (err == WIN32STATUS.ERROR_INSUFFICIENT_BUFFER) + { + SharedLogger.logger.Error($"WinLibrary/PrintActiveConfig: ERROR - The displays were still modified between GetDisplayConfigBufferSizes and QueryDisplayConfig, even though we tried twice. Something is wrong."); + throw new WinLibraryException($"The displays were still modified between GetDisplayConfigBufferSizes and QueryDisplayConfig, even though we tried twice. Something is wrong."); + } + else if (err != WIN32STATUS.ERROR_SUCCESS) + { + SharedLogger.logger.Error($"WinLibrary/PrintActiveConfig: ERROR - QueryDisplayConfig returned WIN32STATUS {err} when trying to query all available displays again"); + throw new WinLibraryException($"QueryDisplayConfig returned WIN32STATUS {err} when trying to query all available displays again."); + } + } + else if (err != WIN32STATUS.ERROR_SUCCESS) + { + SharedLogger.logger.Error($"WinLibrary/PrintActiveConfig: ERROR - QueryDisplayConfig returned WIN32STATUS {err} when trying to query all available displays"); + throw new WinLibraryException($"QueryDisplayConfig returned WIN32STATUS {err} when trying to query all available displays."); + } + + foreach (var path in paths) + { + stringToReturn += $"----++++==== Path ====++++----\n"; + + // get display source name + var sourceInfo = new DISPLAYCONFIG_SOURCE_DEVICE_NAME(); + sourceInfo.Header.Type = DISPLAYCONFIG_DEVICE_INFO_TYPE.DISPLAYCONFIG_DEVICE_INFO_GET_SOURCE_NAME; + sourceInfo.Header.Size = (uint)Marshal.SizeOf(); + sourceInfo.Header.AdapterId = path.SourceInfo.AdapterId; + sourceInfo.Header.Id = path.SourceInfo.Id; + err = CCDImport.DisplayConfigGetDeviceInfo(ref sourceInfo); + if (err == WIN32STATUS.ERROR_SUCCESS) + { + SharedLogger.logger.Trace($"WinLibrary/PrintActiveConfig: Found Display Source {sourceInfo.ViewGdiDeviceName} for source {path.SourceInfo.Id}."); + stringToReturn += $"****** Interrogating Display Source {path.SourceInfo.Id} *******\n"; + stringToReturn += $"Found Display Source {sourceInfo.ViewGdiDeviceName}\n"; + stringToReturn += $"\n"; + } + else + { + SharedLogger.logger.Warn($"WinLibrary/PrintActiveConfig: WARNING - DisplayConfigGetDeviceInfo returned WIN32STATUS {err} when trying to get the source info for source adapter #{path.SourceInfo.AdapterId}"); + } + + + // get display target name + var targetInfo = new DISPLAYCONFIG_TARGET_DEVICE_NAME(); + targetInfo.Header.Type = DISPLAYCONFIG_DEVICE_INFO_TYPE.DISPLAYCONFIG_DEVICE_INFO_GET_TARGET_NAME; + targetInfo.Header.Size = (uint)Marshal.SizeOf(); + targetInfo.Header.AdapterId = path.TargetInfo.AdapterId; + targetInfo.Header.Id = path.TargetInfo.Id; + err = CCDImport.DisplayConfigGetDeviceInfo(ref targetInfo); + if (err == WIN32STATUS.ERROR_SUCCESS) + { + SharedLogger.logger.Trace($"WinLibrary/PrintActiveConfig: Connector Instance: {targetInfo.ConnectorInstance} for source {path.TargetInfo.Id}."); + SharedLogger.logger.Trace($"WinLibrary/PrintActiveConfig: EDID Manufacturer ID: {targetInfo.EdidManufactureId} for source {path.TargetInfo.Id}."); + SharedLogger.logger.Trace($"WinLibrary/PrintActiveConfig: EDID Product Code ID: {targetInfo.EdidProductCodeId} for source {path.TargetInfo.Id}."); + SharedLogger.logger.Trace($"WinLibrary/PrintActiveConfig: Flags Friendly Name from EDID: {targetInfo.Flags.FriendlyNameFromEdid} for source {path.TargetInfo.Id}."); + SharedLogger.logger.Trace($"WinLibrary/PrintActiveConfig: Flags Friendly Name Forced: {targetInfo.Flags.FriendlyNameForced} for source {path.TargetInfo.Id}."); + SharedLogger.logger.Trace($"WinLibrary/PrintActiveConfig: Flags EDID ID is Valid: {targetInfo.Flags.EdidIdsValid} for source {path.TargetInfo.Id}."); + SharedLogger.logger.Trace($"WinLibrary/PrintActiveConfig: Monitor Device Path: {targetInfo.MonitorDevicePath} for source {path.TargetInfo.Id}."); + SharedLogger.logger.Trace($"WinLibrary/PrintActiveConfig: Monitor Friendly Device Name: {targetInfo.MonitorFriendlyDeviceName} for source {path.TargetInfo.Id}."); + SharedLogger.logger.Trace($"WinLibrary/PrintActiveConfig: Output Technology: {targetInfo.OutputTechnology} for source {path.TargetInfo.Id}."); + + stringToReturn += $"****** Interrogating Display Target {targetInfo.MonitorFriendlyDeviceName} *******\n"; + stringToReturn += $" Connector Instance: {targetInfo.ConnectorInstance}\n"; + stringToReturn += $" EDID Manufacturer ID: {targetInfo.EdidManufactureId}\n"; + stringToReturn += $" EDID Product Code ID: {targetInfo.EdidProductCodeId}\n"; + stringToReturn += $" Flags Friendly Name from EDID: {targetInfo.Flags.FriendlyNameFromEdid}\n"; + stringToReturn += $" Flags Friendly Name Forced: {targetInfo.Flags.FriendlyNameForced}\n"; + stringToReturn += $" Flags EDID ID is Valid: {targetInfo.Flags.EdidIdsValid}\n"; + stringToReturn += $" Monitor Device Path: {targetInfo.MonitorDevicePath}\n"; + stringToReturn += $" Monitor Friendly Device Name: {targetInfo.MonitorFriendlyDeviceName}\n"; + stringToReturn += $" Output Technology: {targetInfo.OutputTechnology}\n"; + stringToReturn += $"\n"; + } + else + { + SharedLogger.logger.Warn($"WinLibrary/PrintActiveConfig: WARNING - DisplayConfigGetDeviceInfo returned WIN32STATUS {err} when trying to get the target info for display #{path.TargetInfo.Id}"); + } + + + // get display adapter name + var adapterInfo = new DISPLAYCONFIG_ADAPTER_NAME(); + adapterInfo.Header.Type = DISPLAYCONFIG_DEVICE_INFO_TYPE.DISPLAYCONFIG_DEVICE_INFO_GET_ADAPTER_NAME; + adapterInfo.Header.Size = (uint)Marshal.SizeOf(); + adapterInfo.Header.AdapterId = path.TargetInfo.AdapterId; + adapterInfo.Header.Id = path.TargetInfo.Id; + err = CCDImport.DisplayConfigGetDeviceInfo(ref adapterInfo); + if (err == WIN32STATUS.ERROR_SUCCESS) + { + SharedLogger.logger.Trace($"WinLibrary/PrintActiveConfig: Found Adapter Device Path {adapterInfo.AdapterDevicePath} for source {path.TargetInfo.AdapterId}."); + stringToReturn += $"****** Interrogating Display Adapter {adapterInfo.AdapterDevicePath} *******\n"; + stringToReturn += $" Display Adapter {adapterInfo.AdapterDevicePath}\n"; + stringToReturn += $"\n"; + } + else + { + SharedLogger.logger.Warn($"WinLibrary/GetWindowsDisplayConfig: WARNING - DisplayConfigGetDeviceInfo returned WIN32STATUS {err} when trying to get the adapter device path for target #{path.TargetInfo.AdapterId}"); + } + + // get display target preferred mode + var targetPreferredInfo = new DISPLAYCONFIG_TARGET_PREFERRED_MODE(); + targetPreferredInfo.Header.Type = DISPLAYCONFIG_DEVICE_INFO_TYPE.DISPLAYCONFIG_DEVICE_INFO_GET_TARGET_PREFERRED_MODE; + targetPreferredInfo.Header.Size = (uint)Marshal.SizeOf(); + targetPreferredInfo.Header.AdapterId = path.TargetInfo.AdapterId; + targetPreferredInfo.Header.Id = path.TargetInfo.Id; + err = CCDImport.DisplayConfigGetDeviceInfo(ref targetPreferredInfo); + if (err == WIN32STATUS.ERROR_SUCCESS) + { + SharedLogger.logger.Trace($"WinLibrary/GetWindowsDisplayConfig: Found Target Preferred Width {targetPreferredInfo.Width} for target {path.TargetInfo.Id}."); + SharedLogger.logger.Trace($"WinLibrary/GetWindowsDisplayConfig: Found Target Preferred Height {targetPreferredInfo.Height} for target {path.TargetInfo.Id}."); + SharedLogger.logger.Trace($"WinLibrary/GetWindowsDisplayConfig: Found Target Video Signal Info Active Size: ({targetPreferredInfo.TargetMode.TargetVideoSignalInfo.ActiveSize.Cx}x{targetPreferredInfo.TargetMode.TargetVideoSignalInfo.ActiveSize.Cy} for target {path.TargetInfo.Id}."); + SharedLogger.logger.Trace($"WinLibrary/GetWindowsDisplayConfig: Found Target Video Signal Info Total Size: ({targetPreferredInfo.TargetMode.TargetVideoSignalInfo.TotalSize.Cx}x{targetPreferredInfo.TargetMode.TargetVideoSignalInfo.TotalSize.Cy} for target {path.TargetInfo.Id}."); + SharedLogger.logger.Trace($"WinLibrary/GetWindowsDisplayConfig: Found Target Video Signal Info HSync Frequency: {targetPreferredInfo.TargetMode.TargetVideoSignalInfo.HSyncFreq} for target {path.TargetInfo.Id}."); + SharedLogger.logger.Trace($"WinLibrary/GetWindowsDisplayConfig: Found Target Video Signal Info VSync Frequency: {targetPreferredInfo.TargetMode.TargetVideoSignalInfo.VSyncFreq} for target {path.TargetInfo.Id}."); + SharedLogger.logger.Trace($"WinLibrary/GetWindowsDisplayConfig: Found Target Video Signal Info Pixel Rate: {targetPreferredInfo.TargetMode.TargetVideoSignalInfo.PixelRate} for target {path.TargetInfo.Id}."); + SharedLogger.logger.Trace($"WinLibrary/GetWindowsDisplayConfig: Found Target Video Signal Info Scan Line Ordering: {targetPreferredInfo.TargetMode.TargetVideoSignalInfo.ScanLineOrdering} for target {path.TargetInfo.Id}."); + SharedLogger.logger.Trace($"WinLibrary/GetWindowsDisplayConfig: Found Target Video Signal Info Video Standard: {targetPreferredInfo.TargetMode.TargetVideoSignalInfo.VideoStandard} for target {path.TargetInfo.Id}."); + + stringToReturn += $"****** Interrogating Target Preferred Mode for Display {path.TargetInfo.Id} *******\n"; + stringToReturn += $" Target Preferred Width {targetPreferredInfo.Width} for target {path.TargetInfo.Id}\n"; + stringToReturn += $" Target Preferred Height {targetPreferredInfo.Height} for target {path.TargetInfo.Id}\n"; + stringToReturn += $" Target Video Signal Info Active Size: ({targetPreferredInfo.TargetMode.TargetVideoSignalInfo.ActiveSize.Cx}x{targetPreferredInfo.TargetMode.TargetVideoSignalInfo.ActiveSize.Cy}\n"; + stringToReturn += $" Target Video Signal Info Total Size: ({targetPreferredInfo.TargetMode.TargetVideoSignalInfo.TotalSize.Cx}x{targetPreferredInfo.TargetMode.TargetVideoSignalInfo.TotalSize.Cy}\n"; + stringToReturn += $" Target Video Signal Info HSync Frequency: {targetPreferredInfo.TargetMode.TargetVideoSignalInfo.HSyncFreq}\n"; + stringToReturn += $" Target Video Signal Info VSync Frequency: {targetPreferredInfo.TargetMode.TargetVideoSignalInfo.VSyncFreq}\n"; + stringToReturn += $" Target Video Signal Info Pixel Rate: {targetPreferredInfo.TargetMode.TargetVideoSignalInfo.PixelRate}\n"; + stringToReturn += $" Target Video Signal Info Scan Line Ordering: {targetPreferredInfo.TargetMode.TargetVideoSignalInfo.ScanLineOrdering}\n"; + stringToReturn += $" Target Video Signal Info Video Standard: {targetPreferredInfo.TargetMode.TargetVideoSignalInfo.VideoStandard}\n"; + stringToReturn += $"\n"; + } + else + { + SharedLogger.logger.Warn($"WinLibrary/GetWindowsDisplayConfig: WARNING - DisplayConfigGetDeviceInfo returned WIN32STATUS {err} when trying to get the preferred target name for display #{path.TargetInfo.Id}"); + } + + // get display target base type + var targetBaseTypeInfo = new DISPLAYCONFIG_TARGET_BASE_TYPE(); + targetBaseTypeInfo.Header.Type = DISPLAYCONFIG_DEVICE_INFO_TYPE.DISPLAYCONFIG_DEVICE_INFO_GET_TARGET_BASE_TYPE; + targetBaseTypeInfo.Header.Size = (uint)Marshal.SizeOf(); + targetBaseTypeInfo.Header.AdapterId = path.TargetInfo.AdapterId; + targetBaseTypeInfo.Header.Id = path.TargetInfo.Id; + err = CCDImport.DisplayConfigGetDeviceInfo(ref targetBaseTypeInfo); + if (err == WIN32STATUS.ERROR_SUCCESS) + { + SharedLogger.logger.Trace($"WinLibrary/GetWindowsDisplayConfig: Found Virtual Resolution is Disabled: {targetBaseTypeInfo.BaseOutputTechnology} for target {path.TargetInfo.Id}."); + + stringToReturn += $"****** Interrogating Target Base Type for Display {path.TargetInfo.Id} *******\n"; + stringToReturn += $" Base Output Technology: {targetBaseTypeInfo.BaseOutputTechnology}\n"; + stringToReturn += $"\n"; + } + else + { + SharedLogger.logger.Warn($"WinLibrary/GetWindowsDisplayConfig: WARNING - DisplayConfigGetDeviceInfo returned WIN32STATUS {err} when trying to get the target base type for display #{path.TargetInfo.Id}"); + } + + // get display support virtual resolution + var supportVirtResInfo = new DISPLAYCONFIG_SUPPORT_VIRTUAL_RESOLUTION(); + supportVirtResInfo.Header.Type = DISPLAYCONFIG_DEVICE_INFO_TYPE.DISPLAYCONFIG_DEVICE_INFO_GET_SUPPORT_VIRTUAL_RESOLUTION; + supportVirtResInfo.Header.Size = (uint)Marshal.SizeOf(); + supportVirtResInfo.Header.AdapterId = path.TargetInfo.AdapterId; + supportVirtResInfo.Header.Id = path.TargetInfo.Id; + err = CCDImport.DisplayConfigGetDeviceInfo(ref supportVirtResInfo); + if (err == WIN32STATUS.ERROR_SUCCESS) + { + SharedLogger.logger.Trace($"WinLibrary/GetWindowsDisplayConfig: Found Base Output Technology: {supportVirtResInfo.IsMonitorVirtualResolutionDisabled} for target {path.TargetInfo.Id}."); + stringToReturn += $"****** Interrogating Target Supporting virtual resolution for Display {path.TargetInfo.Id} *******\n"; + stringToReturn += $" Virtual Resolution is Disabled: {supportVirtResInfo.IsMonitorVirtualResolutionDisabled}\n"; + stringToReturn += $"\n"; + } + else + { + SharedLogger.logger.Warn($"WinLibrary/GetWindowsDisplayConfig: WARNING - DisplayConfigGetDeviceInfo returned WIN32STATUS {err} when trying to find out the virtual resolution support for display #{path.TargetInfo.Id}"); + } + + //get advanced color info + var colorInfo = new DISPLAYCONFIG_GET_ADVANCED_COLOR_INFO(); + colorInfo.Header.Type = DISPLAYCONFIG_DEVICE_INFO_TYPE.DISPLAYCONFIG_DEVICE_INFO_GET_ADVANCED_COLOR_INFO; + colorInfo.Header.Size = (uint)Marshal.SizeOf(); + colorInfo.Header.AdapterId = path.TargetInfo.AdapterId; + colorInfo.Header.Id = path.TargetInfo.Id; + err = CCDImport.DisplayConfigGetDeviceInfo(ref colorInfo); + if (err == WIN32STATUS.ERROR_SUCCESS) + { + SharedLogger.logger.Trace($"WinLibrary/GetWindowsDisplayConfig: Found Advanced Color Supported: {colorInfo.AdvancedColorSupported} for target {path.TargetInfo.Id}."); + SharedLogger.logger.Trace($"WinLibrary/GetWindowsDisplayConfig: Found Advanced Color Enabled: {colorInfo.AdvancedColorEnabled} for target {path.TargetInfo.Id}."); + SharedLogger.logger.Trace($"WinLibrary/GetWindowsDisplayConfig: Found Advanced Color Force Disabled: {colorInfo.AdvancedColorForceDisabled} for target {path.TargetInfo.Id}."); + SharedLogger.logger.Trace($"WinLibrary/GetWindowsDisplayConfig: Found Bits per Color Channel: {colorInfo.BitsPerColorChannel} for target {path.TargetInfo.Id}."); + SharedLogger.logger.Trace($"WinLibrary/GetWindowsDisplayConfig: Found Color Encoding: {colorInfo.ColorEncoding} for target {path.TargetInfo.Id}."); + SharedLogger.logger.Trace($"WinLibrary/GetWindowsDisplayConfig: Found Wide Color Enforced: {colorInfo.WideColorEnforced} for target {path.TargetInfo.Id}."); + + stringToReturn += $"****** Interrogating Advanced Color Info for Display {path.TargetInfo.Id} *******\n"; + stringToReturn += $" Advanced Color Supported: {colorInfo.AdvancedColorSupported}\n"; + stringToReturn += $" Advanced Color Enabled: {colorInfo.AdvancedColorEnabled}\n"; + stringToReturn += $" Advanced Color Force Disabled: {colorInfo.AdvancedColorForceDisabled}\n"; + stringToReturn += $" Bits per Color Channel: {colorInfo.BitsPerColorChannel}\n"; + stringToReturn += $" Color Encoding: {colorInfo.ColorEncoding}\n"; + stringToReturn += $" Wide Color Enforced: {colorInfo.WideColorEnforced}\n"; + stringToReturn += $"\n"; + } + else + { + SharedLogger.logger.Warn($"WinLibrary/GetWindowsDisplayConfig: WARNING - DisplayConfigGetDeviceInfo returned WIN32STATUS {err} when trying to find out the virtual resolution support for display #{path.TargetInfo.Id}"); + } + + // get SDR white levels + var whiteLevelInfo = new DISPLAYCONFIG_SDR_WHITE_LEVEL(); + whiteLevelInfo.Header.Type = DISPLAYCONFIG_DEVICE_INFO_TYPE.DISPLAYCONFIG_DEVICE_INFO_GET_SDR_WHITE_LEVEL; + whiteLevelInfo.Header.Size = (uint)Marshal.SizeOf(); + whiteLevelInfo.Header.AdapterId = path.TargetInfo.AdapterId; + whiteLevelInfo.Header.Id = path.TargetInfo.Id; + err = CCDImport.DisplayConfigGetDeviceInfo(ref whiteLevelInfo); + if (err == WIN32STATUS.ERROR_SUCCESS) + { + SharedLogger.logger.Trace($"WinLibrary/GetWindowsDisplayConfig: Found SDR White Level: {whiteLevelInfo.SDRWhiteLevel} for target {path.TargetInfo.Id}."); + + stringToReturn += $"****** Interrogating SDR Whilte Level for Display {path.TargetInfo.Id} *******\n"; + stringToReturn += $" SDR White Level: {whiteLevelInfo.SDRWhiteLevel}\n"; + stringToReturn += $"\n"; + } + else + { + SharedLogger.logger.Warn($"WinLibrary/GetWindowsDisplayConfig: WARNING - DisplayConfigGetDeviceInfo returned WIN32STATUS {err} when trying to find out the SDL white level for display #{path.TargetInfo.Id}"); + } + } + return stringToReturn; + } + + public bool SetActiveConfig(WINDOWS_DISPLAY_CONFIG displayConfig) + { + // Get the all possible windows display configs + SharedLogger.logger.Trace($"WinLibrary/SetActiveConfig: Generating a list of all the current display configs"); + WINDOWS_DISPLAY_CONFIG allWindowsDisplayConfig = GetWindowsDisplayConfig(QDC.QDC_ALL_PATHS); + + // Now we go through the Paths to update the LUIDs as per Soroush's suggestion + SharedLogger.logger.Trace($"WinLibrary/SetActiveConfig: Patching the adapter IDs to make the saved config valid"); + PatchAdapterIDs(ref displayConfig, allWindowsDisplayConfig.displayAdapters); + + SharedLogger.logger.Trace($"WinLibrary/SetActiveConfig: Testing whether the display configuration is valid"); + // Test whether a specified display configuration is supported on the computer + uint myPathsCount = (uint)displayConfig.displayConfigPaths.Length; + uint myModesCount = (uint)displayConfig.displayConfigModes.Length; + WIN32STATUS err = CCDImport.SetDisplayConfig(myPathsCount, displayConfig.displayConfigPaths, myModesCount, displayConfig.displayConfigModes, SDC.DISPLAYMAGICIAN_VALIDATE); + if (err == WIN32STATUS.ERROR_SUCCESS) + { + SharedLogger.logger.Trace($"WinLibrary/SetActiveConfig: Successfully validated that the display configuration supplied would work!"); + } + else + { + SharedLogger.logger.Error($"WinLibrary/SetActiveConfig: ERROR - SetDisplayConfig couldn't validate the display configuration supplied. This display configuration wouldn't work."); + return false; + } + + SharedLogger.logger.Trace($"WinLibrary/SetActiveConfig: Yay! The display configuration is valid! Attempting to set the Display Config now"); + // Now set the specified display configuration for this computer + err = CCDImport.SetDisplayConfig(myPathsCount, displayConfig.displayConfigPaths, myModesCount, displayConfig.displayConfigModes, SDC.DISPLAYMAGICIAN_SET); + if (err == WIN32STATUS.ERROR_SUCCESS) + { + SharedLogger.logger.Trace($"WinLibrary/SetActiveConfig: Successfully set the display configuration to the settings supplied!"); + } + else + { + SharedLogger.logger.Error($"WinLibrary/SetActiveConfig: ERROR - SetDisplayConfig couldn't set the display configuration using the settings supplied. Something is wrong."); + throw new WinLibraryException($"SetDisplayConfig couldn't set the display configuration using the settings supplied. Something is wrong."); + } + + SharedLogger.logger.Trace($"WinLibrary/SetActiveConfig: SUCCESS! The display configuration has been successfully applied"); + + foreach (ADVANCED_HDR_INFO_PER_PATH myHDRstate in displayConfig.displayHDRStates) + { + SharedLogger.logger.Trace($"Trying to get information whether HDR color is in use now on Display {myHDRstate.Id}."); + // Get advanced HDR info + var colorInfo = new DISPLAYCONFIG_GET_ADVANCED_COLOR_INFO(); + colorInfo.Header.Type = DISPLAYCONFIG_DEVICE_INFO_TYPE.DISPLAYCONFIG_DEVICE_INFO_GET_ADVANCED_COLOR_INFO; + colorInfo.Header.Size = (uint)Marshal.SizeOf(); + colorInfo.Header.AdapterId = myHDRstate.AdapterId; + colorInfo.Header.Id = myHDRstate.Id; + err = CCDImport.DisplayConfigGetDeviceInfo(ref colorInfo); + if (err == WIN32STATUS.ERROR_SUCCESS) + { + SharedLogger.logger.Trace($"WinLibrary/SetActiveConfig: Advanced Color Info gathered from Display {myHDRstate.Id}"); + + if (myHDRstate.AdvancedColorInfo.AdvancedColorSupported && colorInfo.AdvancedColorEnabled != myHDRstate.AdvancedColorInfo.AdvancedColorEnabled) + { + SharedLogger.logger.Trace($"HDR is available for use on Display {myHDRstate.Id}, and we want it set to {myHDRstate.AdvancedColorInfo.AdvancedColorEnabled} but is currently {colorInfo.AdvancedColorEnabled}."); + + var setColorState = new DISPLAYCONFIG_SET_ADVANCED_COLOR_STATE(); + setColorState.Header.Type = DISPLAYCONFIG_DEVICE_INFO_TYPE.DISPLAYCONFIG_DEVICE_INFO_SET_ADVANCED_COLOR_STATE; + setColorState.Header.Size = (uint)Marshal.SizeOf(); + setColorState.Header.AdapterId = myHDRstate.AdapterId; + setColorState.Header.Id = myHDRstate.Id; + setColorState.EnableAdvancedColor = myHDRstate.AdvancedColorInfo.AdvancedColorEnabled; + err = CCDImport.DisplayConfigSetDeviceInfo(ref setColorState); + if (err == WIN32STATUS.ERROR_SUCCESS) + { + SharedLogger.logger.Trace($"WinLibrary/SetActiveConfig: SUCCESS! Set HDR successfully to {myHDRstate.AdvancedColorInfo.AdvancedColorEnabled} on Display {myHDRstate.Id}"); + } + else + { + SharedLogger.logger.Error($"WinLibrary/SetActiveConfig: ERROR - DisplayConfigGetDeviceInfo returned WIN32STATUS {err} when trying to set the HDR settings for display #{myHDRstate.Id}"); + return false; + } + } + else + { + SharedLogger.logger.Trace($"WinLibrary/SetActiveConfig: Skipping setting HDR on Display {myHDRstate.Id} as it does not support HDR"); + } + } + else + { + SharedLogger.logger.Warn($"WinLibrary/GetWindowsDisplayConfig: WARNING - DisplayConfigGetDeviceInfo returned WIN32STATUS {err} when trying to find out if HDR is supported for display #{myHDRstate.Id}"); + } + + } + return true; + } + + public bool IsActiveConfig(WINDOWS_DISPLAY_CONFIG displayConfig) + { + // Get the current windows display configs to compare to the one we loaded + WINDOWS_DISPLAY_CONFIG currentWindowsDisplayConfig = GetWindowsDisplayConfig(QDC.QDC_ONLY_ACTIVE_PATHS); + + // Check whether the display config is in use now + SharedLogger.logger.Trace($"WinLibrary/IsActiveConfig: Checking whether the display configuration is already being used."); + if (displayConfig.Equals(currentWindowsDisplayConfig)) + { + SharedLogger.logger.Trace($"WinLibrary/IsActiveConfig: The display configuration is already being used (supplied displayConfig Equals currentWindowsDisplayConfig"); + return true; + } + else + { + SharedLogger.logger.Trace($"WinLibrary/IsActiveConfig: The display configuration is NOT currently in use (supplied displayConfig Equals currentWindowsDisplayConfig"); + return false; + } + + } + + public bool IsPossibleConfig(WINDOWS_DISPLAY_CONFIG displayConfig) + { + // Get the all possible windows display configs + WINDOWS_DISPLAY_CONFIG allWindowsDisplayConfig = GetWindowsDisplayConfig(QDC.QDC_ALL_PATHS); + + SharedLogger.logger.Trace("WinLibrary/PatchAdapterIDs: Going through the list of adapters we stored in the config to make sure they still exist"); + // Firstly check that the Adapter Names are still currently available (i.e. the adapter hasn't been replaced). + foreach (string savedAdapterName in displayConfig.displayAdapters.Values) + { + // If there is even one of the saved adapters that has changed, then it's no longer possible + // to use this display config! + if (!allWindowsDisplayConfig.displayAdapters.Values.Contains(savedAdapterName)) + { + SharedLogger.logger.Error($"WinLibrary/PatchAdapterIDs: ERROR - Saved adapter {savedAdapterName} is not available right now! This display configuration won't work!"); + return false; + } + } + SharedLogger.logger.Trace($"WinLibrary/PatchAdapterIDs: All teh adapters that the display configuration uses are still avilable to use now!"); + + // Now we go through the Paths to update the LUIDs as per Soroush's suggestion + SharedLogger.logger.Trace($"WinLibrary/IsPossibleConfig: Attemptong to patch the saved display configuration's adapter IDs so that it will still work (these change at each boot)"); + PatchAdapterIDs(ref displayConfig, allWindowsDisplayConfig.displayAdapters); + + SharedLogger.logger.Trace($"WinLibrary/IsPossibleConfig: Testing whether the display configuration is valid "); + // Test whether a specified display configuration is supported on the computer + uint myPathsCount = (uint)displayConfig.displayConfigPaths.Length; + uint myModesCount = (uint)displayConfig.displayConfigModes.Length; + WIN32STATUS err = CCDImport.SetDisplayConfig(myPathsCount, displayConfig.displayConfigPaths, myModesCount, displayConfig.displayConfigModes, SDC.DISPLAYMAGICIAN_VALIDATE); + if (err == WIN32STATUS.ERROR_SUCCESS) + { + SharedLogger.logger.Trace($"WinLibrary/IsPossibleConfig: SetDisplayConfig validated that the display configuration is valid and can be used!"); + return true; + } + else + { + SharedLogger.logger.Trace($"WinLibrary/IsPossibleConfig: SetDisplayConfig confirmed that the display configuration is invalid and cannot be used!"); + return false; + } + + } + + public List GetCurrentDisplayIdentifiers() + { + SharedLogger.logger.Error($"WinLibrary/GetCurrentDisplayIdentifiers: Getting the current display identifiers for the displays in use now"); + return GetSomeDisplayIdentifiers(QDC.QDC_ONLY_ACTIVE_PATHS); + } + + public List GetAllConnectedDisplayIdentifiers() + { + SharedLogger.logger.Error($"WinLibrary/GetAllConnectedDisplayIdentifiers: Getting all the display identifiers that can possibly be used"); + return GetSomeDisplayIdentifiers(QDC.QDC_ALL_PATHS); + } + + private List GetSomeDisplayIdentifiers(QDC selector = QDC.QDC_ONLY_ACTIVE_PATHS) + { + SharedLogger.logger.Debug($"WinLibrary/GetCurrentDisplayIdentifiers: Generating the unique Display Identifiers for the currently active configuration"); + + List displayIdentifiers = new List(); + + SharedLogger.logger.Trace($"WinLibrary/GetCurrentDisplayIdentifiers: Testing whether the display configuration is valid (allowing tweaks)."); + // Get the size of the largest Active Paths and Modes arrays + int pathCount = 0; + int modeCount = 0; + WIN32STATUS err = CCDImport.GetDisplayConfigBufferSizes(QDC.QDC_ONLY_ACTIVE_PATHS, out pathCount, out modeCount); + if (err != WIN32STATUS.ERROR_SUCCESS) + { + SharedLogger.logger.Error($"WinLibrary/PrintActiveConfig: ERROR - GetDisplayConfigBufferSizes returned WIN32STATUS {err} when trying to get the maximum path and mode sizes"); + throw new WinLibraryException($"GetDisplayConfigBufferSizes returned WIN32STATUS {err} when trying to get the maximum path and mode sizes"); + } + + SharedLogger.logger.Trace($"WinLibrary/GetSomeDisplayIdentifiers: Getting the current Display Config path and mode arrays"); + var paths = new DISPLAYCONFIG_PATH_INFO[pathCount]; + var modes = new DISPLAYCONFIG_MODE_INFO[modeCount]; + err = CCDImport.QueryDisplayConfig(QDC.QDC_ONLY_ACTIVE_PATHS, ref pathCount, paths, ref modeCount, modes, IntPtr.Zero); + if (err == WIN32STATUS.ERROR_INSUFFICIENT_BUFFER) + { + SharedLogger.logger.Warn($"WinLibrary/GetSomeDisplayIdentifiers: The displays were modified between GetDisplayConfigBufferSizes and QueryDisplayConfig so we need to get the buffer sizes again."); + SharedLogger.logger.Trace($"WinLibrary/GetSomeDisplayIdentifiers: Getting the size of the largest Active Paths and Modes arrays"); + // Screen changed in between GetDisplayConfigBufferSizes and QueryDisplayConfig, so we need to get buffer sizes again + // as per https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-querydisplayconfig + err = CCDImport.GetDisplayConfigBufferSizes(QDC.QDC_ONLY_ACTIVE_PATHS, out pathCount, out modeCount); + if (err != WIN32STATUS.ERROR_SUCCESS) + { + SharedLogger.logger.Error($"WinLibrary/GetSomeDisplayIdentifiers: ERROR - GetDisplayConfigBufferSizes returned WIN32STATUS {err} when trying to get the maximum path and mode sizes again"); + throw new WinLibraryException($"GetDisplayConfigBufferSizes returned WIN32STATUS {err} when trying to get the maximum path and mode sizes again"); + } + SharedLogger.logger.Trace($"WinLibrary/GetSomeDisplayIdentifiers: Getting the current Display Config path and mode arrays"); + paths = new DISPLAYCONFIG_PATH_INFO[pathCount]; + modes = new DISPLAYCONFIG_MODE_INFO[modeCount]; + err = CCDImport.QueryDisplayConfig(QDC.QDC_ONLY_ACTIVE_PATHS, ref pathCount, paths, ref modeCount, modes, IntPtr.Zero); + if (err == WIN32STATUS.ERROR_INSUFFICIENT_BUFFER) + { + SharedLogger.logger.Error($"WinLibrary/GetSomeDisplayIdentifiers: ERROR - The displays were still modified between GetDisplayConfigBufferSizes and QueryDisplayConfig, even though we tried twice. Something is wrong."); + throw new WinLibraryException($"The displays were still modified between GetDisplayConfigBufferSizes and QueryDisplayConfig, even though we tried twice. Something is wrong."); + } + else if (err != WIN32STATUS.ERROR_SUCCESS) + { + SharedLogger.logger.Error($"WinLibrary/GetSomeDisplayIdentifiers: ERROR - QueryDisplayConfig returned WIN32STATUS {err} when trying to query all available displays again"); + throw new WinLibraryException($"QueryDisplayConfig returned WIN32STATUS {err} when trying to query all available displays again."); + } + } + else if (err != WIN32STATUS.ERROR_SUCCESS) + { + SharedLogger.logger.Error($"WinLibrary/GetSomeDisplayIdentifiers: ERROR - QueryDisplayConfig returned WIN32STATUS {err} when trying to query all available displays"); + throw new WinLibraryException($"QueryDisplayConfig returned WIN32STATUS {err} when trying to query all available displays."); + } + + foreach (var path in paths) + { + if (path.TargetInfo.TargetAvailable == false) + { + // We want to skip this one cause it's not valid + SharedLogger.logger.Trace($"WinLibrary/GetSomeDisplayIdentifiers: Skipping path due to TargetAvailable not existing in display #{path.TargetInfo.Id}"); + continue; + } + + // get display source name + var sourceInfo = new DISPLAYCONFIG_SOURCE_DEVICE_NAME(); + sourceInfo.Header.Type = DISPLAYCONFIG_DEVICE_INFO_TYPE.DISPLAYCONFIG_DEVICE_INFO_GET_SOURCE_NAME; + sourceInfo.Header.Size = (uint)Marshal.SizeOf(); + sourceInfo.Header.AdapterId = path.SourceInfo.AdapterId; + sourceInfo.Header.Id = path.SourceInfo.Id; + err = CCDImport.DisplayConfigGetDeviceInfo(ref sourceInfo); + if (err == WIN32STATUS.ERROR_SUCCESS) + { + SharedLogger.logger.Trace($"WinLibrary/GetSomeDisplayIdentifiers: Successfully got the source info from {path.SourceInfo.Id}."); + } + else + { + SharedLogger.logger.Warn($"WinLibrary/GetSomeDisplayIdentifiers: WARNING - DisplayConfigGetDeviceInfo returned WIN32STATUS {err} when trying to get the target info for display #{path.SourceInfo.Id}"); + } + + // get display target name + var targetInfo = new DISPLAYCONFIG_TARGET_DEVICE_NAME(); + targetInfo.Header.Type = DISPLAYCONFIG_DEVICE_INFO_TYPE.DISPLAYCONFIG_DEVICE_INFO_GET_TARGET_NAME; + targetInfo.Header.Size = (uint)Marshal.SizeOf(); + targetInfo.Header.AdapterId = path.TargetInfo.AdapterId; + targetInfo.Header.Id = path.TargetInfo.Id; + err = CCDImport.DisplayConfigGetDeviceInfo(ref targetInfo); + if (err == WIN32STATUS.ERROR_SUCCESS) + { + SharedLogger.logger.Trace($"WinLibrary/GetSomeDisplayIdentifiers: Successfully got the target info from {path.TargetInfo.Id}."); + } + else + { + SharedLogger.logger.Warn($"WinLibrary/GetSomeDisplayIdentifiers: WARNING - DisplayConfigGetDeviceInfo returned WIN32STATUS {err} when trying to get the target info for display #{path.TargetInfo.Id}"); + } + + // get display adapter name + var adapterInfo = new DISPLAYCONFIG_ADAPTER_NAME(); + adapterInfo.Header.Type = DISPLAYCONFIG_DEVICE_INFO_TYPE.DISPLAYCONFIG_DEVICE_INFO_GET_ADAPTER_NAME; + adapterInfo.Header.Size = (uint)Marshal.SizeOf(); + adapterInfo.Header.AdapterId = path.TargetInfo.AdapterId; + adapterInfo.Header.Id = path.TargetInfo.Id; + err = CCDImport.DisplayConfigGetDeviceInfo(ref adapterInfo); + if (err == WIN32STATUS.ERROR_SUCCESS) + { + SharedLogger.logger.Trace($"WinLibrary/GetSomeDisplayIdentifiers: Successfully got the display name info from {path.TargetInfo.Id}."); + } + else + { + SharedLogger.logger.Warn($"WinLibrary/GetSomeDisplayIdentifiers: WARNING - DisplayConfigGetDeviceInfo returned WIN32STATUS {err} when trying to get the target info for display #{path.TargetInfo.Id}"); + } + + // Create an array of all the important display info we need to record + List displayInfo = new List(); + displayInfo.Add("WINAPI"); + try + { + displayInfo.Add(adapterInfo.AdapterDevicePath.ToString()); + } + catch (Exception ex) + { + SharedLogger.logger.Warn(ex, $"WinLibrary/GetSomeDisplayIdentifiers: Exception getting Windows Display Adapter Device Path from video card. Substituting with a # instead"); + displayInfo.Add("#"); + } + try + { + displayInfo.Add(targetInfo.OutputTechnology.ToString()); + } + catch (Exception ex) + { + SharedLogger.logger.Warn(ex, $"WinLibrary/GetSomeDisplayIdentifiers: Exception getting Windows Display Connector Instance from video card. Substituting with a # instead"); + displayInfo.Add("#"); + } + try + { + displayInfo.Add(targetInfo.EdidManufactureId.ToString()); + } + catch (Exception ex) + { + SharedLogger.logger.Warn(ex, $"WinLibrary/GetSomeDisplayIdentifiers: Exception getting Windows Display EDID Manufacturer Code from video card. Substituting with a # instead"); + displayInfo.Add("#"); + } + try + { + displayInfo.Add(targetInfo.EdidProductCodeId.ToString()); + } + catch (Exception ex) + { + SharedLogger.logger.Warn(ex, $"WinLibrary/GetSomeDisplayIdentifiers: Exception getting Windows Display EDID Product Code from video card. Substituting with a # instead"); + displayInfo.Add("#"); + } + try + { + displayInfo.Add(targetInfo.MonitorFriendlyDeviceName.ToString()); + } + catch (Exception ex) + { + SharedLogger.logger.Warn(ex, $"WinLibrary/GetSomeDisplayIdentifiers: Exception getting Windows Display Target Friendly name from video card. Substituting with a # instead"); + displayInfo.Add("#"); + } + + // Create a display identifier out of it + string displayIdentifier = String.Join("|", displayInfo); + // Add it to the list of display identifiers so we can return it + // but only add it if it doesn't already exist. Otherwise we get duplicates :/ + if (!displayIdentifiers.Contains(displayIdentifier)) + { + displayIdentifiers.Add(displayIdentifier); + SharedLogger.logger.Debug($"ProfileRepository/GenerateProfileDisplayIdentifiers: DisplayIdentifier: {displayIdentifier}"); + } + + } + + // Sort the display identifiers + displayIdentifiers.Sort(); + + return displayIdentifiers; + } + + } + + [global::System.Serializable] + public class WinLibraryException : Exception + { + public WinLibraryException() { } + public WinLibraryException(string message) : base(message) { } + public WinLibraryException(string message, Exception inner) : base(message, inner) { } + protected WinLibraryException( + System.Runtime.Serialization.SerializationInfo info, + System.Runtime.Serialization.StreamingContext context) : base(info, context) { } + } +} \ No newline at end of file diff --git a/DisplayMagicianShared/Windows/WinProfileItem.cs b/DisplayMagicianShared/Windows/WinProfileItem.cs new file mode 100644 index 0000000..c200068 --- /dev/null +++ b/DisplayMagicianShared/Windows/WinProfileItem.cs @@ -0,0 +1,632 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Windows.Forms; +using DisplayMagicianShared.Resources; +using Newtonsoft.Json; +using System.Drawing; +using System.Drawing.Imaging; +using System.Text.RegularExpressions; +using IWshRuntimeLibrary; +//using ATI.ADL; +//using WK.Libraries.HotkeyListenerNS; + +namespace DisplayMagicianShared.Windows +{ + + /*// Struct to be used as the AMD Profile + [JsonObject(MemberSerialization.Fields)] + public struct AMDProfile + { + public List Adapters; + } + + // Struct to store the Display + [JsonObject(MemberSerialization.Fields)] + public struct AMDAdapter + { + public int AdapterIndex; + public string AdapterName; + public string DisplayName; + [JsonProperty] + public ADLAdapterInfoX2 AdapterInfoX2; + public List Displays; + } + + // Struct to store the Display + [JsonObject(MemberSerialization.Fields)] + public struct AMDDisplay + { + public string DisplayName; + public string DisplayConnector; + public string UDID; + [JsonRequired] + public List DisplayModes; + public bool HDRSupported; + public bool HDREnabled; + public bool IsEyefinity; + + }*/ + + public class WinProfileItem : ProfileItem, IComparable + { + private static List _allSavedProfiles = new List(); + private ProfileIcon _profileIcon; + private Bitmap _profileBitmap, _profileShortcutBitmap; + private List _profileDisplayIdentifiers = new List(); + private List _screens; + private WINDOWS_DISPLAY_CONFIG _displayConfig = new WINDOWS_DISPLAY_CONFIG(); + private static readonly string uuidV4Regex = @"(?im)^[{(]?[0-9A-F]{8}[-]?(?:[0-9A-F]{4}[-]?){3}[0-9A-F]{12}[)}]?$"; + + private string _uuid = ""; + private bool _isPossible = false; + private Keys _hotkey = Keys.None; + + + public WinProfileItem() + { + } + + public new static Version Version = new Version(2, 1); + + #region Instance Properties + + [JsonIgnore] + public override bool IsPossible + { + get + { + // Return the cached answer + return _isPossible; + } + set + { + _isPossible = value; + } + } + + [JsonIgnore] + public override bool IsActive + { + get + { + + if (this.Equals(ProfileRepository.CurrentProfile)) + return true; + else + return false; + + } + } + + public override string Driver { get; } = "AMD"; + + public override string Name { get; set; } + + //public Topology.Path[] Paths { get; set; } = new Topology.Path[0]; + + [JsonRequired] + public WINDOWS_DISPLAY_CONFIG DisplayConfig + { + get + { + return _displayConfig; + } + set + { + _displayConfig = value; + } + } + + + public override List ProfileDisplayIdentifiers + { + get + { + if (_profileDisplayIdentifiers.Count == 0) + { + _profileDisplayIdentifiers = WinLibrary.GetLibrary().GetCurrentDisplayIdentifiers(); + } + return _profileDisplayIdentifiers; + } + set + { + if (value is List) + _profileDisplayIdentifiers = value; + } + } + + [JsonIgnore] + public override List Screens + { + get + { + if (_screens.Count == 0) + { + _screens = GetScreenPositions(); + } + return _screens; + } + set + { + _screens = value; + } + } + + + + //[JsonConverter(typeof(CustomBitmapConverter))] + [JsonIgnore] + public override Bitmap ProfileBitmap + { + get + { + /*if (!ProfileRepository.ProfilesLoaded) + return null;*/ + + if (_profileBitmap != null) + return _profileBitmap; + else + { + _profileBitmap = this.ProfileIcon.ToBitmap(256, 256); + return _profileBitmap; + } + } + set + { + _profileBitmap = value; + } + + } + + + //[JsonConverter(typeof(CustomBitmapConverter))] + [JsonIgnore] + public override Bitmap ProfileTightestBitmap + { + get + { + if (_profileShortcutBitmap != null) + return _profileShortcutBitmap; + else + { + _profileShortcutBitmap = this.ProfileIcon.ToTightestBitmap(); + return _profileShortcutBitmap; + } + } + set + { + _profileShortcutBitmap = value; + } + + } + + #endregion + + public override bool IsValid() + { + + if (ProfileIcon is ProfileIcon && + System.IO.File.Exists(SavedProfileIconCacheFilename) && + ProfileBitmap is Bitmap && + ProfileTightestBitmap is Bitmap && + ProfileDisplayIdentifiers.Count > 0) + { + if (DisplayConfig.displayConfigModes.Length > 0 && DisplayConfig.displayConfigPaths.Length > 0) + return true; + else + return false; + } + else + return false; + } + + + + public bool CopyTo(WinProfileItem profile, bool overwriteId = true) + { + if (!(profile is WinProfileItem)) + return false; + + if (overwriteId == true) + profile.UUID = UUID; + + // Copy all our profile data over to the other profile + profile.Name = Name; + profile.DisplayConfig = DisplayConfig; + profile.ProfileIcon = ProfileIcon; + profile.SavedProfileIconCacheFilename = SavedProfileIconCacheFilename; + profile.ProfileBitmap = ProfileBitmap; + profile.ProfileTightestBitmap = ProfileTightestBitmap; + profile.ProfileDisplayIdentifiers = ProfileDisplayIdentifiers; + //profile.Screens = Screens; + return true; + } + + public override bool PreSave() + { + // Prepare our profile data for saving + if (_profileDisplayIdentifiers.Count == 0) + { + _profileDisplayIdentifiers = WinLibrary.GetLibrary().GetCurrentDisplayIdentifiers(); + } + + // Return if it is valid and we should continue + return IsValid(); + } + + public override void RefreshPossbility() + { + // Check each display in this profile and make sure it's currently available + int validDisplayCount = 0; + + //validDisplayCount = (from connectedDisplay in ProfileRepository.ConnectedDisplayIdentifiers select connectedDisplay == profileDisplayIdentifier).Count(); + + foreach (string profileDisplayIdentifier in ProfileDisplayIdentifiers) + { + // If this profile has a display that isn't currently available then we need to say it's a no! + if (ProfileRepository.ConnectedDisplayIdentifiers.Any(s => profileDisplayIdentifier.Equals(s))) + { + SharedLogger.logger.Trace($"ProfileItem/RefreshPossbility: We found the display in the profile {Name} with profileDisplayIdentifier {profileDisplayIdentifier} is connected now."); + validDisplayCount++; + } + else + { + SharedLogger.logger.Warn($"ProfileItem/RefreshPossbility: We found the display in the profile {Name} with profileDisplayIdentifier {profileDisplayIdentifier} is NOT currently connected, so this profile cannot be used."); + } + + } + if (validDisplayCount == ProfileDisplayIdentifiers.Count) + { + + SharedLogger.logger.Debug($"ProfileRepository/IsPossibleRefresh: The profile {Name} is possible!"); + _isPossible = true; + + } + else + { + SharedLogger.logger.Debug($"ProfileRepository/IsPossibleRefresh: The profile {Name} is NOT possible!"); + _isPossible = false; + } + + } + + public override bool CreateProfileFromCurrentDisplaySettings() + { + + WinLibrary winLibrary = WinLibrary.GetLibrary(); + if (winLibrary.IsInstalled) + { + // Create the profile data from the current config + _displayConfig = winLibrary.GetActiveConfig(); + + // Now, since the ActiveProfile has changed, we need to regenerate screen positions + _screens = GetScreenPositions(); + + return true; + } + else + { + return false; + } + } + + public override bool PerformPostLoadingTasks() + { + // First thing we do is to set up the Screens + _screens = GetScreenPositions(); + + return true; + } + + public override List GetScreenPositions() + { + + // Now we create the screens structure from the AMD profile information + _screens = new List(); + + if ( _displayConfig.displayConfigModes.Length > 0 && _displayConfig.displayConfigPaths.Length > 0) + { + foreach ( var adapter in _displayConfig.AdapterConfigs) + { + foreach (var display in adapter.Displays) + { + foreach (var mode in display.DisplayModes) + { + ScreenPosition screen = new ScreenPosition(); + screen.Library = "AMD"; + screen.Name = display.DisplayName; + screen.DisplayConnector = display.DisplayConnector; + screen.ScreenX = mode.XPos; + screen.ScreenY = mode.YPos; + screen.ScreenWidth = mode.XRes; + screen.ScreenHeight = mode.YRes; + + // If we're at the 0,0 coordinate then we're the primary monitor + if (screen.ScreenX == 0 && screen.ScreenY == 0) + { + screen.IsPrimary = true; + } + + // HDR information + if (display.HDRSupported) + { + screen.HDRSupported = true; + if (display.HDREnabled) + { + screen.HDREnabled = true; + } + else + { + screen.HDREnabled = false; + } + + } + else + { + screen.HDRSupported = false; + screen.HDREnabled = false; + } + + // Spanned screen options + if (display.IsEyefinity) + { + screen.IsSpanned = true; + screen.Colour = Color.FromArgb(200, 237, 28, 36); // represents AMD Red + screen.SpannedName = "AMD Eyefinity"; + } + else + { + screen.IsSpanned = false; + screen.Colour = Color.FromArgb(255, 195, 195, 195); // represents normal screen colour + } + + + // Figure out features + + //ATI.ADL.ADL.ConvertDisplayModeFlags(mode.ModeValue); + + //screen.Features = mode.ModeValue; + + _screens.Add(screen); + } + } + } + } + + + return _screens; + } + + + // The public override for the Object.Equals + public override bool Equals(object obj) + { + return this.Equals(obj as WinProfileItem); + } + + // Profiles are equal if their Viewports are equal + public bool Equals(WinProfileItem other) + { + + // If parameter is null, return false. + if (other is null) + return false; + + // Optimization for a common success case. + if (Object.ReferenceEquals(this, other)) + return true; + + // If run-time types are not exactly the same, return false. + if (this.GetType() != other.GetType()) + return false; + + // If the DisplayConfig's equal each other + if (DisplayConfig.Equals(other.DisplayConfig)) + return false; + + // Check if the profile identifiers are not the same, then return false + int foundDICount = 0; + foreach (string profileDI in ProfileDisplayIdentifiers) + { + + if (other.ProfileDisplayIdentifiers.Contains(profileDI)) + { + foundDICount++; + continue; + } + + } + + if (foundDICount != other.ProfileDisplayIdentifiers.Count) + return false; + + foundDICount = 0; + foreach (string profileDI in other.ProfileDisplayIdentifiers) + { + + if (ProfileDisplayIdentifiers.Contains(profileDI)) + { + foundDICount++; + continue; + } + + } + + if (foundDICount != ProfileDisplayIdentifiers.Count) + return false; + + // Check whether the profiles' properties are equal + // We need to exclude the name as the name is solely for saving to disk + // and displaying to the user. + // Two profiles are equal only when they have the same viewport data + // The data may be in different orders each run, so we need to compare them one by one + + int foundPathsCount = 0; + int foundOtherPathsCount = 0; + + // TODO: Make this work in AMD land + /*foreach (Topology.Path profilePath in Paths) + { + if (other.Paths.Contains(profilePath)) + { + foundPathsCount++; + continue; + } + + } + foreach (Topology.Path otherPath in other.Paths) + { + if (Paths.Contains(otherPath)) + { + foundOtherPathsCount++; + continue; + } + }*/ + + + if (foundPathsCount == foundOtherPathsCount) + return true; + else + return false; + } + + // If Equals() returns true for this object compared to another + // then GetHashCode() must return the same value for these objects. + /*public override int GetHashCode() + { + + // Get hash code for the Viewports field if it is not null. + int hashPaths = Paths == null ? 0 : Paths.GetHashCode(); + + //Calculate the hash code for the product. + return hashPaths; + + }*/ + public override int GetHashCode() + { + + // Get hash code for the ProfileDisplayIdentifiers field if it is not null. + int hashIds = ProfileDisplayIdentifiers == null ? 0 : ProfileDisplayIdentifiers.GetHashCode(); + + // Get ProfileData too + int hashProfileData = DisplayConfig.GetHashCode(); + + // Calculate the hash code for the product. + return (hashIds, hashProfileData).GetHashCode(); + + } + + + public override string ToString() + { + return (Name ?? Language.UN_TITLED_PROFILE); + } + + } + + // Custom Equality comparer for the Profile class + // Allows us to use 'Contains' + class AMDProfileComparer : IEqualityComparer + { + // Products are equal if their names and product numbers are equal. + /*public bool Equals(AMDProfileItem x, AMDProfileItem y) + { + + //Check whether the compared objects reference the same data. + if (Object.ReferenceEquals(x, y)) return true; + + //Check whether any of the compared objects is null. + if (x is null || y is null) + return false; + + // Check whether the profiles' properties are equal + // We need to exclude the name as the name is solely for saving to disk + // and displaying to the user. + // Two profiles are equal only when they have the same viewport data + if (x.Paths.SequenceEqual(y.Paths)) + return true; + else + return false; + }*/ + + public bool Equals(WinProfileItem x, WinProfileItem y) + { + + //Check whether the compared objects reference the same data. + if (Object.ReferenceEquals(x, y)) return true; + + //Check whether any of the compared objects is null. + if (x is null || y is null) + return false; + + // Check if the profile identifiers are not the same, then return false + int foundDICount = 0; + foreach (string profileDI in x.ProfileDisplayIdentifiers) + { + if (y.ProfileDisplayIdentifiers.Contains(profileDI)) + { + foundDICount++; + continue; + } + + } + if (foundDICount != x.ProfileDisplayIdentifiers.Count) + return false; + + foundDICount = 0; + foreach (string profileDI in y.ProfileDisplayIdentifiers) + { + if (x.ProfileDisplayIdentifiers.Contains(profileDI)) + { + foundDICount++; + continue; + } + + } + if (foundDICount != y.ProfileDisplayIdentifiers.Count) + return false; + + + // Now we need to check the Display Configs themselves + if (x.DisplayConfig.Equals(y.DisplayConfig)) + return false; + + return true; + } + + // If Equals() returns true for a pair of objects + // then GetHashCode() must return the same value for these objects. + /*public int GetHashCode(AMDProfileItem profile) + { + + // Check whether the object is null + if (profile is null) return 0; + + // Get hash code for the Viewports field if it is not null. + int hashPaths = profile.Paths == null ? 0 : profile.Paths.GetHashCode(); + + //Calculate the hash code for the product. + return hashPaths; + + }*/ + // Modified the GetHashCode to compare the displayidentifier + public int GetHashCode(WinProfileItem profile) + { + + // Check whether the object is null + if (profile is null) return 0; + + // Get hash code for the ProfileDisplayIdentifiers field if it is not null. + int hashIds = profile.ProfileDisplayIdentifiers == null ? 0 : profile.ProfileDisplayIdentifiers.GetHashCode(); + + // Get hash code for the Paths + int hashProfileData = profile.DisplayConfig.GetHashCode(); + + //Calculate the hash code for the product. + return (hashIds, hashProfileData).GetHashCode(); + + } + } +} \ No newline at end of file diff --git a/DisplayMagicianShared/Windows/WindowsLibrary.cs b/DisplayMagicianShared/Windows/WindowsLibrary.cs deleted file mode 100644 index 954cc9e..0000000 --- a/DisplayMagicianShared/Windows/WindowsLibrary.cs +++ /dev/null @@ -1,54 +0,0 @@ -using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.Linq; -using System.Runtime.InteropServices; -using System.Text; -using System.Threading.Tasks; - - -namespace DisplayMagicianShared.Windows -{ - class WindowsCCDLibrary - { - static void Main() - { - WIN32STATUS err = CCDImport.GetDisplayConfigBufferSizes(QDC.QDC_ONLY_ACTIVE_PATHS, out var pathCount, out var modeCount); - if (err != WIN32STATUS.ERROR_SUCCESS) - throw new Win32Exception((int)err); - - var paths = new DISPLAYCONFIG_PATH_INFO[pathCount]; - var modes = new DISPLAYCONFIG_MODE_INFO[modeCount]; - err = CCDImport.QueryDisplayConfig(QDC.QDC_ONLY_ACTIVE_PATHS, ref pathCount, paths, ref modeCount, modes, IntPtr.Zero); - if (err != WIN32STATUS.ERROR_SUCCESS) - throw new Win32Exception((int)err); - - foreach (var path in paths) - { - // get display name - var info = new DISPLAYCONFIG_GET_TARGET_NAME(); - info.Header.Type = DISPLAYCONFIG_DEVICE_INFO_TYPE.DISPLAYCONFIG_DEVICE_INFO_GET_TARGET_NAME; - info.Header.Size = Marshal.SizeOf(); - info.Header.AdapterId = path.TargetInfo.AdapterId; - info.Header.Id = path.TargetInfo.Id; - err = CCDImport.DisplayConfigGetDeviceInfo(ref info); - if (err != WIN32STATUS.ERROR_SUCCESS) - throw new Win32Exception((int)err); - - var colorInfo = new DISPLAYCONFIG_GET_ADVANCED_COLOR_INFO(); - colorInfo.Header.Type = DISPLAYCONFIG_DEVICE_INFO_TYPE.DISPLAYCONFIG_DEVICE_INFO_GET_ADVANCED_COLOR_INFO; - colorInfo.Header.Size = Marshal.SizeOf(); - colorInfo.Header.AdapterId = path.TargetInfo.AdapterId; - colorInfo.Header.Id = path.TargetInfo.Id; - err = CCDImport.DisplayConfigGetDeviceInfo(ref colorInfo); - if (err != WIN32STATUS.ERROR_SUCCESS) - throw new Win32Exception((int)err); - - Console.WriteLine(info.MonitorFriendlyDeviceName); - Console.WriteLine(" Advanced Color Supported: " + colorInfo.AdvancedColorSupported); - Console.WriteLine(" Advanced Color Enabled : " + colorInfo.AdvancedColorEnabled); - Console.WriteLine(); - } - } - } -}