mirror of
https://github.com/terrymacdonald/DisplayMagician.git
synced 2024-08-30 18:32:20 +00:00
[WIP] Creates different displayIdentifiers for NVIDIA or other
There are different displayIdentifiers created if the video card is an NVidia card, or if it is anything else. These identifiers are saved in the display profiles, and that allows us to compare the display identifiers we currently have with the ones in various profiles, and then work out which profiles are valid. This code committed today ensures that the nvidia device identifier will always use the NVAPIWrapper lib (whether in surround mode or not) so that the application allows both surround mode profiles and non-surround mode profiles to be selected if the same displays are present. For all other display adapters it just uses the WindowsDisplayAPI to create a different displayIdentifier which isn't as smart. It means that if you have an AMD and use EyeInfinity, then this isn't clever enough to understand the profiles use the same matching screens. I will have to fix this eventually when i build in native AMD support in the future.
This commit is contained in:
@ -227,7 +227,7 @@ namespace HeliosPlus.Shared.DisplayIdentification
|
||||
Console.WriteLine($"EDID-ProductYear:{edid.ProductYear}");
|
||||
Console.WriteLine($"EDID-SerialNumber:{edid.SerialNumber}");
|
||||
Console.WriteLine($"EDID-Timings:{edid.Timings}");
|
||||
Console.WriteLine($"EDID-AdapterDeviceKey:{ConnectedDisplay.Adapter.DeviceName}");
|
||||
Console.WriteLine($"EDID-AdapterDeviceKey:{ConnectedDisplay.Adapter.DeviceKey}");
|
||||
Console.WriteLine($"EDID-AdapterDeviceName:{ConnectedDisplay.Adapter.DeviceName}");
|
||||
Console.WriteLine($"EDID-AdapterDevicePath:{ConnectedDisplay.Adapter.DevicePath}");
|
||||
Console.WriteLine($"EDID-{ConnectedDisplay.Adapter.DevicePath}-{edid.ManufacturerId}-{edid.ProductCode}-{edid.SerialNumber}");
|
||||
|
@ -17,6 +17,7 @@ using System.Drawing.Imaging;
|
||||
using WindowsDisplayAPI;
|
||||
using System.Text.RegularExpressions;
|
||||
using HeliosPlus.Shared.DisplayIdentification;
|
||||
using NvAPIWrapper.Display;
|
||||
|
||||
namespace HeliosPlus.Shared
|
||||
{
|
||||
@ -26,8 +27,8 @@ namespace HeliosPlus.Shared
|
||||
private ProfileIcon _profileIcon;
|
||||
private Bitmap _profileBitmap, _profileShortcutBitmap;
|
||||
private List<string> _profileDisplayIdentifiers = new List<string>();
|
||||
private static List<Display> _availableDisplays;
|
||||
private static List<UnAttachedDisplay> _unavailableDisplays;
|
||||
private static List<WindowsDisplayAPI.Display> _availableDisplays;
|
||||
private static List<WindowsDisplayAPI.UnAttachedDisplay> _unavailableDisplays;
|
||||
|
||||
internal static string AppDataPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "HeliosPlus");
|
||||
|
||||
@ -258,10 +259,10 @@ namespace HeliosPlus.Shared
|
||||
*/
|
||||
|
||||
Console.WriteLine($"### All Unavailable Displays ###");
|
||||
List<UnAttachedDisplay> allDisconnectedDisplays = UnAttachedDisplay.GetUnAttachedDisplays().ToList();
|
||||
foreach (UnAttachedDisplay unavailableDisplay in allDisconnectedDisplays)
|
||||
List<WindowsDisplayAPI.UnAttachedDisplay> allDisconnectedDisplays = WindowsDisplayAPI.UnAttachedDisplay.GetUnAttachedDisplays().ToList();
|
||||
foreach (WindowsDisplayAPI.UnAttachedDisplay unavailableDisplay in allDisconnectedDisplays)
|
||||
{
|
||||
Console.WriteLine($"DevicePath: {unavailableDisplay.DeviceKey}");
|
||||
Console.WriteLine($"DevicePath: {unavailableDisplay.DevicePath}");
|
||||
Console.WriteLine($"DeviceKey: {unavailableDisplay.DeviceKey}");
|
||||
Console.WriteLine($"DeviceName: {unavailableDisplay.Adapter.DeviceName}");
|
||||
Console.WriteLine($"DisplayFullName: {unavailableDisplay.DisplayFullName}");
|
||||
@ -273,10 +274,10 @@ namespace HeliosPlus.Shared
|
||||
}
|
||||
|
||||
Console.WriteLine($"### All Available Displays ###");
|
||||
List<Display> allWindowsConnectedDisplays = Display.GetDisplays().ToList();
|
||||
foreach (Display availableDisplay in allWindowsConnectedDisplays)
|
||||
List<WindowsDisplayAPI.Display> allWindowsConnectedDisplays = WindowsDisplayAPI.Display.GetDisplays().ToList();
|
||||
foreach (WindowsDisplayAPI.Display availableDisplay in allWindowsConnectedDisplays)
|
||||
{
|
||||
Console.WriteLine($"DevicePath: {availableDisplay.DeviceKey}");
|
||||
Console.WriteLine($"DevicePath: {availableDisplay.DevicePath}");
|
||||
Console.WriteLine($"DeviceKey: {availableDisplay.DeviceKey}");
|
||||
Console.WriteLine($"DeviceName: {availableDisplay.Adapter.DeviceName}");
|
||||
Console.WriteLine($"DisplayFullName: {availableDisplay.DisplayFullName}");
|
||||
@ -289,8 +290,8 @@ namespace HeliosPlus.Shared
|
||||
|
||||
|
||||
|
||||
IEnumerable<Display> currentDisplays = Display.GetDisplays();
|
||||
foreach (Display availableDisplay in currentDisplays)
|
||||
IEnumerable<WindowsDisplayAPI.Display> currentDisplays = WindowsDisplayAPI.Display.GetDisplays();
|
||||
foreach (WindowsDisplayAPI.Display availableDisplay in currentDisplays)
|
||||
{
|
||||
Console.WriteLine($"DsiplayName: {availableDisplay.DisplayName}");
|
||||
if (availableDisplay.IsAvailable)
|
||||
@ -303,7 +304,7 @@ namespace HeliosPlus.Shared
|
||||
|
||||
foreach (ProfileViewport availableViewport in availableViewports)
|
||||
{
|
||||
PathInfo pathInfo = availableViewport.ToPathInfo();
|
||||
WindowsDisplayAPI.DisplayConfig.PathInfo pathInfo = availableViewport.ToPathInfo();
|
||||
//pathInfo.TargetsInfo;
|
||||
foreach (ProfileViewportTargetDisplay realTD in availableViewport.TargetDisplays)
|
||||
{
|
||||
@ -447,13 +448,13 @@ namespace HeliosPlus.Shared
|
||||
|
||||
public string SavedProfileIconCacheFilename { get; set; }
|
||||
|
||||
public List<string> ProfileDisplayIdentifiers
|
||||
public List<string> ProfileDisplayIdentifiers
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_profileDisplayIdentifiers.Count == 0)
|
||||
{
|
||||
_profileDisplayIdentifiers = DisplayIdentifier.GetCurrentDisplayIdentification();
|
||||
_profileDisplayIdentifiers = this.GenerateDisplayIdentifiers();
|
||||
}
|
||||
return _profileDisplayIdentifiers;
|
||||
}
|
||||
@ -543,6 +544,99 @@ namespace HeliosPlus.Shared
|
||||
return false;
|
||||
}
|
||||
|
||||
public List<string> GenerateDisplayIdentifiers()
|
||||
{
|
||||
List<string> displayIdentifiers = new List<string>();
|
||||
|
||||
// If the Video Card is an NVidia, then we should generate specific NVidia displayIdentifiers
|
||||
NvAPIWrapper.GPU.LogicalGPU[] myLogicalGPUs = NvAPIWrapper.GPU.LogicalGPU.GetLogicalGPUs();
|
||||
if (myLogicalGPUs.Length > 0)
|
||||
{
|
||||
|
||||
foreach (NvAPIWrapper.GPU.LogicalGPU myLogicalGPU in myLogicalGPUs)
|
||||
{
|
||||
NvAPIWrapper.GPU.PhysicalGPU[] myPhysicalGPUs = myLogicalGPU.CorrespondingPhysicalGPUs;
|
||||
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)
|
||||
{
|
||||
// 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
|
||||
string[] displayInfo = {
|
||||
"NVIDIA",
|
||||
myLogicalGPU.ToString(),
|
||||
myPhysicalGPU.ToString(),
|
||||
myPhysicalGPU.ArchitectInformation.ShortName.ToString(),
|
||||
myPhysicalGPU.ArchitectInformation.Revision.ToString(),
|
||||
myPhysicalGPU.Board.ToString(),
|
||||
myPhysicalGPU.Foundry.ToString(),
|
||||
myPhysicalGPU.GPUId.ToString(),
|
||||
myPhysicalGPU.GPUType.ToString(),
|
||||
aGPUOutput.OutputId.ToString(),
|
||||
aConnectedDisplayDevice.ConnectionType.ToString(),
|
||||
aConnectedDisplayDevice.DisplayId.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);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
// else videocard is not NVIdia so we just use the WindowsAPI access method
|
||||
// Note: This won't support any special AMD EyeFinity profiles unfortunately.....
|
||||
// TODO: Add the detection and generation of the device ids using an AMD library
|
||||
// so that we can match valid AMD Eyefinity profiles with valid AMD standard profiles.
|
||||
else
|
||||
{
|
||||
|
||||
// Then go through the displays in the profile and check they are made of displays
|
||||
// that currently are available.
|
||||
foreach (ProfileViewport profileViewport in Viewports)
|
||||
{
|
||||
// For each profile, we want to make sure all TargetDisplays.DevicePath are in the list of
|
||||
// availableDevicePaths
|
||||
//foreach (WindowsDisplayAPI.DisplayConfig.PathTargetInfo profilePathTargetInfo in profileViewport.ToPathInfo().TargetsInfo)
|
||||
foreach (ProfileViewportTargetDisplay profileTargetDisplay in profileViewport.TargetDisplays)
|
||||
{
|
||||
|
||||
|
||||
WindowsDisplayAPI.DisplayConfig.PathTargetInfo profilePathTargetInfo = profileTargetDisplay.ToPathTargetInfo();
|
||||
|
||||
// Create an array of all the important display info we need to record
|
||||
string[] displayInfo = {
|
||||
"WINAPI",
|
||||
profileViewport.SourceId.ToString(),
|
||||
profilePathTargetInfo.DisplayTarget.Adapter.AdapterId.HighPart.ToString(),
|
||||
profilePathTargetInfo.DisplayTarget.Adapter.AdapterId.LowPart.ToString(),
|
||||
profilePathTargetInfo.OutputTechnology.ToString(),
|
||||
profilePathTargetInfo.DisplayTarget.EDIDManufactureCode.ToString(),
|
||||
profilePathTargetInfo.DisplayTarget.FriendlyName,
|
||||
profilePathTargetInfo.DisplayTarget.EDIDManufactureId.ToString(),
|
||||
profilePathTargetInfo.DisplayTarget.EDIDProductCode.ToString(),
|
||||
profilePathTargetInfo.DisplayTarget.ConnectorInstance.ToString(),
|
||||
profileTargetDisplay.DevicePath,
|
||||
};
|
||||
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return displayIdentifiers;
|
||||
}
|
||||
|
||||
public bool CopyTo(ProfileItem profile, bool overwriteId = true)
|
||||
{
|
||||
if (!(profile is ProfileItem))
|
||||
@ -567,7 +661,7 @@ namespace HeliosPlus.Shared
|
||||
// Prepare our profile data for saving
|
||||
if (_profileDisplayIdentifiers.Count == 0)
|
||||
{
|
||||
_profileDisplayIdentifiers = DisplayIdentifier.GetCurrentDisplayIdentification();
|
||||
_profileDisplayIdentifiers = GenerateDisplayIdentifiers();
|
||||
}
|
||||
|
||||
// Return if it is valid and we should continue
|
||||
|
@ -356,12 +356,12 @@ namespace HeliosPlus.Shared
|
||||
ProfileItem activeProfile = new ProfileItem
|
||||
{
|
||||
Name = "Current Display Profile",
|
||||
Viewports = PathInfo.GetActivePaths().Select(info => new ProfileViewport(info)).ToArray(),
|
||||
ProfileIcon = new ProfileIcon(_currentProfile),
|
||||
ProfileBitmap = _currentProfile.ProfileIcon.ToBitmap(256, 256),
|
||||
ProfileDisplayIdentifiers = DisplayIdentifier.GetCurrentDisplayIdentification()
|
||||
Viewports = PathInfo.GetActivePaths().Select(info => new ProfileViewport(info)).ToArray()
|
||||
};
|
||||
|
||||
activeProfile.ProfileIcon = new ProfileIcon(activeProfile);
|
||||
activeProfile.ProfileBitmap = activeProfile.ProfileIcon.ToBitmap(256, 256);
|
||||
|
||||
if (_profilesLoaded && _allProfiles.Count > 0)
|
||||
{
|
||||
foreach (ProfileItem loadedProfile in ProfileRepository.AllProfiles)
|
||||
|
@ -157,9 +157,10 @@ namespace HeliosPlus.UIForms
|
||||
//_savedProfiles = ProfileRepository.AllProfiles;
|
||||
// Update the Current Profile
|
||||
//ProfileRepository.UpdateCurrentProfile();
|
||||
ProfileRepository.GetActiveProfile();
|
||||
// ProfileRepository.GetActiveProfile();
|
||||
// Change to the current selected Profile
|
||||
ChangeSelectedProfile(ProfileRepository.GetActiveProfile());
|
||||
|
||||
// Refresh the Profile UI
|
||||
RefreshDisplayProfileUI();
|
||||
}
|
||||
|
Reference in New Issue
Block a user