using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Windows.Forms; using DisplayMagicianShared.Resources; using Newtonsoft.Json; using System.Drawing; using System.Drawing.Imaging; namespace DisplayMagicianShared.Windows { public class WinProfileItem : ProfileItem, IComparable { private static List _allSavedProfiles = new List(); private ProfileIcon _profileIcon; private Bitmap _profileBitmap, _profileShortcutBitmap; private List _profileDisplayIdentifiers = new List(); private List _screens; private WINDOWS_DISPLAY_CONFIG _windowsDisplayConfig = new WINDOWS_DISPLAY_CONFIG(); private static readonly string uuidV4Regex = @"(?im)^[{(]?[0-9A-F]{8}[-]?(?:[0-9A-F]{4}[-]?){3}[0-9A-F]{12}[)}]?$"; private string _uuid = ""; private bool _isPossible = false; private Keys _hotkey = Keys.None; public WinProfileItem() { } public new static Version Version = new Version(2, 1); #region Instance Properties [JsonIgnore] public override bool IsPossible { get { // Return the cached answer return _isPossible; } set { _isPossible = value; } } [JsonIgnore] public override bool IsActive { get { if (this.Equals(ProfileRepository.CurrentProfile)) return true; else return false; } } public override VIDEO_MODE VideoMode { get; } = VIDEO_MODE.WINDOWS; public override string Name { get; set; } [JsonRequired] public WINDOWS_DISPLAY_CONFIG WindowsDisplayConfig { get { return _windowsDisplayConfig; } set { _windowsDisplayConfig = value; } } public override List ProfileDisplayIdentifiers { get { if (_profileDisplayIdentifiers.Count == 0) { _profileDisplayIdentifiers = WinLibrary.GetLibrary().GetCurrentDisplayIdentifiers(); } return _profileDisplayIdentifiers; } set { if (value is List) _profileDisplayIdentifiers = value; } } /*[JsonRequired] public override List Screens { get { if (_screens.Count == 0) { _screens = GetScreenPositions(); } return _screens; } set { _screens = value; } } [JsonConverter(typeof(CustomBitmapConverter))] public override Bitmap ProfileBitmap { get { *//*if (!ProfileRepository.ProfilesLoaded) return null;*//* if (_profileBitmap != null) return _profileBitmap; else { _profileBitmap = this.ProfileIcon.ToBitmap(256, 256); return _profileBitmap; } } set { _profileBitmap = value; } } */ /*[JsonConverter(typeof(CustomBitmapConverter))] public override Bitmap ProfileTightestBitmap { get { if (_profileShortcutBitmap != null) return _profileShortcutBitmap; else { _profileShortcutBitmap = this.ProfileIcon.ToTightestBitmap(); return _profileShortcutBitmap; } } set { _profileShortcutBitmap = value; } } */ #endregion public override bool IsValid() { if ( ProfileIcon is ProfileIcon && System.IO.File.Exists(SavedProfileIconCacheFilename) && ProfileBitmap is Bitmap && ProfileTightestBitmap is Bitmap && ProfileDisplayIdentifiers.Count > 0) { return true; } else return false; } public bool CopyTo(WinProfileItem profile, bool overwriteId = true) { if (!(profile is WinProfileItem)) return false; if (overwriteId == true) profile.UUID = UUID; // Copy all our profile data over to the other profile profile.Name = Name; profile.WindowsDisplayConfig = WindowsDisplayConfig; profile.ProfileIcon = ProfileIcon; profile.SavedProfileIconCacheFilename = SavedProfileIconCacheFilename; profile.ProfileBitmap = ProfileBitmap; profile.ProfileTightestBitmap = ProfileTightestBitmap; profile.ProfileDisplayIdentifiers = ProfileDisplayIdentifiers; profile.Screens = Screens; return true; } public override bool PreSave() { // Prepare our profile data for saving if (_profileDisplayIdentifiers.Count == 0) { _profileDisplayIdentifiers = WinLibrary.GetLibrary().GetCurrentDisplayIdentifiers(); } // Return if it is valid and we should continue return IsValid(); } public override void RefreshPossbility() { // Check whether this profile is possible if (WinLibrary.GetLibrary().IsPossibleConfig(_windowsDisplayConfig)) { SharedLogger.logger.Debug($"ProfileRepository/IsPossibleRefresh: The Windows CCD profile {Name} is possible!"); _isPossible = true; } else { SharedLogger.logger.Debug($"ProfileRepository/IsPossibleRefresh: The Windows CCD profile {Name} is NOT possible!"); _isPossible = false; } } public override bool CreateProfileFromCurrentDisplaySettings() { WinLibrary winLibrary = WinLibrary.GetLibrary(); if (winLibrary.IsInstalled) { // Create the profile data from the current config _windowsDisplayConfig = winLibrary.GetActiveConfig(); // Now, since the ActiveProfile has changed, we need to regenerate screen positions _screens = GetScreenPositions(); return true; } else { return false; } } public override bool PerformPostLoadingTasks() { // First thing we do is to set up the Screens _screens = GetScreenPositions(); return true; } public override List GetScreenPositions() { // Now we create the screens structure from the AMD profile information _screens = new List(); int pathCount = _windowsDisplayConfig.DisplayConfigPaths.Length; // First of all we need to figure out how many display paths we have. if (pathCount < 1) { // Return an empty screen if we have no Display Config Paths to use! return _screens; } foreach (var path in _windowsDisplayConfig.DisplayConfigPaths) { // For each path we go through and get the relevant info we need. if (_windowsDisplayConfig.DisplayConfigPaths.Length > 0) { // Set some basics about the screen ScreenPosition screen = new ScreenPosition(); screen.Library = "WINDOWS"; UInt32 targetId = path.TargetInfo.Id; foreach (DISPLAYCONFIG_MODE_INFO displayMode in _windowsDisplayConfig.DisplayConfigModes) { // Find the matching Display Config Source Mode if (displayMode.InfoType != DISPLAYCONFIG_MODE_INFO_TYPE.DISPLAYCONFIG_MODE_INFO_TYPE_SOURCE && displayMode.Id == targetId) { screen.Name = targetId.ToString(); //screen.DisplayConnector = displayMode.DisplayConnector; screen.ScreenX = displayMode.SourceMode.Position.X; screen.ScreenY = displayMode.SourceMode.Position.Y; screen.ScreenWidth = (int)displayMode.SourceMode.Width; screen.ScreenHeight = (int)displayMode.SourceMode.Height; // If we're at the 0,0 coordinate then we're the primary monitor if (screen.ScreenX == 0 && screen.ScreenY == 0) { screen.IsPrimary = true; } } } foreach (ADVANCED_HDR_INFO_PER_PATH hdrInfo in _windowsDisplayConfig.DisplayHDRStates) { // Find the matching HDR information if (hdrInfo.Id == targetId) { // HDR information if (hdrInfo.AdvancedColorInfo.AdvancedColorSupported) { screen.HDRSupported = true; if (hdrInfo.AdvancedColorInfo.AdvancedColorEnabled) { screen.HDREnabled = true; } else { screen.HDREnabled = false; } } else { screen.HDRSupported = false; screen.HDREnabled = false; } } } // No spanning in a windows ccd system screen.IsSpanned = false; screen.Colour = Color.FromArgb(195, 195, 195); // represents normal screen colour _screens.Add(screen); } } return _screens; } // The public override for the Object.Equals public override bool Equals(object obj) { return this.Equals(obj as WinProfileItem); } // Profiles are equal if their Viewports are equal public bool Equals(WinProfileItem other) { // If parameter is null, return false. if (other is 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; // If Windows Display Config is different then return false. if (!WindowsDisplayConfig.Equals(other.WindowsDisplayConfig)) return false; // If Display Identifiers are different then return false. if (!ProfileDisplayIdentifiers.SequenceEqual(other.ProfileDisplayIdentifiers)) return false; // Otherwise if all the tests work, then we're good! return true; } // If Equals() returns true for this object compared to another // then GetHashCode() must return the same value for these objects. public override int GetHashCode() { // Calculate the hash code for the product. return (WindowsDisplayConfig, ProfileDisplayIdentifiers).GetHashCode(); } } }