Added patch to convert v2.0.1 displaySource to list

This should help avoid a crash to desktop when using cloned displays. Partially fixes #47
This commit is contained in:
Terry MacDonald 2021-10-16 16:45:49 +13:00
parent d98372bf39
commit cf1ff873ef
5 changed files with 63 additions and 27 deletions

View File

@ -26,8 +26,8 @@ using System.Resources;
[assembly: Guid("e4ceaf5e-ad01-4695-b179-31168eb74c48")]
// Version information
[assembly: AssemblyVersion("2.0.1.129")]
[assembly: AssemblyFileVersion("2.0.1.129")]
[assembly: AssemblyVersion("2.0.1.149")]
[assembly: AssemblyFileVersion("2.0.1.149")]
[assembly: NeutralResourcesLanguageAttribute( "en" )]
[assembly: CLSCompliant(true)]

View File

@ -2399,7 +2399,7 @@ namespace DisplayMagician.UIForms
_gameLauncher = game.GameLibrary.ToString("G");
lbl_game_library.Text = $"Game Library: {_gameLauncher}";
_gameId = game.Id;
break;
}
}
}

View File

@ -973,7 +973,7 @@ namespace DisplayMagicianShared
{
uint displayId = _nvidiaDisplayConfig.MosaicConfig.MosaicGridTopos[i].Displays[0].DisplayId;
string windowsDisplayName = _nvidiaDisplayConfig.DisplayNames[displayId];
uint sourceIndex = _windowsDisplayConfig.DisplaySources[windowsDisplayName];
List<uint> sourceIndexes = _windowsDisplayConfig.DisplaySources[windowsDisplayName];
for (int x = 0; x < _windowsDisplayConfig.DisplayConfigModes.Length; x++)
{
// Skip this if its not a source info config type
@ -982,8 +982,8 @@ namespace DisplayMagicianShared
continue;
}
// If the source index matches the index of the source info object we're looking at, then process it!
if (_windowsDisplayConfig.DisplayConfigModes[x].Id == sourceIndex)
// If the source index matches the index of the source info object we're looking at, then process it!
if (sourceIndexes.Contains(_windowsDisplayConfig.DisplayConfigModes[x].Id))
{
screen.Name = displayId.ToString();

View File

@ -797,12 +797,11 @@ namespace DisplayMagicianShared
SharedLogger.logger.Error($"ProfileRepository/MigrateJsonToLatestVersion: Exception while trying to process the Profiles json data to migrate any older feature to the latest version.");
}
// Now we try and add a default NVIDIA Color Settings if there isn't one
// We do the change we wre trying to do
try
{
// Now we try and add a default NVIDIA Color Settings if there isn't one
SharedLogger.logger.Trace($"ProfileRepository/MigrateJsonToLatestVersion: Looking for missing NVIDIA Color Config.");
// Create a default object
NVIDIA_DISPLAY_CONFIG myDefaultConfig = new NVIDIA_DISPLAY_CONFIG();
myDefaultConfig.ColorConfig.ColorData = new Dictionary<uint, NV_COLOR_DATA_V5>();
@ -820,22 +819,10 @@ namespace DisplayMagicianShared
changedJson = true;
SharedLogger.logger.Trace($"ProfileRepository/MigrateJsonToLatestVersion: Patched missing NVIDIA Color Config in profile {profile.SelectToken("Name")} (index {i}).");
}
}
}
catch (JsonReaderException ex)
{
SharedLogger.logger.Error($"ProfileRepository/MigrateJsonToLatestVersion: JSONReaderException while trying to process the Profiles json data to migrate any older feature to the latest version.");
}
catch (Exception ex)
{
SharedLogger.logger.Error($"ProfileRepository/MigrateJsonToLatestVersion: Exception while trying to process the Profiles json data to migrate any older feature to the latest version.");
}
}
// Now we try and add a default Windows GDI Device Context if there isn't one
try
{
// Now we try to patch in a Windows GDI device context into the json if there isnt one
SharedLogger.logger.Trace($"ProfileRepository/MigrateJsonToLatestVersion: Looking for missing Windows GDI Device Context.");
// Create a default object
Dictionary<string, GDI_DISPLAY_SETTING> GdiDisplaySettings = new Dictionary<string, GDI_DISPLAY_SETTING>();
JObject defaultGdiDisplaySettings = (JObject)JToken.FromObject(GdiDisplaySettings);
@ -852,6 +839,41 @@ namespace DisplayMagicianShared
SharedLogger.logger.Trace($"ProfileRepository/MigrateJsonToLatestVersion: Patched missing Windows GDI Device Context in profile {profile.SelectToken("Name")} (index {i}).");
}
}
// Now we try to convert the individual sourceids into a list of source ids to cope with cloned devices
SharedLogger.logger.Trace($"ProfileRepository/MigrateJsonToLatestVersion: Looking for missing Windows GDI Device Context.");
// Create a default object
List<uint> WinDisplaySourcesList = new List<uint>();
//JObject WinDisplaySources = (JObject)JToken.FromObject(WinDisplaySourcesList);
for (int i = 0; i < root.Count; i++)
{
JObject profile = (JObject)root[i];
try
{
JObject WindowsDisplaySources = (JObject)profile.SelectToken("WindowsDisplayConfig.DisplaySources");
Dictionary<string, List<uint>> existingDisplaySources = WindowsDisplaySources.ToObject<Dictionary<string, List<uint>>>();
}
catch (Exception ex)
{
JObject WindowsDisplaySources = (JObject)profile.SelectToken("WindowsDisplayConfig.DisplaySources");
//foreach (var displaySource in WindowsDisplaySources.ToObject<Dictionary<string,uint>>())
Dictionary<string, uint> existingDisplaySources = WindowsDisplaySources.ToObject<Dictionary<string, uint>>();
Dictionary<string, List<uint>> newDisplaySources = new Dictionary<string, List<uint>>();
foreach (var sourceName in existingDisplaySources.Keys)
{
List<uint> newList = new List<uint>();
newList.Add((uint)existingDisplaySources[sourceName]);
newDisplaySources[sourceName] = newList;
}
JObject newSourcesDict = JObject.FromObject(newDisplaySources);
JToken WindowsDisplayConfig = (JToken)profile.SelectToken("WindowsDisplayConfig.DisplaySources");
WindowsDisplayConfig.Replace(newSourcesDict);
changedJson = true;
SharedLogger.logger.Trace($"ProfileRepository/MigrateJsonToLatestVersion: Patched missing Windows GDI Device Context in profile {profile.SelectToken("Name")} (index {i}).");
}
}
}
catch (JsonReaderException ex)
{

View File

@ -46,7 +46,7 @@ namespace DisplayMagicianShared.Windows
// Note: We purposely have left out the DisplaySources from the Equals as it's order keeps changing after each reboot and after each profile swap
// and it is informational only and doesn't contribute to the configuration (it's used for generating the Screens structure, and therefore for
// generating the profile icon.
public Dictionary<string, uint> DisplaySources;
public Dictionary<string, List<uint>> DisplaySources;
public List<string> DisplayIdentifiers;
public override bool Equals(object obj) => obj is WINDOWS_DISPLAY_CONFIG other && this.Equals(other);
@ -143,7 +143,7 @@ namespace DisplayMagicianShared.Windows
myDefaultConfig.DisplayConfigPaths = new DISPLAYCONFIG_PATH_INFO[0];
myDefaultConfig.DisplayHDRStates = new ADVANCED_HDR_INFO_PER_PATH[0];
myDefaultConfig.DisplayIdentifiers = new List<string>();
myDefaultConfig.DisplaySources = new Dictionary<string, uint>();
myDefaultConfig.DisplaySources = new Dictionary<string, List<uint>>();
myDefaultConfig.GdiDisplaySettings = new Dictionary<string, GDI_DISPLAY_SETTING>();
return myDefaultConfig;
@ -304,7 +304,7 @@ namespace DisplayMagicianShared.Windows
WINDOWS_DISPLAY_CONFIG windowsDisplayConfig = new WINDOWS_DISPLAY_CONFIG();
windowsDisplayConfig.DisplayAdapters = new Dictionary<ulong, string>();
windowsDisplayConfig.DisplayHDRStates = new ADVANCED_HDR_INFO_PER_PATH[pathCount];
windowsDisplayConfig.DisplaySources = new Dictionary<string, uint>();
windowsDisplayConfig.DisplaySources = new Dictionary<string, List<uint>>();
// Now cycle through the paths and grab the HDR state information
// and map the adapter name to adapter id
@ -322,7 +322,21 @@ namespace DisplayMagicianShared.Windows
if (err == WIN32STATUS.ERROR_SUCCESS)
{
// Store it for later
windowsDisplayConfig.DisplaySources.Add(sourceInfo.ViewGdiDeviceName, path.SourceInfo.Id);
if (windowsDisplayConfig.DisplaySources.ContainsKey(sourceInfo.ViewGdiDeviceName))
{
// We already have at least one display using this source, so we need to add the other cloned display to the existing list
List<uint> sourceIds = windowsDisplayConfig.DisplaySources[sourceInfo.ViewGdiDeviceName];
sourceIds.Add(path.SourceInfo.Id);
windowsDisplayConfig.DisplaySources.Add(sourceInfo.ViewGdiDeviceName, sourceIds);
}
else
{
// This is the first display to use this source
List<uint> sourceIds = new List<uint>();
sourceIds.Add(path.SourceInfo.Id);
windowsDisplayConfig.DisplaySources.Add(sourceInfo.ViewGdiDeviceName, sourceIds);
}
SharedLogger.logger.Trace($"WinLibrary/GetWindowsDisplayConfig: Found Display Source {sourceInfo.ViewGdiDeviceName} for source {path.SourceInfo.Id}.");
}
else