Merge branch 'release/1.0.2' into main

This commit is contained in:
Terry MacDonald 2021-03-28 21:54:03 +13:00
commit 6cf3bd15a1
35 changed files with 445 additions and 74 deletions

View File

@ -91,10 +91,23 @@ namespace DisplayMagician.GameLibraries
catch (Exception ex)
{
logger.Debug(ex, $"SteamGame/IsRunning: Accessing Process.MainModule caused exception. Trying GameUtils.GetMainModuleFilepath instead");
if (GameUtils.GetMainModuleFilepath(gameProcess.Id).StartsWith(_steamGameExePath))
// If there is a race condition where MainModule isn't available, then we
// instead try the much slower GetMainModuleFilepath (which does the same thing)
string filePath = GameUtils.GetMainModuleFilepath(gameProcess.Id);
if (filePath == null)
{
// if we hit this bit then GameUtils.GetMainModuleFilepath failed,
// so we just skip that process
continue;
}
else
{
if (filePath.StartsWith(_steamGameExePath))
numGameProcesses++;
}
}
}
if (numGameProcesses > 0)
return true;
else

View File

@ -94,9 +94,20 @@ namespace DisplayMagician.GameLibraries
logger.Debug(ex, $"UplayGame/IsRunning: Accessing Process.MainModule caused exception. Trying GameUtils.GetMainModuleFilepath instead");
// If there is a race condition where MainModule isn't available, then we
// instead try the much slower GetMainModuleFilepath (which does the same thing)
if (GameUtils.GetMainModuleFilepath(gameProcess.Id).StartsWith(_uplayGameExePath))
string filePath = GameUtils.GetMainModuleFilepath(gameProcess.Id);
if (filePath == null)
{
// if we hit this bit then GameUtils.GetMainModuleFilepath failed,
// so we just skip that process
continue;
}
else
{
if (filePath.StartsWith(_uplayGameExePath))
numGameProcesses++;
}
}
}
if (numGameProcesses > 0)
return true;

View File

@ -52,6 +52,7 @@ namespace DisplayMagician
[System.Runtime.InteropServices.DllImport("Kernel32.dll")]
public static extern Boolean CloseHandle(IntPtr handle);
#pragma warning disable 0649
private struct IMAGELISTDRAWPARAMS
{
public int cbSize;
@ -72,6 +73,7 @@ namespace DisplayMagician
public int Frame;
public int crEffect;
}
#pragma warning restore 0649
[StructLayout(LayoutKind.Sequential)]
private struct IMAGEINFO

View File

