private static DisplayInfoArrays GetDisplayConfigPathInfos(QueryDisplayFlags displayFlags) { var status = Wrapper.GetDisplayConfigBufferSizes( displayFlags, out var numPathArrayElements, out var numModeInfoArrayElements); if (status != StatusCode.Success) { var reason = $"GetDisplayConfigBufferSizesFailed() failed. Status: {status}"; throw new Exception(reason); } var pathInfoArray = new DisplayConfigPathInfo[numPathArrayElements]; var modeInfoArray = new DisplayConfigModeInfo[numModeInfoArrayElements]; var queryDisplayStatus = Wrapper.QueryDisplayConfig( displayFlags, ref numPathArrayElements, pathInfoArray, ref numModeInfoArrayElements, modeInfoArray); if (queryDisplayStatus != StatusCode.Success) { var reason = $"QueryDisplayConfig() failed. Status: {queryDisplayStatus}"; throw new Exception(reason); } var infoArrays = new DisplayInfoArrays { Paths = pathInfoArray, Modes = modeInfoArray }; return(infoArrays); }
public static Tuple <List <DisplayConfigPathInfo>, List <DisplayConfigModeInfo> > GetDisplayConfig(QueryDisplayFlags flags) { while (true) { uint numPathArrayElements, numModeInfoArrayElements; var err = GetDisplayConfigBufferSizes(flags, out numPathArrayElements, out numModeInfoArrayElements); if (err != NO_ERROR) { throw Marshal.GetExceptionForHR(Win32ErrorToHResult(err)); } var pathArray = new DisplayConfigPathInfo[numPathArrayElements]; var modeArray = new DisplayConfigModeInfo[numModeInfoArrayElements]; err = QueryDisplayConfig(flags, ref numPathArrayElements, pathArray, ref numModeInfoArrayElements, modeArray, IntPtr.Zero); if (err == ERROR_INSUFICCIENT_BUFFER) { continue; } if (err != NO_ERROR) { throw Marshal.GetExceptionForHR(Win32ErrorToHResult(err)); } return(Tuple.Create(pathArray.Take((int)numPathArrayElements).ToList(), modeArray.Take((int)numModeInfoArrayElements).ToList())); } }
private static IEnumerable <string> GetAllMonitorsFriendlyNames() { var error = GetDisplayConfigBufferSizes(QueryDeviceConfigFlags.QdcOnlyActivePaths, out var pathCount, out var modeCount); if (error != ErrorSuccess) { throw new Win32Exception(error); } var displayPaths = new DisplayConfigPathInfo[pathCount]; var displayModes = new DisplayConfigModeInfo[modeCount]; error = QueryDisplayConfig(QueryDeviceConfigFlags.QdcOnlyActivePaths, ref pathCount, displayPaths, ref modeCount, displayModes, IntPtr.Zero); if (error != ErrorSuccess) { throw new Win32Exception(error); } for (var i = 0; i < modeCount; i++) { if (displayModes[i].infoType == DisplayConfigModeInfoType.Target) { yield return(MonitorFriendlyName(displayModes[i].adapterId, displayModes[i].id)); } } }
public static DisplayTopology GetDisplayTopology() { uint numPathArrayElements = 0; uint numModeInfoArrayElements = 0; NativeMethods.GetDisplayConfigBufferSizes(QueryDisplayFlags.DatabaseCurrent, out numPathArrayElements, out numModeInfoArrayElements); var pathArray = new DisplayConfigPathInfo[numPathArrayElements]; var modeArray = new DisplayConfigModeInfo[numModeInfoArrayElements]; DisplayConfigTopologyId displayTopology; NativeMethods.QueryDisplayConfig(QueryDisplayFlags.DatabaseCurrent, out numPathArrayElements, pathArray, out numModeInfoArrayElements, modeArray, out displayTopology); switch (displayTopology) { case DisplayConfigTopologyId.External: return(DisplayTopology.External); case DisplayConfigTopologyId.Internal: return(DisplayTopology.Internal); case DisplayConfigTopologyId.Extend: return(DisplayTopology.Extend); } return(DisplayTopology.Clone); }
private void btnRotate_Click(object sender, EventArgs e) { DisplayConfigRotation displayConfigRotation = (DisplayConfigRotation)Enum.Parse(typeof(DisplayConfigRotation), comRotate.Text); int numPathArrayElements; int numModeInfoArrayElements; const QueryDisplayFlags pathType = QueryDisplayFlags.OnlyActivePaths; // query active paths from the current computer. // note that 0 is equal to SUCCESS! // TODO; HARDCODE MAGIC VALUES AWAY. if (CCDWrapper.GetDisplayConfigBufferSizes(pathType, out numPathArrayElements, out numModeInfoArrayElements) == 0) { var pathInfoArray = new DisplayConfigPathInfo[numPathArrayElements]; var modeInfoArray = new DisplayConfigModeInfo[numModeInfoArrayElements]; // TODO; FALLBACK MECHANISM THAT HANDLES DIFFERENT VALUES FOR ZERO. if (CCDWrapper.QueryDisplayConfig( pathType, ref numPathArrayElements, pathInfoArray, ref numModeInfoArrayElements, modeInfoArray, IntPtr.Zero) == 0) { pathInfoArray[0].targetInfo.rotation = displayConfigRotation; CCDWrapper.SetDisplayConfig(numPathArrayElements, pathInfoArray, numModeInfoArrayElements, modeInfoArray, SdcFlags.Apply | SdcFlags.UseSuppliedDisplayConfig); } } }
private static DisplayConfigModeInfo[] GetNewModeInfosArrayWithAddedInfo(DisplayConfigModeInfo[] modeInfoArray, DisplayConfigModeInfo tvModeInfo) { var modeList = modeInfoArray.ToList(); modeList.Add(tvModeInfo); var newModeArray = modeList.ToArray(); return(newModeArray); }
private static DisplayConfigTargetDeviceName[] GetDisplayConfigs() { var error = NativeMethods.GetDisplayConfigBufferSizes(QueryDeviceConfigFlags.QdcOnlyActivePaths, out var pathInfoElementsCount, out var modeInfoElementsCount); if (error != 0) { throw Log.ErrorAndCreateException <Win32Exception>($"Function {nameof(NativeMethods.GetDisplayConfigBufferSizes)} returns error code '{error}'"); } var displayConfigs = new List <DisplayConfigTargetDeviceName>(); var displayConfigPathInfos = new DisplayConfigPathInfo[pathInfoElementsCount]; var displayConfigModeInfos = new DisplayConfigModeInfo[modeInfoElementsCount]; error = NativeMethods.QueryDisplayConfig(QueryDeviceConfigFlags.QdcOnlyActivePaths, ref pathInfoElementsCount, displayConfigPathInfos, ref modeInfoElementsCount, displayConfigModeInfos, IntPtr.Zero); if (error != 0) { throw Log.ErrorAndCreateException <Win32Exception>($"Function {nameof(NativeMethods.QueryDisplayConfig)} returns error code '{error}'"); } foreach (var pathInfo in displayConfigPathInfos) { var adapterName = new DisplayConfigAdapterName(pathInfo.TargetInfo.AdapterId, DisplayConfig.DeviceInfoType.DisplayConfigDeviceInfoGetAdapterName); var targetDeviceName = new DisplayConfigTargetDeviceName() { Header = DisplayConfigDeviceInfoHeader.Initialize(pathInfo.TargetInfo.AdapterId, pathInfo.TargetInfo.Id, DisplayConfig.DeviceInfoType.DisplayConfigDeviceInfoGetTargetName, (uint)Marshal.SizeOf <DisplayConfigTargetDeviceName>()) }; error = (int)NativeMethods.DisplayConfigGetDeviceInfo(ref targetDeviceName); try { if (error != 0) { throw Log.ErrorAndCreateException <Win32Exception>($"Function {nameof(NativeMethods.DisplayConfigGetDeviceInfo)} returns error code '{error}'"); } displayConfigs.Add(targetDeviceName); } catch (Win32Exception ex) { Log.Error(ex); } } return(displayConfigs.ToArray()); }
private IEnumerable <DisplayConfigPathWrap> QueryDisplay(QueryDisplayFlags pathType, out DisplayConfigTopologyId topologyId) { topologyId = DisplayConfigTopologyId.Zero; var status = Win32Api.GetDisplayConfigBufferSizes( pathType, out int numPathArrayElements, out int numModeInfoArrayElements); if (status != StatusCode.Success) { var reason = string.Format("GetDisplayConfigBufferSizesFailed() failed. Status: {0}", status); throw new InvalidOperationException(reason); } var pathInfoArray = new DisplayConfigPathInfo[numPathArrayElements]; var modeInfoArray = new DisplayConfigModeInfo[numModeInfoArrayElements]; var queryDisplayStatus = pathType == QueryDisplayFlags.DatabaseCurrent ? Win32Api.QueryDisplayConfig(pathType, ref numPathArrayElements, pathInfoArray, ref numModeInfoArrayElements, modeInfoArray, out topologyId) : Win32Api.QueryDisplayConfig(pathType, ref numPathArrayElements, pathInfoArray, ref numModeInfoArrayElements, modeInfoArray); if (queryDisplayStatus != StatusCode.Success) { var reason = string.Format("QueryDisplayConfig() failed. Status: {0}", queryDisplayStatus); throw new InvalidOperationException(reason); } var list = new List <DisplayConfigPathWrap>(); foreach (var path in pathInfoArray) { var outputModes = new List <DisplayConfigModeInfo>(); foreach (var modeIndex in new[] { path.sourceInfo.modeInfoIdx, path.targetInfo.modeInfoIdx }) { if (modeIndex >= 0 && modeIndex < modeInfoArray.Length) { outputModes.Add(modeInfoArray[modeIndex]); } } list.Add(new DisplayConfigPathWrap(path, outputModes)); } return(list); }
private static StatusCode GetDisplayConfigTargetDeviceName(DisplayConfigModeInfo targetModeInfo, out DisplayConfigTargetDeviceName displayConfigTargetDeviceName) { displayConfigTargetDeviceName = new DisplayConfigTargetDeviceName { header = new DisplayConfigDeviceInfoHeader { adapterId = targetModeInfo.adapterId, id = targetModeInfo.id, size = Marshal.SizeOf(typeof(DisplayConfigTargetDeviceName)), type = DisplayConfigDeviceInfoType.GetTargetName, } }; return(Win32Api.DisplayConfigGetDeviceInfo(ref displayConfigTargetDeviceName)); }
/// <summary> /// This method give you access to monitor device name. /// Such as "\\DISPLAY1" /// </summary> /// <param name="sourceModeInfo"></param> /// <param name="displayConfigSourceDeviceName"></param> /// <returns></returns> public static StatusCode GetDisplayConfigSourceDeviceName( DisplayConfigModeInfo sourceModeInfo, out DisplayConfigSourceDeviceName displayConfigSourceDeviceName) { displayConfigSourceDeviceName = new DisplayConfigSourceDeviceName { header = new DisplayConfigDeviceInfoHeader { adapterId = sourceModeInfo.adapterId, id = sourceModeInfo.id, size = Marshal.SizeOf( typeof(DisplayConfigSourceDeviceName)), type = DisplayConfigDeviceInfoType.GetSourceName } }; return(Wrapper.DisplayConfigGetDeviceInfo(ref displayConfigSourceDeviceName)); }
/// <summary> /// This method give you access to monitor device name. /// Such as "\\DISPLAY1" /// </summary> /// <param name="sourceModeInfo"></param> /// <param name="displayConfigSourceDeviceName"></param> /// <returns></returns> public static StatusCode GetDisplayConfigSourceDeviceName( DisplayConfigModeInfo sourceModeInfo, out DisplayConfigSourceDeviceName displayConfigSourceDeviceName) { displayConfigSourceDeviceName = new DisplayConfigSourceDeviceName { header = new DisplayConfigDeviceInfoHeader { adapterId = sourceModeInfo.adapterId, id = sourceModeInfo.id, size = Marshal.SizeOf( typeof (DisplayConfigSourceDeviceName)), type = DisplayConfigDeviceInfoType.GetSourceName } }; return Wrapper.DisplayConfigGetDeviceInfo(ref displayConfigSourceDeviceName); }
private static uint AddMode(ref List <DisplayConfigModeInfo> modes, DisplayConfigModeInfo mode) { var existingMode = modes.FindIndex( info => (info.InfoType == mode.InfoType) && (info.AdapterId == mode.AdapterId) && (info.Id == mode.Id)); if (existingMode > 0) { if (modes[existingMode] == mode) { return((uint)existingMode); } throw new DuplicateModeException( "Provided list of path informations, contains one or more duplicate but not identical modes."); } modes.Add(mode); return((uint)modes.Count - 1); }
public static DisplayConfigTopologyId GetCurrentMode(QueryDisplayFlags pathType = QueryDisplayFlags.DatabaseCurrent) { DisplayConfigTopologyId topologyId = DisplayConfigTopologyId.Zero; int numPathArrayElements; int numModeInfoArrayElements; var status = CCDWrapper.GetDisplayConfigBufferSizes( pathType, out numPathArrayElements, out numModeInfoArrayElements); if (status != StatusCode.Success) { // TODO; POSSIBLY HANDLE SOME OF THE CASES. var reason = string.Format("GetDisplayConfigBufferSizesFailed() failed. Status: {0}", status); throw new Exception(reason); } var pathInfoArray = new DisplayConfigPathInfo[numPathArrayElements]; var modeInfoArray = new DisplayConfigModeInfo[numModeInfoArrayElements]; var queryDisplayStatus = pathType == QueryDisplayFlags.DatabaseCurrent ? CCDWrapper.QueryDisplayConfig( pathType, ref numPathArrayElements, pathInfoArray, ref numModeInfoArrayElements, modeInfoArray, out topologyId) : CCDWrapper.QueryDisplayConfig( pathType, ref numPathArrayElements, pathInfoArray, ref numModeInfoArrayElements, modeInfoArray); if (queryDisplayStatus != StatusCode.Success) { // TODO; POSSIBLY HANDLE SOME OF THE CASES. var reason = string.Format("QueryDisplayConfig() failed. Status: {0}", queryDisplayStatus); throw new Exception(reason); } return(topologyId); }
public static DisplayConfiguration QueryDisplayConfig(QueryDisplayFlags flags) { int numPathArrayElements; int numModeInfoArrayElements; var queryErrorCode = User32.GetDisplayConfigBufferSizes(flags, out numPathArrayElements, out numModeInfoArrayElements); if (queryErrorCode == 0) { var pathInfoArray = new DisplayConfigPathInfo[numPathArrayElements]; var modeInfoArray = new DisplayConfigModeInfo[numModeInfoArrayElements]; queryErrorCode = User32.QueryDisplayConfig(flags, ref numPathArrayElements, pathInfoArray, ref numModeInfoArrayElements, modeInfoArray, IntPtr.Zero); return(queryErrorCode == 0 ? new DisplayConfiguration(pathInfoArray, modeInfoArray) : null); } return(null); }
/// <summary> /// This method can be used in order to filter out specific paths that we are interested, /// a long with their corresponding paths. /// </summary> /// <param name="pathType"></param> /// <param name="topologyId"></param> /// <returns></returns> public static IEnumerable <DisplayConfigPathWrap> GetPathWraps( QueryDisplayFlags pathType, out DisplayConfigTopologyId topologyId) { topologyId = DisplayConfigTopologyId.Zero; int numPathArrayElements; int numModeInfoArrayElements; var status = Wrapper.GetDisplayConfigBufferSizes( pathType, out numPathArrayElements, out numModeInfoArrayElements); if (status != StatusCode.Success) { // TODO; POSSIBLY HANDLE SOME OF THE CASES. var reason = string.Format("GetDisplayConfigBufferSizesFailed() failed. Status: {0}", status); throw new Exception(reason); } var pathInfoArray = new DisplayConfigPathInfo[numPathArrayElements]; var modeInfoArray = new DisplayConfigModeInfo[numModeInfoArrayElements]; // topology ID only valid with QDC_DATABASE_CURRENT var queryDisplayStatus = pathType == QueryDisplayFlags.DatabaseCurrent ? Wrapper.QueryDisplayConfig( pathType, ref numPathArrayElements, pathInfoArray, ref numModeInfoArrayElements, modeInfoArray, out topologyId) : Wrapper.QueryDisplayConfig( pathType, ref numPathArrayElements, pathInfoArray, ref numModeInfoArrayElements, modeInfoArray); ////////////////////// if (queryDisplayStatus != StatusCode.Success) { // TODO; POSSIBLY HANDLE SOME OF THE CASES. var reason = string.Format("QueryDisplayConfig() failed. Status: {0}", queryDisplayStatus); throw new Exception(reason); } var list = new List <DisplayConfigPathWrap>(); foreach (var path in pathInfoArray) { var outputModes = new List <DisplayConfigModeInfo>(); foreach (var modeIndex in new[] { path.sourceInfo.modeInfoIdx, path.targetInfo.modeInfoIdx }) { if (modeIndex < modeInfoArray.Length) { outputModes.Add(modeInfoArray[modeIndex]); } } list.Add(new DisplayConfigPathWrap(path, outputModes)); } return(list); }
/// <summary> /// This method can be used in order to filter out specific paths that we are interested, /// a long with their corresponding paths. /// </summary> /// <param name="pathType"></param> /// <param name="topologyId"></param> /// <returns></returns> public static IEnumerable<DisplayConfigPathWrap> GetPathWraps( QueryDisplayFlags pathType, out DisplayConfigTopologyId topologyId) { topologyId = DisplayConfigTopologyId.Zero; int numPathArrayElements; int numModeInfoArrayElements; var status = Wrapper.GetDisplayConfigBufferSizes( pathType, out numPathArrayElements, out numModeInfoArrayElements); if (status != StatusCode.Success) { // TODO; POSSIBLY HANDLE SOME OF THE CASES. var reason = string.Format("GetDisplayConfigBufferSizesFailed() failed. Status: {0}", status); throw new Exception(reason); } var pathInfoArray = new DisplayConfigPathInfo[numPathArrayElements]; var modeInfoArray = new DisplayConfigModeInfo[numModeInfoArrayElements]; // topology ID only valid with QDC_DATABASE_CURRENT var queryDisplayStatus = pathType == QueryDisplayFlags.DatabaseCurrent ? Wrapper.QueryDisplayConfig( pathType, ref numPathArrayElements, pathInfoArray, ref numModeInfoArrayElements, modeInfoArray, out topologyId) : Wrapper.QueryDisplayConfig( pathType, ref numPathArrayElements, pathInfoArray, ref numModeInfoArrayElements, modeInfoArray); ////////////////////// if (queryDisplayStatus != StatusCode.Success) { // TODO; POSSIBLY HANDLE SOME OF THE CASES. var reason = string.Format("QueryDisplayConfig() failed. Status: {0}", queryDisplayStatus); throw new Exception(reason); } var list = new List<DisplayConfigPathWrap>(); foreach (var path in pathInfoArray) { var outputModes = new List<DisplayConfigModeInfo>(); foreach (var modeIndex in new[] { path.sourceInfo.modeInfoIdx, path.targetInfo.modeInfoIdx }) { if (modeIndex < modeInfoArray.Length) outputModes.Add(modeInfoArray[modeIndex]); } list.Add(new DisplayConfigPathWrap(path, outputModes)); } return list; }
public static DisplayTopology GetDisplayTopology() { uint numPathArrayElements = 0; uint numModeInfoArrayElements = 0; NativeMethods.GetDisplayConfigBufferSizes( QueryDisplayFlags.DatabaseCurrent, out numPathArrayElements, out numModeInfoArrayElements ); var pathArray = new DisplayConfigPathInfo[numPathArrayElements]; var modeArray = new DisplayConfigModeInfo[numModeInfoArrayElements]; DisplayConfigTopologyId displayTopology; NativeMethods.QueryDisplayConfig( QueryDisplayFlags.DatabaseCurrent, out numPathArrayElements, pathArray, out numModeInfoArrayElements, modeArray, out displayTopology ); switch( displayTopology ) { case DisplayConfigTopologyId.External: return DisplayTopology.External; case DisplayConfigTopologyId.Internal: return DisplayTopology.Internal; case DisplayConfigTopologyId.Extend: return DisplayTopology.Extend; } return DisplayTopology.Clone; }
public static void SetHDRState(bool enabled, string displayName = null) { uint pathCount, modeCount; var err = NativeMethods.GetDisplayConfigBufferSizes(QueryDisplayFlags.OnlyActivePaths, out pathCount, out modeCount); if (err == NativeConstants.ERROR_SUCCESS) { var pathsArray = new DisplayConfigPathInfo[pathCount]; var modesArray = new DisplayConfigModeInfo[modeCount]; DisplayConfigTopologyId displayTopology; err = NativeMethods.QueryDisplayConfig(QueryDisplayFlags.DatabaseCurrent, ref pathCount, pathsArray, ref modeCount, modesArray, out displayTopology); if (err == NativeConstants.ERROR_SUCCESS) { foreach (var path in pathsArray) { // get display name var info = new DISPLAYCONFIG_SOURCE_DEVICE_NAME(); info.header.type = DISPLAYCONFIG_DEVICE_INFO_TYPE.DISPLAYCONFIG_DEVICE_INFO_GET_SOURCE_NAME; info.header.size = Marshal.SizeOf <DISPLAYCONFIG_SOURCE_DEVICE_NAME>(); info.header.adapterId = path.sourceInfo.adapterId; info.header.id = path.sourceInfo.id; err = NativeMethods.DisplayConfigGetDeviceInfo(ref info); if (err != NativeConstants.ERROR_SUCCESS) { break; } var deviceName = info.viewGdiDeviceName; if (displayName != null && !EqualDisplayNames(deviceName, displayName)) { continue; } var setpacket = new DISPLAYCONFIG_SET_ADVANCED_COLOR_INFO(); setpacket.header = new DISPLAYCONFIG_DEVICE_INFO_HEADER(); setpacket.header.type = DISPLAYCONFIG_DEVICE_INFO_TYPE.DISPLAYCONFIG_DEVICE_INFO_SET_ADVANCED_COLOR_STATE; setpacket.header.size = Marshal.SizeOf <DISPLAYCONFIG_SET_ADVANCED_COLOR_INFO>();; var requestpacket = new DISPLAYCONFIG_GET_ADVANCED_COLOR_INFO(); requestpacket.header = new DISPLAYCONFIG_DEVICE_INFO_HEADER(); requestpacket.header.type = DISPLAYCONFIG_DEVICE_INFO_TYPE.DISPLAYCONFIG_DEVICE_INFO_GET_ADVANCED_COLOR_INFO; requestpacket.header.size = Marshal.SizeOf <DISPLAYCONFIG_GET_ADVANCED_COLOR_INFO>();; for (int i = 0; i < modeCount; i++) { if (modesArray[i].infoType == DisplayConfigModeInfoType.Target) { setpacket.header.adapterId = modesArray[i].adapterId; setpacket.header.id = modesArray[i].id; requestpacket.header.adapterId = modesArray[i].adapterId; requestpacket.header.id = modesArray[i].id; if (NativeMethods.DisplayConfigGetDeviceInfo(ref requestpacket) == NativeConstants.ERROR_SUCCESS) { if (requestpacket.advancedColorSupported) { setpacket.enableAdvancedColor = enabled ? 1U : 0; NativeMethods.DisplayConfigSetDeviceInfo(ref setpacket); } } } } } } } if (err != NativeConstants.ERROR_SUCCESS) { throw new Win32Exception(err); } }
private static PathInfo[] GetPathInfos(QueryDeviceConfigFlags flags, out DisplayConfigTopologyId topologyId) { DisplayConfigPathInfo[] displayPaths; DisplayConfigModeInfo[] displayModes; uint pathCount; while (true) { uint modeCount; var error = DisplayConfigApi.GetDisplayConfigBufferSizes(flags, out pathCount, out modeCount); if (error != Win32Status.Success) { throw new Win32Exception((int)error); } displayPaths = new DisplayConfigPathInfo[pathCount]; displayModes = new DisplayConfigModeInfo[modeCount]; if (flags == QueryDeviceConfigFlags.DatabaseCurrent) { error = DisplayConfigApi.QueryDisplayConfig(flags, ref pathCount, displayPaths, ref modeCount, displayModes, out topologyId); } else { topologyId = DisplayConfigTopologyId.None; error = DisplayConfigApi.QueryDisplayConfig(flags, ref pathCount, displayPaths, ref modeCount, displayModes, IntPtr.Zero); } if (error == Win32Status.Success) { break; } if (error != Win32Status.ErrorInsufficientBuffer) { throw new Win32Exception((int)error); } } var pathInfos = new Dictionary <uint, Tuple <DisplayConfigPathSourceInfo, DisplayConfigSourceMode?, List < Tuple <DisplayConfigPathInfoFlags, DisplayConfigPathTargetInfo, DisplayConfigTargetMode?, DisplayConfigDesktopImageInfo?> > > > (); var sourceId = uint.MaxValue; for (var i = 0u; i < pathCount; i++) { var displayPath = displayPaths[i]; DisplayConfigSourceMode?sourceMode = null; var key = sourceId; var isVirtualSupported = displayPath.Flags.HasFlag(DisplayConfigPathInfoFlags.SupportVirtualMode); if (isVirtualSupported && (displayPath.SourceInfo.SourceModeInfoIndex != DisplayConfigSourceMode.InvalidSourceModeIndex) && (displayModes[displayPath.SourceInfo.SourceModeInfoIndex].InfoType == DisplayConfigModeInfoType.Source)) { sourceMode = displayModes[displayPath.SourceInfo.SourceModeInfoIndex].SourceMode; key = displayPath.SourceInfo.SourceModeInfoIndex; } else if (!isVirtualSupported && (displayPath.SourceInfo.ModeInfoIndex != DisplayConfigModeInfo.InvalidModeIndex) && (displayModes[displayPath.SourceInfo.ModeInfoIndex].InfoType == DisplayConfigModeInfoType.Source)) { sourceMode = displayModes[displayPath.SourceInfo.ModeInfoIndex].SourceMode; key = displayPath.SourceInfo.ModeInfoIndex; } else { sourceId--; } if (!pathInfos.ContainsKey(key)) { pathInfos.Add(key, new Tuple <DisplayConfigPathSourceInfo, DisplayConfigSourceMode?, List < Tuple <DisplayConfigPathInfoFlags, DisplayConfigPathTargetInfo, DisplayConfigTargetMode?, DisplayConfigDesktopImageInfo?> > >( displayPath.SourceInfo, sourceMode, new List < Tuple <DisplayConfigPathInfoFlags, DisplayConfigPathTargetInfo, DisplayConfigTargetMode?, DisplayConfigDesktopImageInfo?> > ())); } DisplayConfigTargetMode?targetMode = null; if (isVirtualSupported && (displayPath.TargetInfo.TargetModeInfoIndex != DisplayConfigTargetMode.InvalidTargetModeIndex) && (displayModes[displayPath.TargetInfo.TargetModeInfoIndex].InfoType == DisplayConfigModeInfoType.Target)) { targetMode = displayModes[displayPath.TargetInfo.TargetModeInfoIndex].TargetMode; } else if (!isVirtualSupported && (displayPath.TargetInfo.ModeInfoIndex != DisplayConfigModeInfo.InvalidModeIndex) && (displayModes[displayPath.TargetInfo.ModeInfoIndex].InfoType == DisplayConfigModeInfoType.Target)) { targetMode = displayModes[displayPath.TargetInfo.ModeInfoIndex].TargetMode; } DisplayConfigDesktopImageInfo?desktopImageMode = null; if (isVirtualSupported && (displayPath.TargetInfo.DesktopModeInfoIndex != DisplayConfigDesktopImageInfo.InvalidDesktopImageModeIndex) && (displayModes[displayPath.TargetInfo.DesktopModeInfoIndex].InfoType == DisplayConfigModeInfoType.DesktopImage)) { desktopImageMode = displayModes[displayPath.TargetInfo.DesktopModeInfoIndex].DesktopImageInfo; } pathInfos[key].Item3.Add( new Tuple <DisplayConfigPathInfoFlags, DisplayConfigPathTargetInfo, DisplayConfigTargetMode?, DisplayConfigDesktopImageInfo?>( displayPath.Flags, displayPath.TargetInfo, targetMode, desktopImageMode)); } return (pathInfos.Select(pair => new PathInfo(pair.Value.Item1, pair.Value.Item2, pair.Value.Item3)).ToArray()); }