2017-02-26 19:23:31 +00:00
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Drawing;
|
|
|
|
|
using System.Linq;
|
|
|
|
|
using WindowsDisplayAPI;
|
|
|
|
|
using WindowsDisplayAPI.DisplayConfig;
|
2020-04-23 08:16:16 +00:00
|
|
|
|
using HeliosPlus.Shared;
|
|
|
|
|
using HeliosPlus.Shared.Topology;
|
2017-02-26 19:23:31 +00:00
|
|
|
|
|
2020-04-23 08:16:16 +00:00
|
|
|
|
namespace HeliosPlus
|
2017-02-26 19:23:31 +00:00
|
|
|
|
{
|
|
|
|
|
internal class DisplayRepresentation
|
|
|
|
|
{
|
|
|
|
|
public DisplayRepresentation(Display display)
|
|
|
|
|
{
|
|
|
|
|
Name = display.DeviceName;
|
|
|
|
|
Path = display.DevicePath;
|
|
|
|
|
var index = Path.IndexOf("{", StringComparison.InvariantCultureIgnoreCase);
|
2018-10-20 00:27:25 +00:00
|
|
|
|
|
2017-02-26 19:23:31 +00:00
|
|
|
|
if (index > 0)
|
2018-10-20 00:27:25 +00:00
|
|
|
|
{
|
2017-02-26 19:23:31 +00:00
|
|
|
|
Path = Path.Substring(0, index).TrimEnd('#');
|
2018-10-20 00:27:25 +00:00
|
|
|
|
}
|
|
|
|
|
|
2017-02-26 19:23:31 +00:00
|
|
|
|
IsAvailable = display.IsAvailable;
|
2018-10-20 00:27:25 +00:00
|
|
|
|
|
2017-02-26 19:23:31 +00:00
|
|
|
|
if (IsAvailable)
|
2018-10-20 00:27:25 +00:00
|
|
|
|
{
|
2017-02-26 19:23:31 +00:00
|
|
|
|
PossibleSettings = GetDisplay()?.GetPossibleSettings()?.ToArray() ?? new DisplayPossibleSetting[0];
|
2018-10-20 00:27:25 +00:00
|
|
|
|
}
|
2017-02-26 19:23:31 +00:00
|
|
|
|
}
|
|
|
|
|
|
2020-05-12 10:46:23 +00:00
|
|
|
|
public DisplayRepresentation(ProfileViewportTargetDisplay display)
|
2017-02-26 19:23:31 +00:00
|
|
|
|
{
|
|
|
|
|
Name = display.DisplayName;
|
|
|
|
|
Path = display.DevicePath;
|
|
|
|
|
IsAvailable = GetDisplay()?.IsAvailable ?? false;
|
2018-10-20 00:27:25 +00:00
|
|
|
|
|
2017-02-26 19:23:31 +00:00
|
|
|
|
if (IsAvailable)
|
2018-10-20 00:27:25 +00:00
|
|
|
|
{
|
2017-02-26 19:23:31 +00:00
|
|
|
|
PossibleSettings = GetDisplay()?.GetPossibleSettings()?.ToArray() ?? new DisplayPossibleSetting[0];
|
2018-10-20 00:27:25 +00:00
|
|
|
|
}
|
2017-02-26 19:23:31 +00:00
|
|
|
|
}
|
|
|
|
|
|
2017-08-10 14:21:45 +00:00
|
|
|
|
public bool IsAvailable { get; }
|
2018-10-20 00:27:25 +00:00
|
|
|
|
public string Name { get; }
|
2017-02-26 19:23:31 +00:00
|
|
|
|
public string Path { get; }
|
|
|
|
|
|
2018-10-20 00:27:25 +00:00
|
|
|
|
public DisplayPossibleSetting[] PossibleSettings { get; }
|
2017-02-26 19:23:31 +00:00
|
|
|
|
|
2020-06-07 08:48:45 +00:00
|
|
|
|
public static IEnumerable<DisplayRepresentation> GetDisplays(ProfileItem profile = null)
|
2017-02-26 19:23:31 +00:00
|
|
|
|
{
|
|
|
|
|
//var displays =
|
|
|
|
|
// Display.GetDisplays()
|
|
|
|
|
// .Select(display => new DisplayRepresentation(display))
|
|
|
|
|
// .OrderByDescending(representation => representation.IsAvailable)
|
|
|
|
|
// .GroupBy(representation => representation.Path)
|
|
|
|
|
// .Select(grouping => grouping.First()).ToList();
|
|
|
|
|
var displays = new List<DisplayRepresentation>();
|
2018-10-20 00:27:25 +00:00
|
|
|
|
|
2017-02-26 19:23:31 +00:00
|
|
|
|
if (profile != null)
|
2018-10-20 00:27:25 +00:00
|
|
|
|
{
|
2020-05-12 10:46:23 +00:00
|
|
|
|
foreach (var target in profile.Viewports.SelectMany(path => path.TargetDisplays))
|
2018-10-20 00:27:25 +00:00
|
|
|
|
{
|
2017-02-26 19:23:31 +00:00
|
|
|
|
if (displays.All(display => display.Path != target.DevicePath))
|
2018-10-20 00:27:25 +00:00
|
|
|
|
{
|
2017-02-26 19:23:31 +00:00
|
|
|
|
displays.Add(new DisplayRepresentation(target));
|
2018-10-20 00:27:25 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-02-26 19:23:31 +00:00
|
|
|
|
return displays;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public Display GetDisplay()
|
|
|
|
|
{
|
|
|
|
|
return Display.GetDisplays().FirstOrDefault(display => display.DevicePath.StartsWith(Path));
|
|
|
|
|
}
|
|
|
|
|
|
2020-06-07 08:48:45 +00:00
|
|
|
|
public ProfileViewport GetPathSource(ProfileItem profile)
|
2017-02-26 19:23:31 +00:00
|
|
|
|
{
|
2020-05-12 10:46:23 +00:00
|
|
|
|
return profile.Viewports.FirstOrDefault(path => path.TargetDisplays.Any(target => target.DevicePath == Path));
|
2017-02-26 19:23:31 +00:00
|
|
|
|
}
|
|
|
|
|
|
2020-06-07 08:48:45 +00:00
|
|
|
|
public ProfileViewportTargetDisplay GetPathTarget(ProfileItem profile)
|
2017-02-26 19:23:31 +00:00
|
|
|
|
{
|
2020-05-12 10:46:23 +00:00
|
|
|
|
return profile.Viewports.SelectMany(path => path.TargetDisplays).FirstOrDefault(target => target.DevicePath == Path);
|
2017-02-26 19:23:31 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public PathDisplayTarget GetTargetInfo()
|
|
|
|
|
{
|
|
|
|
|
return
|
|
|
|
|
PathDisplayTarget.GetDisplayTargets()
|
|
|
|
|
.Where(target => target.DevicePath.StartsWith(Path))
|
|
|
|
|
.OrderByDescending(target => target.IsAvailable)
|
|
|
|
|
.FirstOrDefault();
|
|
|
|
|
}
|
2017-08-10 14:21:45 +00:00
|
|
|
|
|
2020-06-07 08:48:45 +00:00
|
|
|
|
public Bitmap ToBitmap(Size size, ProfileItem profile = null)
|
2017-08-10 14:21:45 +00:00
|
|
|
|
{
|
|
|
|
|
var targetInfo = GetTargetInfo();
|
|
|
|
|
var resolution = Size.Empty;
|
2018-10-20 00:27:25 +00:00
|
|
|
|
|
|
|
|
|
if (targetInfo != null && targetInfo.IsAvailable)
|
2017-08-10 14:21:45 +00:00
|
|
|
|
{
|
|
|
|
|
resolution = targetInfo.PreferredResolution;
|
|
|
|
|
}
|
|
|
|
|
else if (profile != null)
|
|
|
|
|
{
|
|
|
|
|
var targetPath = GetPathSource(profile);
|
2018-10-20 00:27:25 +00:00
|
|
|
|
|
2017-08-10 14:21:45 +00:00
|
|
|
|
if (targetPath != null)
|
2018-10-20 00:27:25 +00:00
|
|
|
|
{
|
2017-08-10 14:21:45 +00:00
|
|
|
|
resolution = targetPath.Resolution;
|
2018-10-20 00:27:25 +00:00
|
|
|
|
}
|
2017-08-10 14:21:45 +00:00
|
|
|
|
}
|
2018-10-20 00:27:25 +00:00
|
|
|
|
|
2020-06-07 08:48:45 +00:00
|
|
|
|
var p = new ProfileItem {Viewports = new ProfileViewport[1]};
|
2020-05-12 10:46:23 +00:00
|
|
|
|
p.Viewports[0] = new ProfileViewport
|
2017-08-10 14:21:45 +00:00
|
|
|
|
{
|
|
|
|
|
Resolution = resolution,
|
|
|
|
|
Position = new Point(),
|
2020-05-12 10:46:23 +00:00
|
|
|
|
TargetDisplays = new ProfileViewportTargetDisplay[1]
|
2017-08-10 14:21:45 +00:00
|
|
|
|
};
|
2020-05-12 10:46:23 +00:00
|
|
|
|
p.Viewports[0].TargetDisplays[0] = new ProfileViewportTargetDisplay {DevicePath = Path};
|
2018-10-20 00:27:25 +00:00
|
|
|
|
|
2017-08-10 14:21:45 +00:00
|
|
|
|
if (profile != null)
|
|
|
|
|
{
|
|
|
|
|
var targetPath = GetPathTarget(profile);
|
2018-10-20 00:27:25 +00:00
|
|
|
|
|
2017-08-10 14:21:45 +00:00
|
|
|
|
if (targetPath != null)
|
2018-10-20 00:27:25 +00:00
|
|
|
|
{
|
2020-05-12 10:46:23 +00:00
|
|
|
|
p.Viewports[0].TargetDisplays[0].SurroundTopology = targetPath.SurroundTopology;
|
2018-10-20 00:27:25 +00:00
|
|
|
|
}
|
2017-08-10 14:21:45 +00:00
|
|
|
|
}
|
2018-10-20 00:27:25 +00:00
|
|
|
|
|
2017-08-10 14:21:45 +00:00
|
|
|
|
return new ProfileIcon(p).ToBitmap(size.Width, size.Height);
|
|
|
|
|
}
|
2017-02-26 19:23:31 +00:00
|
|
|
|
}
|
|
|
|
|
}
|