@ -25,6 +25,13 @@ namespace DisplayMagician {
Uplay
}
public enum ApplyProfileResult
{
Successful,
Cancelled,
Error
}
internal static class Program
{
internal static string AppDataPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "DisplayMagician");
@ -501,7 +508,7 @@ namespace DisplayMagician {
}
// ApplyProfile lives here so that the UI works.
public static bool ApplyProfile(ProfileItem profile)
public static ApplyProfileResult ApplyProfile(ProfileItem profile)
{
logger.Debug($"Program/ApplyProfile: Starting");
@ -511,7 +518,7 @@ namespace DisplayMagician {
if (!profile.IsPossible)
{
logger.Debug($"Program/ApplyProfile: The supplied profile {profile.Name} isn't currently possible to use, so we can't apply it. This means a display that existed before has been removed, or moved.");
return false;
return ApplyProfileResult.Error;
}
@ -519,7 +526,7 @@ namespace DisplayMagician {
if (profile.UUID == ProfileRepository.GetActiveProfile().UUID)
{
logger.Debug($"Program/ApplyProfile: The supplied profile {profile.Name} is currently in use, so we don't need to apply it.");
return false;
return ApplyProfileResult.Successful;
}
try
@ -552,7 +559,7 @@ namespace DisplayMagician {
if (timeoutForm.ShowDialog() == DialogResult.Cancel)
{
return false;
return ApplyProfileResult.Cancelled;
}
// We only want to do the topology change if the profile we're on now
@ -612,7 +619,7 @@ namespace DisplayMagician {
if (!applyTopologyTask.IsCompleted)
{
logger.Debug($"Program/ApplyProfile: Failed to complete applying or removing the NVIDIA Surround profile");
return false;
return ApplyProfileResult.Error;
}
}
@ -645,7 +652,7 @@ namespace DisplayMagician {
logger.Debug($"Program/ApplyProfile: Applying Profile PathInfo stage failed to complete");
if (!applyPathInfoTask.IsCompleted)
return false;
return ApplyProfileResult.Error;
}
catch (Exception ex)
@ -653,13 +660,13 @@ namespace DisplayMagician {
Console.WriteLine($"ProfileRepository/ApplyTopology exception: {ex.Message}: {ex.StackTrace} - {ex.InnerException}");
{
logger.Debug($"Program/ApplyProfile: Failed to complete changing the Windows Display layout");
return false;
return ApplyProfileResult.Error;
}
}
ProfileRepository.UpdateActiveProfile();
return true;
return ApplyProfileResult.Successful;
}
public static bool LoadGamesInBackground()

View File

@ -37,8 +37,8 @@ using System.Runtime.InteropServices;
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.1.*")]
[assembly: AssemblyFileVersion("1.0.1.0")]
[assembly: AssemblyVersion("1.0.2.*")]
[assembly: AssemblyFileVersion("1.0.2.0")]
[assembly: NeutralResourcesLanguage("en")]
[assembly: CLSCompliant(true)]

View File

@ -441,21 +441,27 @@ namespace DisplayMagician
logger.Debug($"ShortcutRepository/LoadShortcuts: Connecting Shortcut profile names to the real profile objects");
foreach (ShortcutItem updatedShortcut in _allShortcuts)
{
bool foundProfile = false;
foreach (ProfileItem profile in ProfileRepository.AllProfiles)
{
if (profile.Equals(updatedShortcut.ProfileToUse))
if (profile.UUID.Equals(updatedShortcut.ProfileUUID))
{
// And assign the matching Profile if we find it.
updatedShortcut.ProfileToUse = profile;
foundProfile = true;
logger.Debug($"ShortcutRepository/LoadShortcuts: Found the profile with UUID {updatedShortcut.ProfileUUID} and linked it to a profile!");
break;
}
}
if (!foundProfile)
{
// We should only get here if there isn't a profile to match to.
logger.Debug($"ShortcutRepository/LoadShortcuts: Couldn't find the profile with UUID {updatedShortcut.ProfileUUID} so couldn't link it to a profile! We can't use this shortcut.");
updatedShortcut.ProfileToUse = null;
}
}
// Sort the shortcuts alphabetically
_allShortcuts.Sort();
@ -598,11 +604,20 @@ namespace DisplayMagician
{
logger.Info($"ShortcutRepository/RunShortcut: Changing to the {rollbackProfile.Name} profile.");
// Apply the Profile!
if (!Program.ApplyProfile(shortcutToUse.ProfileToUse))
ApplyProfileResult result = Program.ApplyProfile(shortcutToUse.ProfileToUse);
if (result == ApplyProfileResult.Error)
{
Console.WriteLine($"ERROR - Cannot apply '{shortcutToUse.ProfileToUse.Name}' Display Profile");
logger.Error($"ShortcutRepository/RunShortcut: Cannot apply '{shortcutToUse.ProfileToUse.Name}' Display Profile");
return;
}
else if (result == ApplyProfileResult.Cancelled)
{
Console.WriteLine($"ERROR - User cancelled applying '{shortcutToUse.ProfileToUse.Name}' Display Profile");
logger.Error($"ShortcutRepository/RunShortcut: User cancelled applying '{shortcutToUse.ProfileToUse.Name}' Display Profile");
return;
}
}
// record the old audio device
@ -946,6 +961,11 @@ namespace DisplayMagician
logger.Debug($"ShortcutRepository/RunShortcut: No more '{processNameToLookFor}' processes are still running");
break;
}
// Send a message to windows so that it doesn't think
// we're locked and try to kill us
System.Threading.Thread.CurrentThread.Join(0);
Thread.Sleep(1000);
}
}
Console.WriteLine($"{processNameToLookFor} has exited.");
@ -1063,7 +1083,10 @@ namespace DisplayMagician
break;
}
Thread.Sleep(300);
// Send a message to windows so that it doesn't think
// we're locked and try to kill us
System.Threading.Thread.CurrentThread.Join(0);
Thread.Sleep(1000);
}
Console.WriteLine($"{steamGameToRun.Name} has exited.");
logger.Debug($"ShortcutRepository/RunShortcut: Steam Game {steamGameToRun.Name} has exited.");
@ -1222,7 +1245,10 @@ namespace DisplayMagician
break;
}
Thread.Sleep(300);
// Send a message to windows so that it doesn't think
// we're locked and try to kill us
System.Threading.Thread.CurrentThread.Join(0);
Thread.Sleep(1000);
}
Console.WriteLine($"{uplayGameToRun.Name} has exited.");
logger.Debug($"ShortcutRepository/RunShortcut: Uplay Game {uplayGameToRun.Name} has exited.");
@ -1387,12 +1413,21 @@ namespace DisplayMagician
{
logger.Debug($"ShortcutRepository/RunShortcut: Rolling back display profile to {rollbackProfile.Name}");
//if (!ProfileRepository.ApplyProfile(rollbackProfile))
if (!Program.ApplyProfile(rollbackProfile))
ApplyProfileResult result = Program.ApplyProfile(rollbackProfile);
if (result == ApplyProfileResult.Error)
{
Console.WriteLine($"ERROR - Cannot revert back to '{rollbackProfile.Name}' Display Profile");
logger.Error($"ShortcutRepository/RunShortcut: Rolling back display profile to {rollbackProfile.Name}");
logger.Error($"ShortcutRepository/RunShortcut: Error rolling back display profile to {rollbackProfile.Name}");
return;
}
else if (result == ApplyProfileResult.Cancelled)
{
Console.WriteLine($"ERROR - User cancelled revert back to '{rollbackProfile.Name}' Display Profile");
logger.Error($"ShortcutRepository/RunShortcut: User cancelled rolling back display profile to {rollbackProfile.Name}");
return;
}
}
}

