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")] [assembly: Guid("e4ceaf5e-ad01-4695-b179-31168eb74c48")]
// Version information // Version information
[assembly: AssemblyVersion("2.0.1.129")] [assembly: AssemblyVersion("2.0.1.149")]
[assembly: AssemblyFileVersion("2.0.1.129")] [assembly: AssemblyFileVersion("2.0.1.149")]
[assembly: NeutralResourcesLanguageAttribute( "en" )] [assembly: NeutralResourcesLanguageAttribute( "en" )]
[assembly: CLSCompliant(true)] [assembly: CLSCompliant(true)]

View File

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

View File

@ -973,7 +973,7 @@ namespace DisplayMagicianShared
{ {
uint displayId = _nvidiaDisplayConfig.MosaicConfig.MosaicGridTopos[i].Displays[0].DisplayId; uint displayId = _nvidiaDisplayConfig.MosaicConfig.MosaicGridTopos[i].Displays[0].DisplayId;
string windowsDisplayName = _nvidiaDisplayConfig.DisplayNames[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++) for (int x = 0; x < _windowsDisplayConfig.DisplayConfigModes.Length; x++)
{ {
// Skip this if its not a source info config type // Skip this if its not a source info config type
@ -982,8 +982,8 @@ namespace DisplayMagicianShared
continue; continue;
} }
// If the source index matches the index of the source info object we're looking at, then process it! // 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 (sourceIndexes.Contains(_windowsDisplayConfig.DisplayConfigModes[x].Id))
{ {
screen.Name = displayId.ToString(); 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."); SharedLogger.logger.Error($"ProfileRepository/MigrateJsonToLatestVersion: Exception while trying to process the Profiles json data to migrate any older feature to the latest version.");
} }
// We do the change we wre trying to do
// Now we try and add a default NVIDIA Color Settings if there isn't one
try 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."); SharedLogger.logger.Trace($"ProfileRepository/MigrateJsonToLatestVersion: Looking for missing NVIDIA Color Config.");
// Create a default object // Create a default object
NVIDIA_DISPLAY_CONFIG myDefaultConfig = new NVIDIA_DISPLAY_CONFIG(); NVIDIA_DISPLAY_CONFIG myDefaultConfig = new NVIDIA_DISPLAY_CONFIG();
myDefaultConfig.ColorConfig.ColorData = new Dictionary<uint, NV_COLOR_DATA_V5>(); myDefaultConfig.ColorConfig.ColorData = new Dictionary<uint, NV_COLOR_DATA_V5>();
@ -820,22 +819,10 @@ namespace DisplayMagicianShared
changedJson = true; changedJson = true;
SharedLogger.logger.Trace($"ProfileRepository/MigrateJsonToLatestVersion: Patched missing NVIDIA Color Config in profile {profile.SelectToken("Name")} (index {i})."); 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 // Now we try to patch in a Windows GDI device context into the json if there isnt one
try
{
SharedLogger.logger.Trace($"ProfileRepository/MigrateJsonToLatestVersion: Looking for missing Windows GDI Device Context."); SharedLogger.logger.Trace($"ProfileRepository/MigrateJsonToLatestVersion: Looking for missing Windows GDI Device Context.");
// Create a default object // Create a default object
Dictionary<string, GDI_DISPLAY_SETTING> GdiDisplaySettings = new Dictionary<string, GDI_DISPLAY_SETTING>(); Dictionary<string, GDI_DISPLAY_SETTING> GdiDisplaySettings = new Dictionary<string, GDI_DISPLAY_SETTING>();
JObject defaultGdiDisplaySettings = (JObject)JToken.FromObject(GdiDisplaySettings); 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})."); 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) 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 // 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 // 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. // generating the profile icon.
public Dictionary<string, uint> DisplaySources; public Dictionary<string, List<uint>> DisplaySources;
public List<string> DisplayIdentifiers; public List<string> DisplayIdentifiers;
public override bool Equals(object obj) => obj is WINDOWS_DISPLAY_CONFIG other && this.Equals(other); 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.DisplayConfigPaths = new DISPLAYCONFIG_PATH_INFO[0];
myDefaultConfig.DisplayHDRStates = new ADVANCED_HDR_INFO_PER_PATH[0]; myDefaultConfig.DisplayHDRStates = new ADVANCED_HDR_INFO_PER_PATH[0];
myDefaultConfig.DisplayIdentifiers = new List<string>(); 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>(); myDefaultConfig.GdiDisplaySettings = new Dictionary<string, GDI_DISPLAY_SETTING>();
return myDefaultConfig; return myDefaultConfig;
@ -304,7 +304,7 @@ namespace DisplayMagicianShared.Windows
WINDOWS_DISPLAY_CONFIG windowsDisplayConfig = new WINDOWS_DISPLAY_CONFIG(); WINDOWS_DISPLAY_CONFIG windowsDisplayConfig = new WINDOWS_DISPLAY_CONFIG();
windowsDisplayConfig.DisplayAdapters = new Dictionary<ulong, string>(); windowsDisplayConfig.DisplayAdapters = new Dictionary<ulong, string>();
windowsDisplayConfig.DisplayHDRStates = new ADVANCED_HDR_INFO_PER_PATH[pathCount]; 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 // Now cycle through the paths and grab the HDR state information
// and map the adapter name to adapter id // and map the adapter name to adapter id
@ -322,7 +322,21 @@ namespace DisplayMagicianShared.Windows
if (err == WIN32STATUS.ERROR_SUCCESS) if (err == WIN32STATUS.ERROR_SUCCESS)
{ {
// Store it for later // 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}."); SharedLogger.logger.Trace($"WinLibrary/GetWindowsDisplayConfig: Found Display Source {sourceInfo.ViewGdiDeviceName} for source {path.SourceInfo.Id}.");
} }
else else