using System; using System.Collections.Generic; using System.Linq; using NvAPIWrapper.Native.Display; using NvAPIWrapper.Native.Display.Structures; using NvAPIWrapper.Native.Exceptions; using NvAPIWrapper.Native.General; using NvAPIWrapper.Native.General.Structures; using NvAPIWrapper.Native.GPU; using NvAPIWrapper.Native.Helpers; using NvAPIWrapper.Native.Helpers.Structures; using NvAPIWrapper.Native.Interfaces.Display; using NvAPIWrapper.Native.Interfaces.GPU; using Rectangle = NvAPIWrapper.Native.General.Structures.Rectangle; namespace NvAPIWrapper.Native { /// /// Contains display and display control static functions /// public static class DisplayApi { /// /// This API controls the display color configurations. /// /// The targeted display id. /// The structure to be filled with information requested or applied on the display. public static void ColorControl(uint displayId, ref TColorData colorData) where TColorData : struct, IColorData { var c = colorData as IColorData; ColorControl(displayId, ref c); colorData = (TColorData) c; } /// /// This API controls the display color configurations. /// /// The targeted display id. /// The structure to be filled with information requested or applied on the display. public static void ColorControl(uint displayId, ref IColorData colorData) { var colorControl = DelegateFactory.GetDelegate(); var type = colorData.GetType(); if (!colorControl.Accepts().Contains(type)) { throw new ArgumentOutOfRangeException(nameof(type)); } using (var colorDataReference = ValueTypeReference.FromValueType(colorData, type)) { var status = colorControl(displayId, colorDataReference); if (status != Status.Ok) { throw new NVIDIAApiException(status); } colorData = colorDataReference.ToValueType(type); } } /// /// This API controls the display color configurations. /// /// The targeted display id. /// The list of structures to be filled with information requested or applied on the display. /// The structure that succeed in requesting information or used for applying configuration on the display. // ReSharper disable once IdentifierTypo public static IColorData ColorControl(uint displayId, IColorData[] colorDatas) { foreach (var colorData in colorDatas) { try { var c = colorData; ColorControl(displayId, ref c); return c; } catch (NVIDIAApiException e) { if (e.Status == Status.IncompatibleStructureVersion) { continue; } throw; } } throw new NVIDIANotSupportedException("This operation is not supported."); } /// /// This function converts the unattached display handle to an active attached display handle. /// At least one GPU must be present in the system and running an NVIDIA display driver. /// /// An unattached display handle to convert. /// Display handle of newly created display. /// Status.InvalidArgument: Invalid UnAttachedDisplayHandle handle. /// Status.NvidiaDeviceNotFound: No NVIDIA GPU driving a display was found /// A delegate callback throws an exception. public static DisplayHandle CreateDisplayFromUnAttachedDisplay(UnAttachedDisplayHandle display) { var createDisplayFromUnAttachedDisplay = DelegateFactory.GetDelegate(); var status = createDisplayFromUnAttachedDisplay(display, out var newDisplay); if (status != Status.Ok) { throw new NVIDIAApiException(status); } return newDisplay; } /// /// This function deletes the custom display configuration, specified from the registry for all the displays whose /// display IDs are passed. /// /// Array of display IDs on which custom display configuration should be removed. /// The custom display to remove. public static void DeleteCustomDisplay(uint[] displayIds, CustomDisplay customDisplay) { if (displayIds.Length == 0) { return; } using (var displayIdsReference = ValueTypeArray.FromArray(displayIds)) { using (var customDisplayReference = ValueTypeReference.FromValueType(customDisplay)) { var status = DelegateFactory.GetDelegate()( displayIdsReference, (uint) displayIds.Length, customDisplayReference ); if (status != Status.Ok) { throw new NVIDIAApiException(status); } } } } /// /// This API enumerates the custom timing specified by the enum index. /// /// The display id of the display. /// A list of public static IEnumerable EnumCustomDisplays(uint displayId) { var instance = typeof(CustomDisplay).Instantiate(); using (var customDisplayReference = ValueTypeReference.FromValueType(instance)) { for (uint i = 0; i < uint.MaxValue; i++) { var status = DelegateFactory.GetDelegate()( displayId, i, customDisplayReference ); if (status == Status.EndEnumeration) { yield break; } if (status != Status.Ok) { throw new NVIDIAApiException(status); } yield return customDisplayReference.ToValueType().GetValueOrDefault(); } } } /// /// This function returns the handle of all NVIDIA displays /// Note: Display handles can get invalidated on a mode-set, so the calling applications need to re-enum the handles /// after every mode-set. /// /// Array of display handles. /// Status.NvidiaDeviceNotFound: No NVIDIA device found in the system /// A delegate callback throws an exception. public static DisplayHandle[] EnumNvidiaDisplayHandle() { var enumNvidiaDisplayHandle = DelegateFactory.GetDelegate(); var results = new List(); uint i = 0; while (true) { var status = enumNvidiaDisplayHandle(i, out var displayHandle); if (status == Status.EndEnumeration) { break; } if (status != Status.Ok) { throw new NVIDIAApiException(status); } results.Add(displayHandle); i++; } return results.ToArray(); } /// /// This function returns the handle of all unattached NVIDIA displays /// Note: Display handles can get invalidated on a mode-set, so the calling applications need to re-enum the handles /// after every mode-set. /// /// Array of unattached display handles. /// Status.NvidiaDeviceNotFound: No NVIDIA device found in the system /// A delegate callback throws an exception. public static UnAttachedDisplayHandle[] EnumNvidiaUnAttachedDisplayHandle() { var enumNvidiaUnAttachedDisplayHandle = DelegateFactory.GetDelegate(); var results = new List(); uint i = 0; while (true) { var status = enumNvidiaUnAttachedDisplayHandle(i, out var displayHandle); if (status == Status.EndEnumeration) { break; } if (status != Status.Ok) { throw new NVIDIAApiException(status); } results.Add(displayHandle); i++; } return results.ToArray(); } /// /// This function gets the active outputId associated with the display handle. /// /// /// NVIDIA Display selection. It can be DisplayHandle.DefaultHandle or a handle enumerated from /// DisplayApi.EnumNVidiaDisplayHandle(). /// /// /// The active display output ID associated with the selected display handle hNvDisplay. The output id will have /// only one bit set. In the case of Clone or Span mode, this will indicate the display outputId of the primary display /// that the GPU is driving. /// /// Status.NvidiaDeviceNotFound: No NVIDIA GPU driving a display was found. /// Status.ExpectedDisplayHandle: display is not a valid display handle. /// A delegate callback throws an exception. public static OutputId GetAssociatedDisplayOutputId(DisplayHandle display) { var getAssociatedDisplayOutputId = DelegateFactory.GetDelegate(); var status = getAssociatedDisplayOutputId(display, out var outputId); if (status != Status.Ok) { throw new NVIDIAApiException(status); } return outputId; } /// /// This function returns the handle of the NVIDIA display that is associated with the given display "name" (such as /// "\\.\DISPLAY1"). /// /// Display name /// Display handle of associated display /// Status.InvalidArgument: Display name is null. /// Status.NvidiaDeviceNotFound: No NVIDIA device maps to that display name. /// A delegate callback throws an exception. public static DisplayHandle GetAssociatedNvidiaDisplayHandle(string name) { var getAssociatedNvidiaDisplayHandle = DelegateFactory.GetDelegate(); var status = getAssociatedNvidiaDisplayHandle(name, out var display); if (status != Status.Ok) { throw new NVIDIAApiException(status); } return display; } /// /// For a given NVIDIA display handle, this function returns a string (such as "\\.\DISPLAY1") to identify the display. /// /// Handle of the associated display /// Name of the display /// Status.InvalidArgument: Display handle is null. /// Status.NvidiaDeviceNotFound: No NVIDIA device maps to that display name. /// A delegate callback throws an exception. public static string GetAssociatedNvidiaDisplayName(DisplayHandle display) { var getAssociatedNvidiaDisplayName = DelegateFactory.GetDelegate(); var status = getAssociatedNvidiaDisplayName(display, out var displayName); if (status != Status.Ok) { throw new NVIDIAApiException(status); } return displayName.Value; } /// /// This function returns the handle of an unattached NVIDIA display that is associated with the given display "name" /// (such as "\\DISPLAY1"). /// /// Display name /// Display handle of associated unattached display /// Status.InvalidArgument: Display name is null. /// Status.NvidiaDeviceNotFound: No NVIDIA device maps to that display name. /// A delegate callback throws an exception. public static UnAttachedDisplayHandle GetAssociatedUnAttachedNvidiaDisplayHandle(string name) { var getAssociatedUnAttachedNvidiaDisplayHandle = DelegateFactory.GetDelegate(); var status = getAssociatedUnAttachedNvidiaDisplayHandle(name, out var display); if (status != Status.Ok) { throw new NVIDIAApiException(status); } return display; } /// /// This API lets caller retrieve the current global display configuration. /// Note: User should dispose all returned PathInfo objects /// /// Array of path information /// This operation is not supported. /// Status.InvalidArgument: Invalid input parameter. /// Status.DeviceBusy: ModeSet has not yet completed. Please wait and call it again. /// A delegate callback throws an exception. public static IPathInfo[] GetDisplayConfig() { var getDisplayConfig = DelegateFactory.GetDelegate(); uint allAvailable = 0; var status = getDisplayConfig(ref allAvailable, ValueTypeArray.Null); if (status != Status.Ok) { throw new NVIDIAApiException(status); } if (allAvailable == 0) { return new IPathInfo[0]; } foreach (var acceptType in getDisplayConfig.Accepts()) { var count = allAvailable; var instances = acceptType.Instantiate().Repeat((int) allAvailable); using (var pathInfos = ValueTypeArray.FromArray(instances, acceptType)) { status = getDisplayConfig(ref count, pathInfos); if (status != Status.Ok) { throw new NVIDIAApiException(status); } instances = pathInfos.ToArray((int) count, acceptType); } if (instances.Length <= 0) { return new IPathInfo[0]; } // After allocation, we should make sure to dispose objects // In this case however, the responsibility is on the user shoulders instances = instances.AllocateAll().ToArray(); using (var pathInfos = ValueTypeArray.FromArray(instances, acceptType)) { status = getDisplayConfig(ref count, pathInfos); if (status != Status.Ok) { throw new NVIDIAApiException(status); } return pathInfos.ToArray((int) count, acceptType); } } throw new NVIDIANotSupportedException("This operation is not supported."); } /// /// Gets the build title of the Driver Settings Database for a display /// /// The display handle to get DRS build title. /// The DRS build title. public static string GetDisplayDriverBuildTitle(DisplayHandle displayHandle) { var status = DelegateFactory.GetDelegate()(displayHandle, out var name); if (status != Status.Ok) { throw new NVIDIAApiException(status); } return name.Value; } /// /// This function retrieves the available driver memory footprint for the GPU associated with a display. /// /// Handle of the display for which the memory information of its GPU is to be extracted. /// The memory footprint available in the driver. /// This operation is not supported. /// Status.NvidiaDeviceNotFound: No NVIDIA GPU driving a display was found. /// A delegate callback throws an exception. public static IDisplayDriverMemoryInfo GetDisplayDriverMemoryInfo(DisplayHandle displayHandle) { var getMemoryInfo = DelegateFactory.GetDelegate(); foreach (var acceptType in getMemoryInfo.Accepts()) { var instance = acceptType.Instantiate(); using (var displayDriverMemoryInfo = ValueTypeReference.FromValueType(instance, acceptType)) { var status = getMemoryInfo(displayHandle, displayDriverMemoryInfo); if (status == Status.IncompatibleStructureVersion) { continue; } if (status != Status.Ok) { throw new NVIDIAApiException(status); } return displayDriverMemoryInfo.ToValueType(acceptType); } } throw new NVIDIANotSupportedException("This operation is not supported."); } /// /// This API retrieves the Display Id of a given display by display name. The display must be active to retrieve the /// displayId. In the case of clone mode or Surround gaming, the primary or top-left display will be returned. /// /// Name of display (Eg: "\\DISPLAY1" to retrieve the displayId for. /// Display ID of the requested display. /// Status.InvalidArgument: One or more args passed in are invalid. /// Status.ApiNotInitialized: The NvAPI API needs to be initialized first /// Status.NoImplementation: This entry-point not available /// Status.Error: Miscellaneous error occurred /// A delegate callback throws an exception. public static uint GetDisplayIdByDisplayName(string displayName) { var getDisplayIdByDisplayName = DelegateFactory.GetDelegate(); var status = getDisplayIdByDisplayName(displayName, out var display); if (status != Status.Ok) { throw new NVIDIAApiException(status); } return display; } /// [PRIVATE] /// /// This API returns the current saturation level from the Digital Vibrance Control /// /// /// The targeted display's handle. /// /// An instance of the PrivateDisplayDVCInfo structure containing requested information. public static PrivateDisplayDVCInfo GetDVCInfo(DisplayHandle display) { var instance = typeof(PrivateDisplayDVCInfo).Instantiate(); using (var displayDVCInfoReference = ValueTypeReference.FromValueType(instance)) { var status = DelegateFactory.GetDelegate()( display, OutputId.Invalid, displayDVCInfoReference ); if (status != Status.Ok) { throw new NVIDIAApiException(status); } return displayDVCInfoReference.ToValueType().GetValueOrDefault(); } } /// [PRIVATE] /// /// This API returns the current saturation level from the Digital Vibrance Control /// /// /// The targeted display output id. /// /// An instance of the PrivateDisplayDVCInfo structure containing requested information. public static PrivateDisplayDVCInfo GetDVCInfo(OutputId displayId) { var instance = typeof(PrivateDisplayDVCInfo).Instantiate(); using (var displayDVCInfoReference = ValueTypeReference.FromValueType(instance)) { var status = DelegateFactory.GetDelegate()( DisplayHandle.DefaultHandle, displayId, displayDVCInfoReference ); if (status != Status.Ok) { throw new NVIDIAApiException(status); } return displayDVCInfoReference.ToValueType().GetValueOrDefault(); } } /// [PRIVATE] /// /// This API returns the current and the default saturation level from the Digital Vibrance Control. /// The difference between this API and the 'GetDVCInfo()' includes the possibility to get the default /// saturation level as well as to query under saturated configurations. /// /// /// The targeted display's handle. /// /// An instance of the PrivateDisplayDVCInfoEx structure containing requested information. public static PrivateDisplayDVCInfoEx GetDVCInfoEx(DisplayHandle display) { var instance = typeof(PrivateDisplayDVCInfoEx).Instantiate(); using (var displayDVCInfoReference = ValueTypeReference.FromValueType(instance)) { var status = DelegateFactory.GetDelegate()( display, OutputId.Invalid, displayDVCInfoReference ); if (status != Status.Ok) { throw new NVIDIAApiException(status); } return displayDVCInfoReference.ToValueType().GetValueOrDefault(); } } /// [PRIVATE] /// /// This API returns the current and the default saturation level from the Digital Vibrance Control. /// The difference between this API and the 'GetDVCInfo()' includes the possibility to get the default /// saturation level as well as to query under saturated configurations. /// /// /// The targeted display output id. /// /// An instance of the PrivateDisplayDVCInfoEx structure containing requested information. public static PrivateDisplayDVCInfoEx GetDVCInfoEx(OutputId displayId) { var instance = typeof(PrivateDisplayDVCInfoEx).Instantiate(); using (var displayDVCInfoReference = ValueTypeReference.FromValueType(instance)) { var status = DelegateFactory.GetDelegate()( DisplayHandle.DefaultHandle, displayId, displayDVCInfoReference ); if (status != Status.Ok) { throw new NVIDIAApiException(status); } return displayDVCInfoReference.ToValueType().GetValueOrDefault(); } } /// /// This API returns the current info-frame data on the specified device (monitor). /// /// The display handle of the device to retrieve HDMI support information for. /// The target display's output id, or to determine automatically. /// An instance of a type implementing the interface. public static IHDMISupportInfo GetHDMISupportInfo(DisplayHandle displayHandle, OutputId outputId = OutputId.Invalid) { var getHDMISupportInfo = DelegateFactory.GetDelegate(); foreach (var acceptType in getHDMISupportInfo.Accepts()) { var instance = acceptType.Instantiate(); using (var supportInfoReference = ValueTypeReference.FromValueType(instance, acceptType)) { var status = getHDMISupportInfo(displayHandle, (uint)outputId, supportInfoReference); if (status == Status.IncompatibleStructureVersion) { continue; } if (status != Status.Ok) { throw new NVIDIAApiException(status); } return supportInfoReference.ToValueType(acceptType); } } throw new NVIDIANotSupportedException("This operation is not supported."); } /// /// This API returns the current info-frame data on the specified device (monitor). /// /// The display id of the device to retrieve HDMI support information for. /// An instance of a type implementing the interface. public static IHDMISupportInfo GetHDMISupportInfo(uint displayId) { var getHDMISupportInfo = DelegateFactory.GetDelegate(); foreach (var acceptType in getHDMISupportInfo.Accepts()) { var instance = acceptType.Instantiate(); using (var supportInfoReference = ValueTypeReference.FromValueType(instance, acceptType)) { var status = getHDMISupportInfo(DisplayHandle.DefaultHandle, displayId, supportInfoReference); if (status == Status.IncompatibleStructureVersion) { continue; } if (status != Status.Ok) { throw new NVIDIAApiException(status); } return supportInfoReference.ToValueType(acceptType); } } throw new NVIDIANotSupportedException("This operation is not supported."); } /// [PRIVATE] /// /// This API returns the current default HUE angle /// /// /// The targeted display's handle. /// /// An instance of the PrivateDisplayHUEInfo structure containing requested information. public static PrivateDisplayHUEInfo GetHUEInfo(DisplayHandle display) { var instance = typeof(PrivateDisplayHUEInfo).Instantiate(); using (var displayDVCInfoReference = ValueTypeReference.FromValueType(instance)) { var status = DelegateFactory.GetDelegate()( display, OutputId.Invalid, displayDVCInfoReference ); if (status != Status.Ok) { throw new NVIDIAApiException(status); } return displayDVCInfoReference.ToValueType().GetValueOrDefault(); } } /// [PRIVATE] /// /// This API returns the current and default HUE angle /// /// /// The targeted display output id. /// /// An instance of the PrivateDisplayHUEInfo structure containing requested information. public static PrivateDisplayHUEInfo GetHUEInfo(OutputId displayId) { var instance = typeof(PrivateDisplayHUEInfo).Instantiate(); using (var displayDVCInfoReference = ValueTypeReference.FromValueType(instance)) { var status = DelegateFactory.GetDelegate()( DisplayHandle.DefaultHandle, displayId, displayDVCInfoReference ); if (status != Status.Ok) { throw new NVIDIAApiException(status); } return displayDVCInfoReference.ToValueType().GetValueOrDefault(); } } /// /// This API returns all the monitor capabilities. /// /// The target display id. /// The type of capabilities requested. /// An instance of . public static MonitorCapabilities? GetMonitorCapabilities( uint displayId, MonitorCapabilitiesType capabilitiesType) { var instance = new MonitorCapabilities(capabilitiesType); using (var monitorCapReference = ValueTypeReference.FromValueType(instance)) { var status = DelegateFactory.GetDelegate()( displayId, monitorCapReference ); if (status == Status.Error) { return null; } if (status != Status.Ok) { throw new NVIDIAApiException(status); } instance = monitorCapReference.ToValueType().GetValueOrDefault(); if (!instance.IsValid) { return null; } return instance; } } /// /// This API returns all the color formats and bit depth values supported by a given display port monitor. /// /// The target display id. /// A list of instances. public static MonitorColorData[] GetMonitorColorCapabilities(uint displayId) { var getMonitorColorCapabilities = DelegateFactory.GetDelegate(); var count = 0u; var status = getMonitorColorCapabilities(displayId, ValueTypeArray.Null, ref count); if (status != Status.Ok) { throw new NVIDIAApiException(status); } if (count == 0) { return new MonitorColorData[0]; } var array = typeof(MonitorColorData).Instantiate().Repeat((int) count); using (var monitorCapsReference = ValueTypeArray.FromArray(array)) { status = getMonitorColorCapabilities(displayId, monitorCapsReference, ref count); if (status != Status.Ok) { throw new NVIDIAApiException(status); } return monitorCapsReference.ToArray((int) count); } } /// /// This API returns the Display ID of the GDI Primary. /// /// Display ID of the GDI Primary. /// Status.NvidiaDeviceNotFound: GDI Primary not on an NVIDIA GPU. /// Status.ApiNotInitialized: The NvAPI API needs to be initialized first /// Status.NoImplementation: This entry-point not available /// Status.Error: Miscellaneous error occurred /// A delegate callback throws an exception. public static uint GetGDIPrimaryDisplayId() { var getGDIPrimaryDisplay = DelegateFactory.GetDelegate(); var status = getGDIPrimaryDisplay(out var displayId); if (status != Status.Ok) { throw new NVIDIAApiException(status); } return displayId; } /// /// This API gets High Dynamic Range (HDR) capabilities of the display. /// /// The targeted display id. /// /// A boolean value indicating if the EDID HDR parameters should be expanded (true) or the actual current HDR /// parameters should be reported (false). /// /// HDR capabilities of the display public static HDRCapabilitiesV1 GetHDRCapabilities(uint displayId, bool driverExpandDefaultHDRParameters) { var hdrCapabilities = new HDRCapabilitiesV1(driverExpandDefaultHDRParameters); using (var hdrCapabilitiesReference = ValueTypeReference.FromValueType(hdrCapabilities)) { var status = DelegateFactory.GetDelegate()( displayId, hdrCapabilitiesReference ); if (status != Status.Ok) { throw new NVIDIAApiException(status); } return hdrCapabilitiesReference.ToValueType().GetValueOrDefault(); } } /// /// This API queries current state of one of the various scan-out composition parameters on the specified display. /// /// Combined physical display and GPU identifier of the display to query the configuration. /// Scan-out composition parameter to by queried. /// Additional container containing the returning data associated with the specified parameter. /// Scan-out composition parameter value. public static ScanOutCompositionParameterValue GetScanOutCompositionParameter( uint displayId, ScanOutCompositionParameter parameter, out float container) { var status = DelegateFactory.GetDelegate()( displayId, parameter, out var parameterValue, out container ); if (status != Status.Ok) { throw new NVIDIAApiException(status); } return parameterValue; } /// /// This API queries the desktop and scan-out portion of the specified display. /// /// Combined physical display and GPU identifier of the display to query the configuration. /// Desktop area to displayId mapping information. public static ScanOutInformationV1 GetScanOutConfiguration(uint displayId) { var instance = typeof(ScanOutInformationV1).Instantiate(); using (var scanOutInformationReference = ValueTypeReference.FromValueType(instance)) { var status = DelegateFactory.GetDelegate()( displayId, scanOutInformationReference ); if (status != Status.Ok) { throw new NVIDIAApiException(status); } return scanOutInformationReference.ToValueType().GetValueOrDefault(); } } /// /// This API queries the desktop and scan-out portion of the specified display. /// /// Combined physical display and GPU identifier of the display to query the configuration. /// Desktop area of the display in desktop coordinates. /// Scan-out area of the display relative to desktopRect. public static void GetScanOutConfiguration( uint displayId, out Rectangle desktopRectangle, out Rectangle scanOutRectangle) { var instance1 = typeof(Rectangle).Instantiate(); var instance2 = typeof(Rectangle).Instantiate(); using (var desktopRectangleReference = ValueTypeReference.FromValueType(instance1)) { using (var scanOutRectangleReference = ValueTypeReference.FromValueType(instance2)) { var status = DelegateFactory.GetDelegate()( displayId, desktopRectangleReference, scanOutRectangleReference ); if (status != Status.Ok) { throw new NVIDIAApiException(status); } desktopRectangle = desktopRectangleReference.ToValueType().GetValueOrDefault(); scanOutRectangle = scanOutRectangleReference.ToValueType().GetValueOrDefault(); } } } /// /// This API queries current state of the intensity feature on the specified display. /// /// Combined physical display and GPU identifier of the display to query the configuration. /// Intensity state data. public static ScanOutIntensityStateV1 GetScanOutIntensityState(uint displayId) { var instance = typeof(ScanOutIntensityStateV1).Instantiate(); using (var scanOutIntensityReference = ValueTypeReference.FromValueType(instance)) { var status = DelegateFactory.GetDelegate()( displayId, scanOutIntensityReference ); if (status != Status.Ok) { throw new NVIDIAApiException(status); } return scanOutIntensityReference.ToValueType().GetValueOrDefault(); } } /// /// This API queries current state of the warping feature on the specified display. /// /// Combined physical display and GPU identifier of the display to query the configuration. /// The warping state data. public static ScanOutWarpingStateV1 GetScanOutWarpingState(uint displayId) { var instance = typeof(ScanOutWarpingStateV1).Instantiate(); using (var scanOutWarpingReference = ValueTypeReference.FromValueType(instance)) { var status = DelegateFactory.GetDelegate()( displayId, scanOutWarpingReference ); if (status != Status.Ok) { throw new NVIDIAApiException(status); } return scanOutWarpingReference.ToValueType().GetValueOrDefault(); } } /// /// This API lets caller enumerate all the supported NVIDIA display views - nView and DualView modes. /// /// /// NVIDIA Display selection. It can be DisplayHandle.DefaultHandle or a handle enumerated from /// DisplayApi.EnumNVidiaDisplayHandle(). /// /// Array of supported views. /// This operation is not supported. /// Status.Error: Miscellaneous error occurred /// Status.InvalidArgument: Invalid input parameter. /// A delegate callback throws an exception. public static TargetViewMode[] GetSupportedViews(DisplayHandle display) { var getSupportedViews = DelegateFactory.GetDelegate(); uint allAvailable = 0; var status = getSupportedViews(display, ValueTypeArray.Null, ref allAvailable); if (status != Status.Ok) { throw new NVIDIAApiException(status); } if (allAvailable == 0) { return new TargetViewMode[0]; } if (!getSupportedViews.Accepts().Contains(typeof(TargetViewMode))) { throw new NVIDIANotSupportedException("This operation is not supported."); } using ( var viewModes = ValueTypeArray.FromArray(TargetViewMode.Standard.Repeat((int) allAvailable).Cast(), typeof(TargetViewMode).GetEnumUnderlyingType())) { status = getSupportedViews(display, viewModes, ref allAvailable); if (status != Status.Ok) { throw new NVIDIAApiException(status); } return viewModes.ToArray((int) allAvailable, typeof(TargetViewMode).GetEnumUnderlyingType()); } } /// /// This function calculates the timing from the visible width/height/refresh-rate and timing type info. /// /// Display ID of the display. /// Inputs used for calculating the timing. /// An instance of the structure. public static Timing GetTiming(uint displayId, TimingInput timingInput) { var instance = typeof(Timing).Instantiate(); using (var timingInputReference = ValueTypeReference.FromValueType(timingInput)) { using (var timingReference = ValueTypeReference.FromValueType(instance)) { var status = DelegateFactory.GetDelegate()( displayId, timingInputReference, timingReference ); if (status != Status.Ok) { throw new NVIDIAApiException(status); } return timingReference.ToValueType().GetValueOrDefault(); } } } /// /// This function returns the display name given, for example, "\\DISPLAY1", using the unattached NVIDIA display handle /// /// Handle of the associated unattached display /// Name of the display /// Status.InvalidArgument: Display handle is null. /// Status.NvidiaDeviceNotFound: No NVIDIA device maps to that display name. /// A delegate callback throws an exception. public static string GetUnAttachedAssociatedDisplayName(UnAttachedDisplayHandle display) { var getUnAttachedAssociatedDisplayName = DelegateFactory.GetDelegate(); var status = getUnAttachedAssociatedDisplayName(display, out var displayName); if (status != Status.Ok) { throw new NVIDIAApiException(status); } return displayName.Value; } /// /// This API controls the InfoFrame values. /// /// The targeted display id. /// The structure to be filled with information requested or applied on the display. public static void InfoFrameControl(uint displayId, ref InfoFrameData infoFrameData) { var infoFrameControl = DelegateFactory.GetDelegate(); using (var infoFrameDataReference = ValueTypeReference.FromValueType(infoFrameData)) { var status = infoFrameControl(displayId, infoFrameDataReference); if (status != Status.Ok) { throw new NVIDIAApiException(status); } infoFrameData = infoFrameDataReference.ToValueType().GetValueOrDefault(); } } /// /// This API is used to restore the display configuration, that was changed by calling . /// This function must be called only after a custom display configuration is tested on the hardware, using /// , otherwise no action is taken. /// On Vista, should be called with an active display that was affected during /// the call, per GPU. /// /// Array of display ids on which custom display configuration is to be reverted. public static void RevertCustomDisplayTrial(uint[] displayIds) { if (displayIds.Length == 0) { return; } using (var displayIdsReference = ValueTypeArray.FromArray(displayIds)) { var status = DelegateFactory.GetDelegate()( displayIdsReference, (uint) displayIds.Length ); if (status != Status.Ok) { throw new NVIDIAApiException(status); } } } /// /// This API configures High Dynamic Range (HDR) and Extended Dynamic Range (EDR) output. /// /// The targeted display id. /// The structure to be filled with information requested or applied on the display. public static void HDRColorControl(uint displayId, ref THDRColorData hdrColorData) where THDRColorData : struct, IHDRColorData { var c = hdrColorData as IHDRColorData; HDRColorControl(displayId, ref c); hdrColorData = (THDRColorData)c; } /// /// This API configures High Dynamic Range (HDR) and Extended Dynamic Range (EDR) output. /// /// The targeted display id. /// The structure to be filled with information requested or applied on the display. public static void HDRColorControl(uint displayId, ref IHDRColorData hdrColorData) { var hdrColorControl = DelegateFactory.GetDelegate(); var type = hdrColorData.GetType(); if (!hdrColorControl.Accepts().Contains(type)) { throw new ArgumentOutOfRangeException(nameof(type)); } using (var hdrColorDataReference = ValueTypeReference.FromValueType(hdrColorData, type)) { var status = hdrColorControl(displayId, hdrColorDataReference); if (status != Status.Ok) { throw new NVIDIAApiException(status); } hdrColorData = hdrColorDataReference.ToValueType(type); } } /// /// This function saves the current hardware display configuration on the specified Display IDs as a custom display /// configuration. /// This function should be called right after to save the custom display from the /// current hardware context. /// This function will not do anything if the custom display configuration is not tested on the hardware. /// /// Array of display ids on which custom display configuration is to be saved. /// /// If set, the saved custom display will only be applied on the monitor with the same /// outputId. /// /// /// If set, the saved custom display will only be applied on the monitor with the same EDID /// ID or the same TV connector in case of analog TV. /// public static void SaveCustomDisplay(uint[] displayIds, bool isThisOutputIdOnly, bool isThisMonitorOnly) { if (displayIds.Length == 0) { return; } using (var displayIdsReference = ValueTypeArray.FromArray(displayIds)) { var status = DelegateFactory.GetDelegate()( displayIdsReference, (uint) displayIds.Length, isThisOutputIdOnly ? 1 : (uint) 0, isThisMonitorOnly ? 1 : (uint) 0 ); if (status != Status.Ok) { throw new NVIDIAApiException(status); } } } /// /// This API configures High Dynamic Range (HDR) and Extended Dynamic Range (EDR) output. /// /// The targeted display id. /// The list of structures to be filled with information requested or applied on the display. /// The structure that succeed in requesting information or used for applying configuration on the display. // ReSharper disable once IdentifierTypo public static IHDRColorData HDRColorControl(uint displayId, IHDRColorData[] colorDatas) { foreach (var colorData in colorDatas) { try { var c = colorData; HDRColorControl(displayId, ref c); return c; } catch (NVIDIAApiException e) { if (e.Status == Status.IncompatibleStructureVersion) { continue; } throw; } } throw new NVIDIANotSupportedException("This operation is not supported."); } /// /// This API lets caller apply a global display configuration across multiple GPUs. /// If all sourceIds are zero, then NvAPI will pick up sourceId's based on the following criteria : /// - If user provides SourceModeInfo then we are trying to assign 0th SourceId always to GDIPrimary. /// This is needed since active windows always moves along with 0th sourceId. /// - For rest of the paths, we are incrementally assigning the SourceId per adapter basis. /// - If user doesn't provide SourceModeInfo then NVAPI just picks up some default SourceId's in incremental order. /// Note : NVAPI will not intelligently choose the SourceIDs for any configs that does not need a mode-set. /// /// Array of path information /// Flags for applying settings /// This operation is not supported. /// Status.ApiNotInitialized: NVAPI not initialized /// Status.Error: Miscellaneous error occurred /// Status.InvalidArgument: Invalid input parameter. /// A delegate callback throws an exception. public static void SetDisplayConfig(IPathInfo[] pathInfos, DisplayConfigFlags flags) { var setDisplayConfig = DelegateFactory.GetDelegate(); if (pathInfos.Length > 0 && !setDisplayConfig.Accepts().Contains(pathInfos[0].GetType())) { throw new NVIDIANotSupportedException("This operation is not supported."); } using (var arrayReference = ValueTypeArray.FromArray(pathInfos)) { var status = setDisplayConfig((uint) pathInfos.Length, arrayReference, flags); if (status != Status.Ok) { throw new NVIDIAApiException(status); } } } /// [PRIVATE] /// /// This API sets the current saturation level for the Digital Vibrance Control /// /// /// The targeted display's handle. /// /// /// The saturation level to be set. /// public static void SetDVCLevel(DisplayHandle display, int currentLevel) { var status = DelegateFactory.GetDelegate()( display, OutputId.Invalid, currentLevel ); if (status != Status.Ok) { throw new NVIDIAApiException(status); } } /// [PRIVATE] /// /// This API sets the current saturation level for the Digital Vibrance Control /// /// /// The targeted display output id. /// /// /// The saturation level to be set. /// public static void SetDVCLevel(OutputId displayId, int currentLevel) { var status = DelegateFactory.GetDelegate()( DisplayHandle.DefaultHandle, displayId, currentLevel ); if (status != Status.Ok) { throw new NVIDIAApiException(status); } } /// [PRIVATE] /// /// This API sets the current saturation level for the Digital Vibrance Control. /// The difference between this API and the 'SetDVCLevel()' includes the possibility to set under saturated /// levels. /// /// /// The targeted display's handle. /// /// /// The saturation level to be set. /// public static void SetDVCLevelEx(DisplayHandle display, int currentLevel) { var instance = new PrivateDisplayDVCInfoEx(currentLevel); using (var displayDVCInfoReference = ValueTypeReference.FromValueType(instance)) { var status = DelegateFactory.GetDelegate()( display, OutputId.Invalid, displayDVCInfoReference ); if (status != Status.Ok) { throw new NVIDIAApiException(status); } } } /// [PRIVATE] /// /// This API sets the current saturation level for the Digital Vibrance Control. /// The difference between this API and the 'SetDVCLevel()' includes the possibility to set under saturated /// levels. /// /// /// The targeted display output id. /// /// /// The saturation level to be set. /// public static void SetDVCLevelEx(OutputId displayId, int currentLevel) { var instance = new PrivateDisplayDVCInfoEx(currentLevel); using (var displayDVCInfoReference = ValueTypeReference.FromValueType(instance)) { var status = DelegateFactory.GetDelegate()( DisplayHandle.DefaultHandle, displayId, displayDVCInfoReference ); if (status != Status.Ok) { throw new NVIDIAApiException(status); } } } /// [PRIVATE] /// /// This API sets the current HUE angle /// /// /// The targeted display's handle. /// /// /// The HUE angle to be set. /// public static void SetHUEAngle(DisplayHandle display, int currentAngle) { var status = DelegateFactory.GetDelegate()( display, OutputId.Invalid, currentAngle ); if (status != Status.Ok) { throw new NVIDIAApiException(status); } } /// [PRIVATE] /// /// This API sets the current HUE angle /// /// /// The targeted display output id. /// /// /// The HUE angle to be set. /// public static void SetHUEAngle(OutputId displayId, int currentAngle) { var status = DelegateFactory.GetDelegate()( DisplayHandle.DefaultHandle, displayId, currentAngle ); if (status != Status.Ok) { throw new NVIDIAApiException(status); } } /// /// This function overrides the refresh rate on the given display. /// The new refresh rate can be applied right away in this API call or deferred to be applied with the next OS /// mode-set. /// The override is good for only one mode-set (regardless whether it's deferred or immediate). /// /// The display handle to override refresh rate of. /// The override refresh rate. /// /// A boolean value indicating if the refresh rate override should be deferred to the next OS /// mode-set. /// public static void SetRefreshRateOverride(DisplayHandle display, float refreshRate, bool isDeferred) { var status = DelegateFactory.GetDelegate()( display, OutputId.Invalid, refreshRate, isDeferred ? 1u : 0 ); if (status != Status.Ok) { throw new NVIDIAApiException(status); } } /// /// This function overrides the refresh rate on the given output mask. /// The new refresh rate can be applied right away in this API call or deferred to be applied with the next OS /// mode-set. /// The override is good for only one mode-set (regardless whether it's deferred or immediate). /// /// The output(s) to override refresh rate of. /// The override refresh rate. /// /// A boolean value indicating if the refresh rate override should be deferred to the next OS /// mode-set. /// public static void SetRefreshRateOverride(OutputId outputMask, float refreshRate, bool isDeferred) { var status = DelegateFactory.GetDelegate()( DisplayHandle.DefaultHandle, outputMask, refreshRate, isDeferred ? 1u : 0 ); if (status != Status.Ok) { throw new NVIDIAApiException(status); } } /// /// This API sets various parameters that configure the scan-out composition feature on the specified display. /// /// Combined physical display and GPU identifier of the display to apply the intensity control. /// The scan-out composition parameter to be set. /// The value to be set for the specified parameter. /// Additional container for data associated with the specified parameter. // ReSharper disable once TooManyArguments public static void SetScanOutCompositionParameter( uint displayId, ScanOutCompositionParameter parameter, ScanOutCompositionParameterValue parameterValue, ref float container) { var status = DelegateFactory.GetDelegate()( displayId, parameter, parameterValue, ref container ); if (status != Status.Ok) { throw new NVIDIAApiException(status); } } /// /// This API enables and sets up per-pixel intensity feature on the specified display. /// /// Combined physical display and GPU identifier of the display to apply the intensity control. /// The intensity texture info. /// Indicates whether the settings will be kept over a reboot. public static void SetScanOutIntensity(uint displayId, IScanOutIntensity scanOutIntensity, out bool isSticky) { Status status; int isStickyInt; if (scanOutIntensity == null) { status = DelegateFactory.GetDelegate()( displayId, ValueTypeReference.Null, out isStickyInt ); } else { using (var scanOutWarpingReference = ValueTypeReference.FromValueType(scanOutIntensity, scanOutIntensity.GetType())) { status = DelegateFactory.GetDelegate()( displayId, scanOutWarpingReference, out isStickyInt ); } } if (status != Status.Ok) { throw new NVIDIAApiException(status); } isSticky = isStickyInt > 0; } /// /// This API enables and sets up the warping feature on the specified display. /// /// Combined physical display and GPU identifier of the display to apply the intensity control. /// The warping data info. /// The maximum number of vertices. /// Indicates whether the settings will be kept over a reboot. // ReSharper disable once TooManyArguments public static void SetScanOutWarping( uint displayId, ScanOutWarpingV1? scanOutWarping, ref int maximumNumberOfVertices, out bool isSticky) { Status status; int isStickyInt; if (scanOutWarping == null || maximumNumberOfVertices == 0) { maximumNumberOfVertices = 0; status = DelegateFactory.GetDelegate()( displayId, ValueTypeReference.Null, ref maximumNumberOfVertices, out isStickyInt ); } else { using (var scanOutWarpingReference = ValueTypeReference.FromValueType(scanOutWarping.Value)) { status = DelegateFactory.GetDelegate()( displayId, scanOutWarpingReference, ref maximumNumberOfVertices, out isStickyInt ); } } if (status != Status.Ok) { throw new NVIDIAApiException(status); } isSticky = isStickyInt > 0; } /// /// This API is used to set up a custom display without saving the configuration on multiple displays. /// /// A list of display ids with corresponding custom display instances. public static void TryCustomDisplay(IDictionary displayIdCustomDisplayPairs) { if (displayIdCustomDisplayPairs.Count == 0) { return; } using (var displayIdsReference = ValueTypeArray.FromArray(displayIdCustomDisplayPairs.Keys.ToArray())) { using (var customDisplaysReference = ValueTypeArray.FromArray(displayIdCustomDisplayPairs.Values.ToArray())) { var status = DelegateFactory.GetDelegate()( displayIdsReference, (uint) displayIdCustomDisplayPairs.Count, customDisplaysReference ); if (status != Status.Ok) { throw new NVIDIAApiException(status); } } } } } }