View File

@ -35,6 +35,7 @@
this.progressBar = new CircularProgressBar.CircularProgressBar();
this.lbl_message = new System.Windows.Forms.Label();
this.t_countdown = new System.Windows.Forms.Timer(this.components);
this.btn_close = new System.Windows.Forms.Button();
this.progressPanel.SuspendLayout();
this.SuspendLayout();
//
@ -106,12 +107,28 @@
this.t_countdown.Interval = 1000;
this.t_countdown.Tick += new System.EventHandler(this.t_countdown_Tick);
//
// btn_close
//
this.btn_close.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
this.btn_close.FlatAppearance.BorderSize = 0;
this.btn_close.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
this.btn_close.Font = new System.Drawing.Font("Microsoft Sans Serif", 14.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.btn_close.ForeColor = System.Drawing.Color.White;
this.btn_close.Location = new System.Drawing.Point(759, 12);
this.btn_close.Name = "btn_close";
this.btn_close.Size = new System.Drawing.Size(29, 32);
this.btn_close.TabIndex = 2;
this.btn_close.Text = "X";
this.btn_close.UseVisualStyleBackColor = true;
this.btn_close.Click += new System.EventHandler(this.btn_close_Click);
//
// ApplyingProfileForm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(50)))), ((int)(((byte)(50)))), ((int)(((byte)(50)))));
this.ClientSize = new System.Drawing.Size(800, 450);
this.Controls.Add(this.btn_close);
this.Controls.Add(this.progressPanel);
this.DoubleBuffered = true;
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
@ -142,5 +159,6 @@
private System.Windows.Forms.Label lbl_sub_message;
private System.Windows.Forms.Label lbl_message;
private System.Windows.Forms.Timer t_countdown;
private System.Windows.Forms.Button btn_close;
}
}

View File

@ -274,6 +274,10 @@ namespace DisplayMagician.UIForms
base.WndProc(ref m);
}
private void btn_close_Click(object sender, EventArgs e)
{
this.Close();
}
}
}

View File

