diff --git a/HeliosDisplayManagement.Shared/Profile.cs b/HeliosDisplayManagement.Shared/Profile.cs index c51de19..5924f07 100644 --- a/HeliosDisplayManagement.Shared/Profile.cs +++ b/HeliosDisplayManagement.Shared/Profile.cs @@ -9,6 +9,7 @@ using System.Windows.Forms; using WindowsDisplayAPI.DisplayConfig; using HeliosPlus.Shared.Resources; using Newtonsoft.Json; +//using NvAPIWrapper.Display; using NvAPIWrapper.GPU; using NvAPIWrapper.Mosaic; using NvAPIWrapper.Native.Mosaic; @@ -16,17 +17,20 @@ using HeliosPlus.Shared.Topology; using System.Drawing; using System.Drawing.Imaging; using WindowsDisplayAPI; +using WindowsDisplayAPI.DisplayConfig; +using WindowsDisplayAPI.Native.DisplayConfig; using System.Text.RegularExpressions; namespace HeliosPlus.Shared { - public class Profile : IEquatable + public class Profile { private static Profile _currentProfile; private static List _allSavedProfiles = new List(); private ProfileIcon _profileIcon; private Bitmap _profileBitmap; private static List _availableDisplays; + private static List _unavailableDisplays; internal static string AppDataPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "HeliosPlus"); @@ -122,8 +126,10 @@ namespace HeliosPlus.Shared get { - // Firstly check which displays are attached to this computer - _availableDisplays = Display.GetDisplays().ToList(); + + // Firstly check which displays are attached to this computer and are on +/* _availableDisplays = Display.GetDisplays().ToList(); + _unavailableDisplays = UnAttachedDisplay.GetUnAttachedDisplays().ToList(); // DevicePath "\\\\?\\DISPLAY#DELD065#5&38860457&0&UID4609#{e6f07b5f-ee97-4a90-b076-33f57bf4eaa7}" List availableDevicePath = new List(); foreach (Display aDisplay in _availableDisplays) @@ -136,40 +142,41 @@ namespace HeliosPlus.Shared availableDevicePath.Add(devicePathMatches.Groups[1].Value.ToString()); } } - - if (availableDevicePath.Count > 0) +*/ + /* if (availableDevicePath.Count > 0) { - - int profileDisplaysCount = 0; - int profileDisplaysFoundCount = 0; - // Then go through the displays in the profile and check they're live - foreach (ProfileViewport profileViewport in Viewports) +*/ + List unavailableDeviceNames = new List(); + // Then go through the displays in the profile and check they're live + foreach (ProfileViewport profileViewport in Viewports) + { + foreach (ProfileViewportTargetDisplay profileViewportTargetDisplay in profileViewport.TargetDisplays) { - foreach (ProfileViewportTargetDisplay profileViewportTargetDisplay in profileViewport.TargetDisplays) - { - profileDisplaysCount++; - if (profileViewportTargetDisplay.DevicePath.Equals(availableDevicePath)); - profileDisplaysFoundCount++; - } - } - - if (profileDisplaysCount == profileDisplaysFoundCount) - { - // If we found all our profile displays in the available displays! - return true; - } - else - { - return false; + PathTargetInfo viewportTargetInfo = profileViewportTargetDisplay.ToPathTargetInfo(); + bool isAvailable = viewportTargetInfo.DisplayTarget != null ? viewportTargetInfo.DisplayTarget.IsAvailable : false; + if (!viewportTargetInfo.DisplayTarget.IsAvailable) + unavailableDeviceNames.Add(profileViewportTargetDisplay.DisplayName); } } + + if (unavailableDeviceNames.Count > 0) + { + // Darn - there was at least one unavilable displaytarget + return false; + } + else + { + // There were no unavailable DisplayTargets! + return true; + } +/* } else { return false; } +*/ - - // This should include the ones not currently enabled. +/* // This should include the ones not currently enabled. var displayAdapters = DisplayAdapter.GetDisplayAdapters().ToArray(); var displays = Display.GetDisplays().ToArray(); @@ -178,7 +185,13 @@ namespace HeliosPlus.Shared var displayDevices = physicalGPUs[0].GetDisplayDevices().ToArray(); return true; - /*var surroundTopologies = + + GridTopology.ValidateGridTopologies( + SurroundTopologies.Select(topology => topology.ToGridTopology()).ToArray(), + SetDisplayTopologyFlag.MaximizePerformance); + + // Check if we are using NVIDIA surround in this profile + var surroundTopologies = Viewports.SelectMany(path => path.TargetDisplays) .Select(target => target.SurroundTopology) .Where(topology => topology != null).ToArray(); @@ -296,66 +309,6 @@ namespace HeliosPlus.Shared } - /// - public bool Equals(Profile other) - { - //if the other profile points to null, it's not equal - if (ReferenceEquals(null, other)) - { - return false; - } - - //if the other profile is the same object, it's equal - if (ReferenceEquals(this, other)) - { - return true; - } - - //return Paths.All(path => other.Paths.Contains(path)); - if (Viewports.Length != other.Viewports.Length) - { - return false; - } - - int thisToOtherViewportCount = 0; - int otherToThisViewportCount = 0; - - foreach (ProfileViewport myProfileViewport in Viewports) - { - foreach (ProfileViewport otherProfileViewport in other.Viewports) - { - if (myProfileViewport.Equals(otherProfileViewport)) - { - thisToOtherViewportCount++; - } - } - - } - - foreach (ProfileViewport otherProfileViewport in other.Viewports) - { - foreach (ProfileViewport myProfileViewport in Viewports) - { - if (myProfileViewport.Equals(otherProfileViewport)) - { - otherToThisViewportCount++; - } - } - - } - - if (thisToOtherViewportCount == otherToThisViewportCount) - { - return true; - } - else - { - return false; - } - - return false; - } - public static IEnumerable LoadAllProfiles() { @@ -402,7 +355,7 @@ namespace HeliosPlus.Shared loadedProfile.ProfileIcon = new ProfileIcon(loadedProfile); loadedProfile.ProfileBitmap = loadedProfile.ProfileIcon.ToBitmap(128,128); - if (loadedProfile.Equals(myCurrentProfile)) { + if (loadedProfile.IsActive) { _currentProfile = loadedProfile; } @@ -433,18 +386,6 @@ namespace HeliosPlus.Shared return _allSavedProfiles; } - - - public static bool operator ==(Profile left, Profile right) - { - return Equals(left, right) || left?.Equals(right) == true; - } - - public static bool operator !=(Profile left, Profile right) - { - return !(left == right); - } - public static bool IsValidName(string testName) { foreach (Profile loadedProfile in _allSavedProfiles) @@ -474,7 +415,11 @@ namespace HeliosPlus.Shared public static void RefreshActiveStatus() { - //_currentProfile = null; + _currentProfile = new Profile + { + Name = "Current Display Profile", + Viewports = PathInfo.GetActivePaths().Select(info => new ProfileViewport(info)).ToArray() + }; } public static bool SaveAllProfiles() @@ -541,37 +486,53 @@ namespace HeliosPlus.Shared return false; } - /// + + // The public override for the Object.Equals public override bool Equals(object obj) { - if (ReferenceEquals(null, obj)) - { - return false; - } - - if (ReferenceEquals(this, obj)) - { - return true; - } - - if (obj.GetType() != GetType()) - { - return false; - } - - return Equals((Profile) obj); + return this.Equals(obj as Profile); } - /// + // Profiles are equal if their contents (except name) are equal + public bool Equals(Profile other) + { + + // If parameter is null, return false. + if (Object.ReferenceEquals(other, null)) + return false; + + // Optimization for a common success case. + if (Object.ReferenceEquals(this, other)) + return true; + + // If run-time types are not exactly the same, return false. + if (this.GetType() != other.GetType()) + return false; + + // Check whether the profiles' properties are equal + // We need to exclude the name as the name is solely for saving to disk + // and displaying to the user. + // Two profiles are equal only when they have the same viewport data + if (Viewports.Equals(other.Viewports)) + return true; + else + return false; + } + + // If Equals() returns true for this object compared to another + // then GetHashCode() must return the same value for these objects. public override int GetHashCode() { - unchecked - { - return (Viewports?.GetHashCode() ?? 0) * 397; - } + + // Get hash code for the Viewports field if it is not null. + int hashViewports = Viewports == null ? 0 : Viewports.GetHashCode(); + + //Calculate the hash code for the product. + return hashViewports; + } - /// + public override string ToString() { return (Name ?? Language.UN_TITLED_PROFILE) + (IsActive ? " " + Language._Active_ : ""); @@ -606,10 +567,12 @@ namespace HeliosPlus.Shared { try { + // Wait 20 seconds Thread.Sleep(2000); try { + // Get an array of the valid NVIDAI surround topologies var surroundTopologies = Viewports.SelectMany(path => path.TargetDisplays) .Select(target => target.SurroundTopology) @@ -617,8 +580,11 @@ namespace HeliosPlus.Shared .Select(topology => topology.ToGridTopology()) .ToArray(); + // See if we have any surroundTopologies specified! if (surroundTopologies.Length == 0) { + // if we do not have surroundTopopligies specified then + // Figure out how to lay out the standard windows displays var currentTopologies = GridTopology.GetGridTopologies(); if (currentTopologies.Any(topology => topology.Rows * topology.Columns > 1)) @@ -629,10 +595,11 @@ namespace HeliosPlus.Shared .Select(displays => new GridTopology(1, 1, new[] {displays})) .ToArray(); } - } - - if (surroundTopologies.Length > 0) + } + else { + // if we DO have surroundTopopligies specified then + // Figure out how to turn them on GridTopology.SetGridTopologies(surroundTopologies, SetDisplayTopologyFlag.MaximizePerformance); } } @@ -641,17 +608,25 @@ namespace HeliosPlus.Shared // ignored } + // Wait 18 seconds Thread.Sleep(18000); - var pathInfos = Viewports.Select(path => path.ToPathInfo()).Where(info => info != null).ToArray(); - if (!pathInfos.Any()) + // Check to see what Viewports we have enabled + var ViewportsPathInfo = Viewports.Select(path => path.ToPathInfo()).Where(info => info != null).ToArray(); + + // If we don't have any + if (!ViewportsPathInfo.Any()) { throw new InvalidOperationException( @"Display configuration changed since this profile is created. Please re-create this profile."); } - PathInfo.ApplyPathInfos(pathInfos, true, true, true); + // Apply the new screen configuration + PathInfo.ApplyPathInfos(ViewportsPathInfo, true, true, true); + // Wait 10 seconds Thread.Sleep(10000); + + // Check o see what our current screen profile is now! RefreshActiveStatus(); return true; @@ -665,21 +640,48 @@ namespace HeliosPlus.Shared } } - public Profile Clone() + } + + // Custom comparer for the Profile class + // Allows us to use 'Contains' + class ProfileComparer : IEqualityComparer + { + // Products are equal if their names and product numbers are equal. + public bool Equals(Profile x, Profile y) { - try - { - var serialized = JsonConvert.SerializeObject(this); - var cloned = JsonConvert.DeserializeObject(serialized); - cloned.Id = Guid.NewGuid().ToString("B"); + //Check whether the compared objects reference the same data. + if (Object.ReferenceEquals(x, y)) return true; - return cloned; - } - catch - { - return null; - } + //Check whether any of the compared objects is null. + if (Object.ReferenceEquals(x, null) || Object.ReferenceEquals(y, null)) + return false; + + // Check whether the profiles' properties are equal + // We need to exclude the name as the name is solely for saving to disk + // and displaying to the user. + // Two profiles are equal only when they have the same viewport data + if (x.Viewports.Equals(y.Viewports)) + return true; + else + return false; } + + // If Equals() returns true for a pair of objects + // then GetHashCode() must return the same value for these objects. + public int GetHashCode(Profile profile) + { + + // Check whether the object is null + if (Object.ReferenceEquals(profile, null)) return 0; + + // Get hash code for the Viewports field if it is not null. + int hashViewports = profile.Viewports == null ? 0 : profile.Viewports.GetHashCode(); + + //Calculate the hash code for the product. + return hashViewports; + + } + } } \ No newline at end of file diff --git a/HeliosDisplayManagement.Shared/Topology/ProfileViewport.cs b/HeliosDisplayManagement.Shared/Topology/ProfileViewport.cs index b2c16a9..a1eb4d5 100644 --- a/HeliosDisplayManagement.Shared/Topology/ProfileViewport.cs +++ b/HeliosDisplayManagement.Shared/Topology/ProfileViewport.cs @@ -5,10 +5,11 @@ using WindowsDisplayAPI.DisplayConfig; using WindowsDisplayAPI.Native.DisplayConfig; using Newtonsoft.Json; using Newtonsoft.Json.Converters; +using System.Collections.Generic; namespace HeliosPlus.Shared.Topology { - public class ProfileViewport : IEquatable + public class ProfileViewport { public ProfileViewport(PathInfo pathInfo) { @@ -34,116 +35,6 @@ namespace HeliosPlus.Shared.Topology public ProfileViewportTargetDisplay[] TargetDisplays { get; set; } - /// - public bool Equals(ProfileViewport other) - { - if (ReferenceEquals(null, other)) - { - return false; - } - - if (ReferenceEquals(this, other)) - { - return true; - } - - if (PixelFormat == other.PixelFormat && - Position.Equals(other.Position) && - Resolution.Equals(other.Resolution) && - TargetDisplays.Length == other.TargetDisplays.Length) - { - // TODO fix this so it checks for exact match - - //TargetDisplays.All(target => other.TargetDisplays.Contains(target)); - int thisToOtherTargetDisplayCount = 0; - int otherToThisTargetDisplayCount = 0; - - foreach (ProfileViewportTargetDisplay myProfileViewportTargetDisplay in TargetDisplays) - { - foreach (ProfileViewportTargetDisplay otherProfileViewportTargetDisplay in other.TargetDisplays) - { - if (myProfileViewportTargetDisplay.Equals(otherProfileViewportTargetDisplay)) - { - thisToOtherTargetDisplayCount++; - } - } - - } - - foreach (ProfileViewportTargetDisplay otherProfileViewportTargetDisplay in other.TargetDisplays) - { - foreach (ProfileViewportTargetDisplay myProfileViewportTargetDisplay in TargetDisplays) - { - if (otherProfileViewportTargetDisplay.Equals(myProfileViewportTargetDisplay)) - { - otherToThisTargetDisplayCount++; - } - } - - } - - if (thisToOtherTargetDisplayCount == otherToThisTargetDisplayCount) - { - return true; - } - else - { - return false; - } - } - else - { - return false; - } - - } - - public static bool operator ==(ProfileViewport left, ProfileViewport right) - { - return Equals(left, right) || left?.Equals(right) == true; - } - - public static bool operator !=(ProfileViewport left, ProfileViewport right) - { - return !(left == right); - } - - /// - public override bool Equals(object obj) - { - if (ReferenceEquals(null, obj)) - { - return false; - } - - if (ReferenceEquals(this, obj)) - { - return true; - } - - if (obj.GetType() != GetType()) - { - return false; - } - - return Equals((ProfileViewport) obj); - } - - /// - public override int GetHashCode() - { - unchecked - { - var hashCode = (int) PixelFormat; - hashCode = (hashCode * 397) ^ Position.GetHashCode(); - hashCode = (hashCode * 397) ^ Resolution.GetHashCode(); - hashCode = (hashCode * 397) ^ (TargetDisplays?.GetHashCode() ?? 0); - - return hashCode; - } - } - - /// public override string ToString() { return $"\\\\.\\DISPLAY{SourceId}"; @@ -161,5 +52,130 @@ namespace HeliosPlus.Shared.Topology return null; } + + // The public override for the Object.Equals + public override bool Equals(object obj) + { + return this.Equals(obj as ProfileViewport); + } + + // Profiles are equal if their contents (except name) are equal + public bool Equals(ProfileViewport other) + { + + // If parameter is null, return false. + if (Object.ReferenceEquals(other, null)) + return false; + + // Optimization for a common success case. + if (Object.ReferenceEquals(this, other)) + return true; + + // If run-time types are not exactly the same, return false. + if (this.GetType() != other.GetType()) + return false; + + // Check whether the Profile Viewport properties are equal + // Two profiles are equal only when they have the same viewport data exactly + if (PixelFormat == other.PixelFormat && + Position.Equals(other.Position) && + Resolution.Equals(other.Resolution) && + SourceId == other.SourceId) + { + // If the above all match, then we need to check the DisplayTargets + foreach (ProfileViewportTargetDisplay targetDisplay in TargetDisplays) + { + if (!other.TargetDisplays.Contains(targetDisplay)) + return false; + } + return true; + } + else + return false; + } + + // If Equals() returns true for this object compared to another + // then GetHashCode() must return the same value for these objects. + public override int GetHashCode() + { + // Get hash code for the PixelFormat field if it is not null. + int hashPixelFormat = PixelFormat.GetHashCode(); + + // Get hash code for the Position field if it is not null. + int hashPosition = Position == null ? 0 : Position.GetHashCode(); + + // Get hash code for the Resolution field if it is not null. + int hashResolution = Resolution == null ? 0 : Resolution.GetHashCode(); + + // Get hash code for the SourceId field if it is not null. + int hashSourceId = SourceId.GetHashCode(); + + // Get hash code for the TargetDisplays field if it is not null. + int hashTargetDisplays = TargetDisplays == null ? 0 : TargetDisplays.GetHashCode(); + + //Calculate the hash code for the product. + return hashPixelFormat ^ hashPosition ^ hashResolution ^ hashSourceId ^ hashTargetDisplays; + } + } + + // Custom comparer for the ProfileViewport class + class ProfileViewportComparer : IEqualityComparer + { + // Products are equal if their names and product numbers are equal. + public bool Equals(ProfileViewport x, ProfileViewport y) + { + + //Check whether the compared objects reference the same data. + if (Object.ReferenceEquals(x, y)) return true; + + //Check whether any of the compared objects is null. + if (Object.ReferenceEquals(x, null) || Object.ReferenceEquals(y, null)) + return false; + + // Check whether the Profile Viewport properties are equal + // Two profiles are equal only when they have the same viewport data exactly + if (x.PixelFormat == y.PixelFormat && + x.Position.Equals(y.Position) && + x.Resolution.Equals(y.Resolution) && + x.SourceId == y.SourceId) + { + // If the above all match, then we need to check the DisplayTargets + foreach (ProfileViewportTargetDisplay xTargetDisplay in x.TargetDisplays) + { + if (!y.TargetDisplays.Contains(xTargetDisplay)) + return false; + } + return true; + } + else + return false; + } + + // If Equals() returns true for a pair of objects + // then GetHashCode() must return the same value for these objects. + public int GetHashCode(ProfileViewport profileViewport) + { + // Check whether the object is null + if (Object.ReferenceEquals(profileViewport, null)) return 0; + + // Get hash code for the PixelFormat field if it is not null. + int hashPixelFormat = profileViewport.PixelFormat.GetHashCode(); + + // Get hash code for the Position field if it is not null. + int hashPosition = profileViewport.Position == null ? 0 : profileViewport.Position.GetHashCode(); + + // Get hash code for the Resolution field if it is not null. + int hashResolution = profileViewport.Resolution == null ? 0 : profileViewport.Resolution.GetHashCode(); + + // Get hash code for the SourceId field if it is not null. + int hashSourceId = profileViewport.SourceId.GetHashCode(); + + // Get hash code for the TargetDisplays field if it is not null. + int hashTargetDisplays = profileViewport.TargetDisplays == null ? 0 : profileViewport.TargetDisplays.GetHashCode(); + + //Calculate the hash code for the product. + return hashPixelFormat ^ hashPosition ^ hashResolution ^ hashSourceId ^ hashTargetDisplays; + } + } } \ No newline at end of file diff --git a/HeliosDisplayManagement.Shared/Topology/ProfileViewportTargetDisplay.cs b/HeliosDisplayManagement.Shared/Topology/ProfileViewportTargetDisplay.cs index a030047..c4bf802 100644 --- a/HeliosDisplayManagement.Shared/Topology/ProfileViewportTargetDisplay.cs +++ b/HeliosDisplayManagement.Shared/Topology/ProfileViewportTargetDisplay.cs @@ -4,6 +4,7 @@ using WindowsDisplayAPI.DisplayConfig; using HeliosPlus.Shared.NVIDIA; using Newtonsoft.Json; using Newtonsoft.Json.Converters; +using System.Collections.Generic; namespace HeliosPlus.Shared.Topology { @@ -58,99 +59,6 @@ namespace HeliosPlus.Shared.Topology public SurroundTopology SurroundTopology { get; set; } - /// - public bool Equals(ProfileViewportTargetDisplay other) - { - if (ReferenceEquals(null, other)) - { - return false; - } - - if (ReferenceEquals(this, other)) - { - return true; - } - - if (FrequencyInMillihertz.Equals(other.FrequencyInMillihertz) && - Rotation.Equals(other.Rotation) && - Scaling.Equals(other.Scaling) && - ScanLineOrdering.Equals(other.ScanLineOrdering) && - DevicePath.Equals(other.DevicePath)) - { - if (SurroundTopology == null) - { - if (other.SurroundTopology == null) - { - return true; - } - else - { - return false; - } - } - else - { - if (other.SurroundTopology == null) - { - return false; - } - else - { - return SurroundTopology.Equals(other.SurroundTopology); - } - } - } - - return false; - } - - public static bool operator ==(ProfileViewportTargetDisplay left, ProfileViewportTargetDisplay right) - { - return Equals(left, right) || left?.Equals(right) == true; - } - - public static bool operator !=(ProfileViewportTargetDisplay left, ProfileViewportTargetDisplay right) - { - return !(left == right); - } - - /// - public override bool Equals(object obj) - { - if (ReferenceEquals(null, obj)) - { - return false; - } - - if (ReferenceEquals(this, obj)) - { - return true; - } - - if (obj.GetType() != GetType()) - { - return false; - } - - return Equals((ProfileViewportTargetDisplay) obj); - } - - /// - public override int GetHashCode() - { - unchecked - { - var hashCode = FrequencyInMillihertz.GetHashCode(); - hashCode = (hashCode * 397) ^ (int) Rotation; - hashCode = (hashCode * 397) ^ (int) Scaling; - hashCode = (hashCode * 397) ^ (int) ScanLineOrdering; - hashCode = (hashCode * 397) ^ DevicePath.GetHashCode(); - hashCode = (hashCode * 397) ^ SurroundTopology?.GetHashCode() ?? 0; - - return hashCode; - } - } - /// public override string ToString() { @@ -175,5 +83,157 @@ namespace HeliosPlus.Shared.Topology FrequencyInMillihertz, ScanLineOrdering.ToDisplayConfigScanLineOrdering(), Rotation.ToDisplayConfigRotation(), Scaling.ToDisplayConfigScaling()); } + + // The public override for the Object.Equals + public override bool Equals(object obj) + { + return this.Equals(obj as ProfileViewportTargetDisplay); + } + + // Profiles are equal if their contents (except name) are equal + public bool Equals(ProfileViewportTargetDisplay other) + { + + // If parameter is null, return false. + if (Object.ReferenceEquals(other, null)) + return false; + + // Optimization for a common success case. + if (Object.ReferenceEquals(this, other)) + return true; + + // If run-time types are not exactly the same, return false. + if (this.GetType() != other.GetType()) + return false; + + // Check whether the Profile Viewport properties are equal + // Two profiles are equal only when they have the same viewport data exactly + if (FrequencyInMillihertz == other.FrequencyInMillihertz && + Rotation.Equals(other.Rotation) && + Scaling.Equals(other.Scaling) && + ScanLineOrdering.Equals(other.ScanLineOrdering) && + DisplayName.Equals(other.DisplayName) && + DevicePath.Equals(other.DevicePath)) + { + // If the above all match, then we need to check the SurroundTopology matches + if (SurroundTopology == null && other.SurroundTopology == null) + return true; + else if (SurroundTopology != null && other.SurroundTopology == null) + return false; + else if (SurroundTopology == null && other.SurroundTopology != null) + return false; + else if (SurroundTopology.Equals(other.SurroundTopology)) + return true; + + return false; + } + else + return false; + } + + // If Equals() returns true for this object compared to another + // then GetHashCode() must return the same value for these objects. + public override int GetHashCode() + { + // Get hash code for the FrequencyInMillihertz field if it is not null. + int hashFrequencyInMillihertz = FrequencyInMillihertz.GetHashCode(); + + // Get hash code for the Position field if it is not null. + int hashRotation = Rotation.GetHashCode(); + + // Get hash code for the Scaling field if it is not null. + int hashScaling = Scaling.GetHashCode(); + + // Get hash code for the ScanLineOrdering field if it is not null. + int hashScanLineOrdering = ScanLineOrdering.GetHashCode(); + + // Get hash code for the hashDisplayName field if it is not null. + int hashDisplayName = DisplayName == null ? 0 : DisplayName.GetHashCode(); + + // Get hash code for the DevicePath field if it is not null. + int hashDevicePath = DevicePath == null ? 0 : DevicePath.GetHashCode(); + + // Get hash code for the SurroundTopology field if it is not null. + int hashSurroundTopology = SurroundTopology == null ? 0 : SurroundTopology.GetHashCode(); + + //Calculate the hash code for the product. + return hashFrequencyInMillihertz ^ hashRotation ^ hashScaling ^ hashScanLineOrdering ^ + hashDisplayName ^ hashDevicePath ^ hashSurroundTopology; + } + + } + + // Custom comparer for the ProfileViewportTargetDisplay class + class ProfileViewportTargetDisplayComparer : IEqualityComparer + { + // Products are equal if their names and product numbers are equal. + public bool Equals(ProfileViewportTargetDisplay x, ProfileViewportTargetDisplay y) + { + + //Check whether the compared objects reference the same data. + if (Object.ReferenceEquals(x, y)) return true; + + //Check whether any of the compared objects is null. + if (Object.ReferenceEquals(x, null) || Object.ReferenceEquals(y, null)) + return false; + + // Check whether the Profile Viewport properties are equal + // Two profiles are equal only when they have the same viewport data exactly + if (x.FrequencyInMillihertz == y.FrequencyInMillihertz && + x.Rotation.Equals(y.Rotation) && + x.Scaling.Equals(y.Scaling) && + x.ScanLineOrdering.Equals(y.ScanLineOrdering) && + x.DisplayName.Equals(y.DisplayName) && + x.DevicePath.Equals(y.DevicePath)) + { + // If the above all match, then we need to check the SurroundTopology matches + if (x.SurroundTopology == null && y.SurroundTopology == null) + return true; + else if (x.SurroundTopology != null && y.SurroundTopology == null) + return false; + else if (x.SurroundTopology == null && y.SurroundTopology != null) + return false; + else if (x.SurroundTopology.Equals(y.SurroundTopology)) + return true; + + return false; + } + else + return false; + } + + // If Equals() returns true for a pair of objects + // then GetHashCode() must return the same value for these objects. + public int GetHashCode(ProfileViewportTargetDisplay profileViewport) + { + // Check whether the object is null + if (Object.ReferenceEquals(profileViewport, null)) return 0; + + // Get hash code for the FrequencyInMillihertz field if it is not null. + int hashFrequencyInMillihertz = profileViewport.FrequencyInMillihertz.GetHashCode(); + + // Get hash code for the Position field if it is not null. + int hashRotation = profileViewport.Rotation.GetHashCode(); + + // Get hash code for the Scaling field if it is not null. + int hashScaling = profileViewport.Scaling.GetHashCode(); + + // Get hash code for the ScanLineOrdering field if it is not null. + int hashScanLineOrdering = profileViewport.ScanLineOrdering.GetHashCode(); + + // Get hash code for the hashDisplayName field if it is not null. + int hashDisplayName = profileViewport.DisplayName == null ? 0 : profileViewport.DisplayName.GetHashCode(); + + // Get hash code for the DevicePath field if it is not null. + int hashDevicePath = profileViewport.DevicePath == null ? 0 : profileViewport.DevicePath.GetHashCode(); + + // Get hash code for the SurroundTopology field if it is not null. + int hashSurroundTopology = profileViewport.SurroundTopology == null ? 0 : profileViewport.SurroundTopology.GetHashCode(); + + //Calculate the hash code for the product. + return hashFrequencyInMillihertz ^ hashRotation ^ hashScaling ^ hashScanLineOrdering ^ + hashDisplayName ^ hashDevicePath ^ hashSurroundTopology; + } + } } \ No newline at end of file diff --git a/HeliosDisplayManagement/UIForms/DisplayProfileForm.cs b/HeliosDisplayManagement/UIForms/DisplayProfileForm.cs index 92b4faa..efb3a60 100644 --- a/HeliosDisplayManagement/UIForms/DisplayProfileForm.cs +++ b/HeliosDisplayManagement/UIForms/DisplayProfileForm.cs @@ -32,37 +32,28 @@ namespace HeliosPlus.UIForms private void Apply_Click(object sender, EventArgs e) { - /* if (dv_profile.Profile != null && - lv_profiles_old.SelectedIndices.Count > 0 && - lv_profiles_old.SelectedItems[0].Tag != null) + if (!_selectedProfile.IsPossible) { - if (!dv_profile.Profile.IsPossible) - { - MessageBox.Show(this, Language.This_profile_is_currently_impossible_to_apply, - Language.Apply_Profile, - MessageBoxButtons.OK, MessageBoxIcon.Warning); + MessageBox.Show(this, Language.This_profile_is_currently_impossible_to_apply, + Language.Apply_Profile, + MessageBoxButtons.OK, MessageBoxIcon.Warning); - return; - } + return; + } - Enabled = false; - Visible = false; + if ( + new SplashForm( + () => + { + Task.Factory.StartNew(() => _selectedProfile.Apply(), TaskCreationOptions.LongRunning); + }, 3, 30).ShowDialog(this) != + DialogResult.Cancel) + { + // nothing to do + Console.WriteLine("Applying profile " + _selectedProfile.Name); + } - if ( - new SplashForm( - () => - { - Task.Factory.StartNew(() => dv_profile.Profile.Apply(), TaskCreationOptions.LongRunning); - }, 3, 30).ShowDialog(this) != - DialogResult.Cancel) - { - ReloadProfiles(); - } - - Visible = true; - Enabled = true; - Activate(); - }*/ + Activate(); } private void Exit_Click(object sender, EventArgs e) @@ -186,9 +177,10 @@ namespace HeliosPlus.UIForms // so we need to show the current profile // And finally we need to select the currentProfile, as it's the one we're using now newItem.Selected = true; + ChangeSelectedProfile(Profile.CurrentProfile); } } - ChangeSelectedProfile(Profile.CurrentProfile); + } else {