@ -51,8 +51,10 @@ namespace DisplayMagician.UIForms
}
// Apply the Profile
Program.ApplyProfile(_selectedProfile);
if (Program.ApplyProfile(_selectedProfile) == ApplyProfileResult.Successful)
{
ChangeSelectedProfile(_selectedProfile);
}
}
@ -94,7 +96,7 @@ namespace DisplayMagician.UIForms
// select the
foreach (ProfileItem newSelectedProfile in ProfileRepository.AllProfiles)
{
if (newSelectedProfile.Name.Equals(ilv_saved_profiles.Items[ilvItemToSelect].Text))
if (newSelectedProfile.UUID.Equals(ilv_saved_profiles.Items[ilvItemToSelect].EquipmentModel))
{
ChangeSelectedProfile(newSelectedProfile);
}

View File

@ -96,7 +96,7 @@ namespace DisplayMagician.UIForms
{
Rectangle pos = Utility.GetSizedImageBounds(img, new Rectangle(bounds.Location + itemPadding, ImageListView.ThumbnailSize));
ShortcutItem shortcutToRender = ShortcutRepository.GetShortcut(item.Text);
ShortcutItem shortcutToRender = ShortcutRepository.GetShortcut(item.EquipmentModel);
if (shortcutToRender.IsValid == ShortcutValidity.Error)
{
// The shortcut is permanently invalid (game removed or profile deleted)
@ -267,7 +267,7 @@ namespace DisplayMagician.UIForms
{
Rectangle pos = Utility.GetSizedImageBounds(img, new Rectangle(bounds.Location + itemPadding, ImageListView.ThumbnailSize));
ProfileItem profileToRender = ProfileRepository.GetProfile(item.Text);
ProfileItem profileToRender = ProfileRepository.GetProfile(item.EquipmentModel);
if (profileToRender.IsPossible)
{
// Draw the full color image as the shortcuts is not invalid

View File

@ -98,7 +98,7 @@ namespace DisplayMagician.UIForms
profileToUse = ProfileRepository.CurrentProfile;
}
return profileToUse.Name;
return profileToUse.UUID;
}
catch (Exception ex)
{
@ -205,7 +205,7 @@ namespace DisplayMagician.UIForms
details.Add(new Utility.Tuple<ColumnType, string, object>(ColumnType.Dimensions, string.Empty, mySize));
details.Add(new Utility.Tuple<ColumnType, string, object>(ColumnType.Resolution, string.Empty, mySizeF));
details.Add(new Utility.Tuple<ColumnType, string, object>(ColumnType.ImageDescription, string.Empty, name ?? ""));
details.Add(new Utility.Tuple<ColumnType, string, object>(ColumnType.EquipmentModel, string.Empty, ""));
details.Add(new Utility.Tuple<ColumnType, string, object>(ColumnType.EquipmentModel, string.Empty, profileToUse.UUID));
details.Add(new Utility.Tuple<ColumnType, string, object>(ColumnType.DateTaken, string.Empty, now));
details.Add(new Utility.Tuple<ColumnType, string, object>(ColumnType.Artist, string.Empty, ""));
details.Add(new Utility.Tuple<ColumnType, string, object>(ColumnType.Copyright, string.Empty, ""));

View File

@ -77,7 +77,7 @@ namespace DisplayMagician.UIForms
ShortcutItem shortcut = (ShortcutItem) key;
//return shortcut.Name;
return shortcut.Name;
return shortcut.UUID;
}
catch (Exception ex)
{
@ -181,7 +181,7 @@ namespace DisplayMagician.UIForms
details.Add(new Utility.Tuple<ColumnType, string, object>(ColumnType.Dimensions, string.Empty, mySize));
details.Add(new Utility.Tuple<ColumnType, string, object>(ColumnType.Resolution, string.Empty, mySizeF));
details.Add(new Utility.Tuple<ColumnType, string, object>(ColumnType.ImageDescription, string.Empty, name ?? ""));
details.Add(new Utility.Tuple<ColumnType, string, object>(ColumnType.EquipmentModel, string.Empty, ""));
details.Add(new Utility.Tuple<ColumnType, string, object>(ColumnType.EquipmentModel, string.Empty, shortcut.UUID));
details.Add(new Utility.Tuple<ColumnType, string, object>(ColumnType.DateTaken, string.Empty, now));
details.Add(new Utility.Tuple<ColumnType, string, object>(ColumnType.Artist, string.Empty, ""));
details.Add(new Utility.Tuple<ColumnType, string, object>(ColumnType.Copyright, string.Empty, ""));

View File

@ -100,6 +100,11 @@ namespace DisplayMagician.UIForms
return (from item in ShortcutRepository.AllShortcuts where item.Name == shortcutName select item).First();
}
private ShortcutItem GetShortcutFromUUID(string shortcutUUID)
{
return (from item in ShortcutRepository.AllShortcuts where item.UUID == shortcutUUID select item).First();
}
private void btn_save_Click(object sender, EventArgs e)
{
//DialogResult = DialogResult.None;
@ -252,8 +257,8 @@ namespace DisplayMagician.UIForms
private void btn_edit_Click(object sender, EventArgs e)
{
int currentIlvIndex = ilv_saved_shortcuts.SelectedItems[0].Index;
string shortcutName = ilv_saved_shortcuts.Items[currentIlvIndex].Text;
_selectedShortcut = GetShortcutFromName(shortcutName);
string shortcutUUID = ilv_saved_shortcuts.Items[currentIlvIndex].EquipmentModel;
_selectedShortcut = GetShortcutFromUUID(shortcutUUID);
if (_selectedShortcut == null)
return;
@ -262,9 +267,10 @@ namespace DisplayMagician.UIForms
// We need to stop ImageListView redrawing things before we're ready
// This stops an exception when ILV is just too keen!
ilv_saved_shortcuts.SuspendLayout();
var shortcutForm = new ShortcutForm(_selectedShortcut);
//ilv_saved_shortcuts.SuspendLayout();
shortcutForm.ShowDialog(this);
if (shortcutForm.DialogResult == DialogResult.OK)
{

View File

@ -31,5 +31,5 @@ using System.Runtime.InteropServices;
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.1.0")]
[assembly: AssemblyFileVersion("1.0.1.0")]
[assembly: AssemblyVersion("1.0.2.0")]
[assembly: AssemblyFileVersion("1.0.2.0")]

View File

@ -6,7 +6,7 @@
-->
<?define MajorVersion="1" ?>
<?define MinorVersion="0" ?>
<?define BuildVersion="1" ?>
<?define BuildVersion="2" ?>
<!-- Revision is NOT used by WiX in the upgrade procedure -->
<!-- Full version number to display -->
<?define VersionNumber="$(var.MajorVersion).$(var.MinorVersion).$(var.BuildVersion)" ?>

View File

@ -327,11 +327,68 @@ namespace DisplayMagicianShared
if (this.GetType() != other.GetType())
return false;
if (Paths.Length != other.Paths.Length)
return false;
// Check if the profile identifiers are not the same, then return false
int foundDICount = 0;
foreach (string profileDI in ProfileDisplayIdentifiers)
{
if (other.ProfileDisplayIdentifiers.Contains(profileDI))
{
foundDICount++;
continue;
}
}
if (foundDICount != other.ProfileDisplayIdentifiers.Count)
return false;
foundDICount = 0;
foreach (string profileDI in other.ProfileDisplayIdentifiers)
{
if (ProfileDisplayIdentifiers.Contains(profileDI))
{
foundDICount++;
continue;
}
}
if (foundDICount != ProfileDisplayIdentifiers.Count)
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 (Paths.SequenceEqual(other.Paths))
// The data may be in different orders each run, so we need to compare them one by one
int foundPathsCount = 0;
int foundOtherPathsCount = 0;
foreach (Topology.Path profilePath in Paths)
{
if (other.Paths.Contains(profilePath))
{
foundPathsCount++;
continue;
}
}
foreach (Topology.Path otherPath in other.Paths)
{
if (Paths.Contains(otherPath))
{
foundOtherPathsCount++;
continue;
}
}
if (foundPathsCount == foundOtherPathsCount)
return true;
else
return false;
@ -339,7 +396,7 @@ namespace DisplayMagicianShared
// If Equals() returns true for this object compared to another
// then GetHashCode() must return the same value for these objects.
public override int GetHashCode()
/*public override int GetHashCode()
{
// Get hash code for the Viewports field if it is not null.
@ -348,6 +405,19 @@ namespace DisplayMagicianShared
//Calculate the hash code for the product.
return hashPaths;
}*/
public override int GetHashCode()
{
// Get hash code for the ProfileDisplayIdentifiers field if it is not null.
int hashIds = ProfileDisplayIdentifiers == null ? 0 : ProfileDisplayIdentifiers.GetHashCode();
// Get Paths too
int hashPaths = Paths == null ? 0 : Paths.GetHashCode();
// Calculate the hash code for the product.
return (hashIds, hashPaths).GetHashCode();
}
@ -445,8 +515,10 @@ namespace DisplayMagicianShared
}
if (validDisplayCount == ProfileDisplayIdentifiers.Count)
{
SharedLogger.logger.Debug($"ProfileRepository/IsPossibleRefresh: The profile {Name} is possible!");
_isPossible = true;
}
else
{
@ -462,7 +534,7 @@ namespace DisplayMagicianShared
class ProfileComparer : IEqualityComparer<ProfileItem>
{
// Products are equal if their names and product numbers are equal.
public bool Equals(ProfileItem x, ProfileItem y)
/*public bool Equals(ProfileItem x, ProfileItem y)
{
//Check whether the compared objects reference the same data.
@ -480,11 +552,83 @@ namespace DisplayMagicianShared
return true;
else
return false;
}*/
public bool Equals(ProfileItem x, ProfileItem 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 (x is null || y is null)
return false;
if (x.Paths.Length != y.Paths.Length)
return false;
// Check if the profile identifiers are not the same, then return false
int foundDICount = 0;
foreach (string profileDI in x.ProfileDisplayIdentifiers)
{
if (y.ProfileDisplayIdentifiers.Contains(profileDI))
{
foundDICount++;
continue;
}
}
if (foundDICount != x.ProfileDisplayIdentifiers.Count)
return false;
foundDICount = 0;
foreach (string profileDI in y.ProfileDisplayIdentifiers)
{
if (x.ProfileDisplayIdentifiers.Contains(profileDI))
{
foundDICount++;
continue;
}
}
if (foundDICount != y.ProfileDisplayIdentifiers.Count)
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
int foundPathsCount = 0;
int foundOtherPathsCount = 0;
foreach (Topology.Path profilePath in x.Paths)
{
if (y.Paths.Contains(profilePath))
{
foundPathsCount++;
continue;
}
}
foreach (Topology.Path otherPath in y.Paths)
{
if (x.Paths.Contains(otherPath))
{
foundOtherPathsCount++;
continue;
}
}
if (foundPathsCount == foundOtherPathsCount)
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(ProfileItem profile)
/*public int GetHashCode(ProfileItem profile)
{
// Check whether the object is null
@ -496,7 +640,23 @@ namespace DisplayMagicianShared
//Calculate the hash code for the product.
return hashPaths;
}
}*/
// Modified the GetHashCode to compare the displayidentifier
public int GetHashCode(ProfileItem profile)
{
// Check whether the object is null
if (profile is null) return 0;
// Get hash code for the ProfileDisplayIdentifiers field if it is not null.
int hashIds = profile.ProfileDisplayIdentifiers == null ? 0 : profile.ProfileDisplayIdentifiers.GetHashCode();
// Get hash code for the Paths
int hashPaths = profile.Paths == null ? 0 : profile.Paths.GetHashCode();
//Calculate the hash code for the product.
return (hashIds,hashPaths).GetHashCode();
}
}
}

View File

@ -16,6 +16,7 @@ using NvAPIWrapper.Native.GPU;
namespace DisplayMagicianShared
{
public static class ProfileRepository
{
#region Class Variables
@ -47,10 +48,10 @@ namespace DisplayMagicianShared
SharedLogger.logger.Debug($"ProfileRepository/ProfileRepository: Initialising the NvAPIWrapper.NVIDIA library.");
NvAPIWrapper.NVIDIA.Initialize();
SharedLogger.logger.Debug($"ProfileRepository/ProfileRepository: Creating the Profiles storage folder {AppProfileStoragePath}.");
// Create the Profile Storage Path if it doesn't exist so that it's avilable for all the program
if (!Directory.Exists(AppProfileStoragePath))
{
SharedLogger.logger.Debug($"ProfileRepository/ProfileRepository: Creating the Profiles storage folder {AppProfileStoragePath}.");
Directory.CreateDirectory(AppProfileStoragePath);
}
}
@ -406,7 +407,8 @@ namespace DisplayMagicianShared
foreach (ProfileItem testProfile in _allProfiles)
{
if (testProfile.Paths.SequenceEqual(_currentProfile.Paths))
// TODO - change for Equals
if (testProfile.Equals(_currentProfile))
{
SharedLogger.logger.Debug($"ProfileRepository/ContainsCurrentProfile: Our profile repository does contain the display profile currently in use");
return true;
@ -495,7 +497,7 @@ namespace DisplayMagicianShared
}
public static void UpdateActiveProfile()
/*public static void UpdateActiveProfile()
{
SharedLogger.logger.Debug($"ProfileRepository/UpdateActiveProfile: Updating the profile currently active (in use now).");
@ -526,9 +528,43 @@ namespace DisplayMagicianShared
//IsPossibleRefresh();
}
}*/
public static void UpdateActiveProfile()
{
SharedLogger.logger.Debug($"ProfileRepository/UpdateActiveProfile: Updating the profile currently active (in use now).");
ProfileItem activeProfile = new ProfileItem
{
Name = "Current Display Profile",
Paths = PathInfo.GetActivePaths().Select(info => new DisplayMagicianShared.Topology.Path(info)).ToArray(),
//ProfileDisplayIdentifiers = ProfileRepository.GenerateProfileDisplayIdentifiers()
};
activeProfile.ProfileIcon = new ProfileIcon(activeProfile);
activeProfile.ProfileBitmap = activeProfile.ProfileIcon.ToBitmap(256, 256);
if (_profilesLoaded && _allProfiles.Count > 0)
{
foreach (ProfileItem loadedProfile in ProfileRepository.AllProfiles)
{
if (activeProfile.Equals(loadedProfile))
{
_currentProfile = loadedProfile;
SharedLogger.logger.Debug($"ProfileRepository/UpdateActiveProfile: The profile {loadedProfile.Name} is currently active (in use now).");
return;
}
}
}
SharedLogger.logger.Debug($"ProfileRepository/UpdateActiveProfile: The current profile is a new profile that doesn't already exist in the Profile Repository.");
_currentProfile = activeProfile;
//IsPossibleRefresh();
}
public static ProfileItem GetActiveProfile()
{
if (!(_currentProfile is ProfileItem))
@ -549,7 +585,8 @@ namespace DisplayMagicianShared
SharedLogger.logger.Debug($"ProfileRepository/IsActiveProfile: Checking whether the profile {profile.Name} is the currently active profile.");
if (profile.Paths.SequenceEqual(_currentProfile.Paths))
//if (profile.Paths.SequenceEqual(_currentProfile.Paths))
if (profile.Equals(_currentProfile))
{
SharedLogger.logger.Debug($"ProfileRepository/IsActiveProfile: The profile {profile.Name} is the currently active profile.");
return true;
@ -877,6 +914,9 @@ namespace DisplayMagicianShared
}
// Sort the display identifiers
displayIdentifiers.Sort();
return displayIdentifiers;
}
@ -1082,6 +1122,9 @@ namespace DisplayMagicianShared
}
// Sort the display identifiers
displayIdentifiers.Sort();
return displayIdentifiers;
}

View File

@ -35,5 +35,5 @@ using System.Runtime.InteropServices;
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.1.*")]
[assembly: AssemblyFileVersion("1.0.1.0")]
[assembly: AssemblyVersion("1.0.2.*")]
[assembly: AssemblyFileVersion("1.0.2.0")]

View File

@ -77,17 +77,34 @@ namespace DisplayMagicianShared.Topology
// 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)*/
// Note: Removed the source ID as it changes on boot sometimes!
// It can change and the profiles can still be the same
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
/*// If the above all match, then we need to check the DisplayTargets
if (other.TargetDisplays.SequenceEqual(TargetDisplays))
return true;
else
return false;*/
foreach (PathTarget myTargetDisplay in TargetDisplays)
{
if (!other.TargetDisplays.Contains(myTargetDisplay))
return false;
}
/*foreach (PathTarget theirTargetDisplay in other.TargetDisplays)
{
if (!TargetDisplays.Contains(theirTargetDisplay))
return false;
}*/
return true;
}
else
return false;
}
@ -114,8 +131,50 @@ namespace DisplayMagicianShared.Topology
//Calculate the hash code for the product.
return hashPixelFormat ^ hashPosition ^ hashResolution ^ hashSourceId ^ hashTargetDisplays;
}
public bool IsPossible(Path 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)*/
// Note: Removed the source ID as it changes on boot sometimes!
// It can change and the profiles can still be the same
if (PixelFormat == other.PixelFormat &&
Position.Equals(other.Position) &&
Resolution.Equals(other.Resolution))
return true;
else
return false;
}
public bool ContainsSurround()
{
foreach (PathTarget pathTarget in TargetDisplays)
{
if (pathTarget.SurroundTopology == null)
return false;
}
return true;
}
}
// Custom comparer for the ProfileViewport class
class PathComparer : IEqualityComparer<Path>
{
@ -132,6 +191,12 @@ namespace DisplayMagicianShared.Topology
// 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)*/
// Note: Removed the source ID as it changes on boot sometimes!
// It can change and the profiles can still be the same
if (x.PixelFormat == y.PixelFormat &&
x.Position.Equals(y.Position) &&
x.Resolution.Equals(y.Resolution) &&
@ -139,16 +204,21 @@ namespace DisplayMagicianShared.Topology
{
// If the above all match, then we need to check the DisplayTargets
// If they aren't equal then we need to return false;
if (!x.TargetDisplays.SequenceEqual(y.TargetDisplays))
/*if (!x.TargetDisplays.SequenceEqual(y.TargetDisplays))
return false;
else
return true;
/* foreach (ProfileViewportTargetDisplay xTargetDisplay in x.TargetDisplays)
return true;*/
foreach (PathTarget xTargetDisplay in x.TargetDisplays)
{
if (!y.TargetDisplays.Contains(xTargetDisplay))
return false;
}
/*foreach (PathTarget yTargetDisplay in y.TargetDisplays)
{
if (!x.TargetDisplays.Contains(yTargetDisplay))
return false;
}*/
//return true;
return true;
}
else
return false;

View File

@ -35,5 +35,5 @@ using System.Runtime.InteropServices;
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.1.*")]
[assembly: AssemblyFileVersion("1.0.1.0")]
[assembly: AssemblyVersion("1.0.2.*")]
[assembly: AssemblyFileVersion("1.0.2.0")]

View File

@ -68,7 +68,7 @@ I am doing this work to scratch a programming itch I've had for a while. It's pr
<div style="text-align:center"><img src="READMEAssets/DisplayMagicianConfigureShortcut3.png"/></div>
<div style="text-align:center"><img src="READMEAssets/DisplayMagicianConfigureShortcut4.png"/></div>
<div style="text-align:center"><img src="READMEAssets/DisplayMagicianConfigureShortcut5.png"/></div>
<div style="text-align:center"><img src="READMEAssets/HeliosPlusShellExtension.png"/></div>
<div style="text-align:center"><img src="READMEAssets/DisplayMagicianShellExtension.png"/></div>
### Initial Setup:

Binary file not shown.

Before

Width:  |  Height:  |  Size: 47 KiB

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 56 KiB

After

Width:  |  Height:  |  Size: 65 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 57 KiB

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 91 KiB

After

Width:  |  Height:  |  Size: 95 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 58 KiB

After

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 248 KiB

After

Width:  |  Height:  |  Size: 248 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 765 KiB

After

Width:  |  Height:  |  Size: 766 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 447 KiB

After

Width:  |  Height:  |  Size: 594 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.9 KiB

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

View File

@ -65,7 +65,7 @@ I am doing this work to scratch a programming itch I've had for a while. It's pr
<div style="text-align:center"><img src="https://github.com/terrymacdonald/DisplayMagician/raw/main/READMEAssets/DisplayMagicianConfigureShortcut3.png"/></div>
<div style="text-align:center"><img src="https://github.com/terrymacdonald/DisplayMagician/raw/main/READMEAssets/DisplayMagicianConfigureShortcut4.png"/></div>
<div style="text-align:center"><img src="https://github.com/terrymacdonald/DisplayMagician/raw/main/READMEAssets/DisplayMagicianConfigureShortcut5.png"/></div>
<div style="text-align:center"><img src="https://github.com/terrymacdonald/DisplayMagician/raw/main/READMEAssets/HeliosPlusShellExtension.png"/></div>
<div style="text-align:center"><img src="https://github.com/terrymacdonald/DisplayMagician/raw/main/READMEAssets/DisplayMagicianShellExtension.png"/></div>
### Initial Setup:

View File

@ -1,6 +1,6 @@
{
"version": "1.0.1.0",
"url": "https://github.com/terrymacdonald/DisplayMagician/releases/download/v1.0.1/DisplayMagicianSetup-v1.0.1.msi",
"version": "1.0.2.0",
"url": "https://github.com/terrymacdonald/DisplayMagician/releases/download/v1.0.2/DisplayMagicianSetup-v1.0.2.msi",
"changelog": "https://github.com/terrymacdonald/DisplayMagician/releases",
"mandatory": {
"value": false,
@ -8,7 +8,7 @@
"mode": 0
},
"checksum": {
"value": "78067AE8F7F28101CB530110CFBF2AD9C47B809DC5D7365D4BD413D63D314FAC",
"value": "49363731427276601051E6D70F1DA3BB389760FC73CEF5F7854EC88E5011BF40",
"hashingAlgorithm": "SHA256"
}
}