fix shutdown-event, add disable error popup setting, use better display id for Nvidia, fix refresh rate issues and improve background color

This commit is contained in:
Vincent Maas committed 2024-04-21 11:48:04 +02:00
1 parent 4f4ce54ade
commit 27bc0505b7
22 files changed
+384 -614

No files matched your search

+2 -2
View File
@@ -18,8 +18,8 @@
<PublisherName>Maassoft</PublisherName>
<Company>Maassoft</Company>
<ApplicationRevision>0</ApplicationRevision>
<ApplicationVersion>9.9.0.0</ApplicationVersion>
<Version>9.9.0.0</Version>
<ApplicationVersion>9.9.0.1</ApplicationVersion>
<Version>9.9.0.1</Version>
<UseApplicationTrust>false</UseApplicationTrust>
<PublishWizardCompleted>true</PublishWizardCompleted>
<BootstrapperEnabled>false</BootstrapperEnabled>
+9 -1
View File
@@ -311,8 +311,15 @@ Currently ColorControl is {(_winApiService.IsAdministrator() ? "" : "not ")}runn
SubLabel = "When this is enabled MinTML and MaxTML will be automatically be set to respectively the minimum luminance and the maximum luminance of the color profile",
Value = _config.SetMinTmlAndMaxTml
};
var disableErrorPopupField = new FieldDefinition
{
FieldType = FieldType.CheckBox,
Label = "Disable error popup when applying presets",
SubLabel = "Check this to disable the error popup when there was an error applying a preset",
Value = _config.DisableErrorPopupWhenApplyingPreset
};
var values = MessageForms.ShowDialog("Advanced settings", new[] { processPollingIntervalField, useRawInputField, setMinTmlAndMaxTmlField });
var values = MessageForms.ShowDialog("Advanced settings", new[] { processPollingIntervalField, useRawInputField, setMinTmlAndMaxTmlField, disableErrorPopupField });
if (values?.Any() != true)
{
@@ -322,6 +329,7 @@ Currently ColorControl is {(_winApiService.IsAdministrator() ? "" : "not ")}runn
_config.ProcessMonitorPollingInterval = processPollingIntervalField.ValueAsInt;
_config.UseRawInput = useRawInputField.ValueAsBool;
_config.SetMinTmlAndMaxTml = setMinTmlAndMaxTmlField.ValueAsBool;
_config.DisableErrorPopupWhenApplyingPreset = disableErrorPopupField.ValueAsBool;
_keyboardShortcutDispatcher.SetUseRawInput(_config.UseRawInput);
}
+4 -4
View File
@@ -37,6 +37,7 @@ namespace ColorControl
public NotifyIconManager _notifyIconManager;
private readonly KeyboardShortcutDispatcher _keyboardShortcutDispatcher;
private readonly UpdateManager _updateManager;
private readonly WindowMessageDispatcher _windowMessageDispatcher;
private Config _config;
private LgPanel _lgPanel;
@@ -48,7 +49,7 @@ namespace ColorControl
private GamePanel _gamePanel;
public MainForm(GlobalContext globalContext, ServiceManager serviceManager, IServiceProvider serviceProvider, ElevationService elevationService,
NotifyIconManager notifyIconManager, KeyboardShortcutDispatcher keyboardShortcutDispatcher, UpdateManager updateManager)
NotifyIconManager notifyIconManager, KeyboardShortcutDispatcher keyboardShortcutDispatcher, UpdateManager updateManager, WindowMessageDispatcher windowMessageDispatcher)
{
InitializeComponent();
@@ -60,6 +61,7 @@ namespace ColorControl
_notifyIconManager = notifyIconManager;
_keyboardShortcutDispatcher = keyboardShortcutDispatcher;
_updateManager = updateManager;
_windowMessageDispatcher = windowMessageDispatcher;
_config = Program.Config;
Text = globalContext.ApplicationTitleAdmin;
@@ -178,10 +180,8 @@ namespace ColorControl
if (m.Msg == NativeConstants.WM_QUERYENDSESSION)
{
SystemShutdown = true;
}
else if (m.Msg == NativeConstants.WM_ENDSESSION)
{
EndSession = true;
_windowMessageDispatcher.DispatchEvent(WindowMessageDispatcher.Event_WindowMessageQueryEndSession, new WindowMessageEventArgs(m));
}
else if (m.Msg == Utils.WM_BRINGTOFRONT)
{
+3 -14
View File
@@ -30,7 +30,6 @@ internal class MainWorker
private readonly WinApiService _winApiService;
private readonly WinApiAdminService _winApiAdminService;
private readonly UpdateManager _updateManager;
private bool _queryEndSession;
private nint _screenStateNotify;
public static int SHORTCUTID_SCREENSAVER = -100;
@@ -85,7 +84,6 @@ internal class MainWorker
_globalContext.SynchronizationContext = AsyncOperationManager.SynchronizationContext;
_windowMessageDispatcher.RegisterEventHandler(WindowMessageDispatcher.Event_WindowMessageQueryEndSession, HandleQueryEndSessionEvent);
_windowMessageDispatcher.RegisterEventHandler(WindowMessageDispatcher.Event_WindowMessageClose, HandleCloseEvent);
_windowMessageDispatcher.RegisterEventHandler(WindowMessageDispatcher.Event_WindowMessagePowerBroadcast, HandlePowerBroadcastEvent);
_windowMessageDispatcher.RegisterEventHandler(WindowMessageDispatcher.Event_WindowMessageShowWindow, HandleShowWindowEvent);
_windowMessageDispatcher.RegisterEventHandler(WindowMessageDispatcher.Event_WindowMessageUserBringToFront, HandleUserBringToFrontEvent);
@@ -151,21 +149,12 @@ internal class MainWorker
}
}
private void HandleCloseEvent(object sender, WindowMessageEventArgs e)
{
if (_queryEndSession)
{
Logger.Debug($"MainWorker: SystemShutdown");
_powerEventDispatcher.SendEvent(PowerEventDispatcher.Event_Shutdown);
}
}
private void HandleQueryEndSessionEvent(object sender, WindowMessageEventArgs e)
{
Logger.Debug("MainWorker: QueryEndSession");
Logger.Debug($"MainWorker: QueryEndSession");
Logger.Debug($"MainWorker: SystemShutdown");
_queryEndSession = true;
_powerEventDispatcher.SendEvent(PowerEventDispatcher.Event_Shutdown);
}
private void HandleHotKeyEvent(object sender, KeyboardShortcutEventArgs args)
+1 -1
View File
@@ -92,7 +92,7 @@ namespace ColorControl.Services.AMD
item = lvAmdPresets.Items.Add(display.DisplayName);
item.ImageIndex = id;
item.Font = new Font(item.Font, item.Font.Style | FontStyle.Bold);
item.BackColor = Color.LightGray;
item.BackColor = _globalContext.Config.UseDarkMode ? DarkModeUtils.ListViewDarkModeBackColor : Color.LightGray;
}
var values = displayInfo.Values;
+4 -3
View File
@@ -65,9 +65,10 @@ namespace ColorControl.Services.AMD
public override List<string> GetDisplayValues(Config config = null)
{
var values = new List<string>();
values.Add(name);
var values = new List<string>
{
name
};
var display = string.Format("{0}", primaryDisplay ? "Primary" : displayName);
values.Add(display);
+7 -5
View File
@@ -305,10 +305,11 @@ namespace ColorControl.Services.AMD
var index = 0;
foreach (var screen in Screen.AllScreens)
{
Logger.Debug($"SCREEN[{index}]: {screen.DeviceName}, {screen.DeviceFriendlyName()}, {screen.Primary}");
var info = CCD.GetDisplayInfo(screen.DeviceName);
Logger.Debug($"SCREEN[{index}]: {screen.DeviceName}, {info?.FriendlyName}, {screen.Primary}");
index++;
}
return Screen.AllScreens.FirstOrDefault(x => x.DeviceFriendlyName().Equals(display.DisplayName));
return Screen.AllScreens.FirstOrDefault(x => CCD.GetDisplayInfo(x.DeviceName)?.FriendlyName.Equals(display.DisplayName) ?? false);
}
public List<AmdDisplayInfo> GetDisplayInfos()
@@ -328,9 +329,10 @@ namespace ColorControl.Services.AMD
foreach (var display in displays)
{
var values = new List<string>();
values.Add("Current settings");
var values = new List<string>
{
"Current settings"
};
var screen = GetScreenForDisplay(display);
+4 -1
View File
@@ -93,7 +93,10 @@ namespace ColorControl.Services.Common
{
Logger.Error(e);
MessageForms.ErrorOk($"Error applying {ServiceName}-preset ({e.TargetSite.Name}): {e.Message}");
if (!_globalContext.Config.DisableErrorPopupWhenApplyingPreset)
{
MessageForms.ErrorOk($"Error applying {ServiceName}-preset ({preset.IdOrName}): {e.Message}");
}
return false;
}
}
+41 -5
View File
@@ -1,4 +1,6 @@
using NvAPIWrapper.Display;
using ColorControl.Shared.Native;
using NStandard;
using NvAPIWrapper.Display;
using System.Collections.Generic;
namespace ColorControl.Services.NVIDIA
@@ -7,18 +9,52 @@ namespace ColorControl.Services.NVIDIA
{
public Display Display { get; }
public List<string> Values { get; }
public List<string> Values { get; set; }
public string InfoLine { get; }
public string InfoLine { get; set; }
public string Name { get; }
public string Name { get; private set; }
public NvDisplayInfo(Display display, List<string> values, string infoLine, string name)
public string DisplayId { get; private set; }
public NvDisplayInfo(Display display, List<string> values, string infoLine, string name = null)
{
Display = display;
Values = values;
InfoLine = infoLine;
Name = name;
SetDisplayName();
}
private void SetDisplayName()
{
if (!Name.IsNullOrEmpty())
{
return;
}
if (Display == null)
{
Name = "Unknown";
return;
}
var info = CCD.GetDisplayInfo(Display.Name);
Name = info?.FriendlyName;
DisplayId = info?.DisplayId;
if (Name.IsNullOrEmpty())
{
Name = DisplayId;
}
else
{
Name = $"{Name} ({DisplayId})";
}
}
public override string ToString()
+42 -40
View File
@@ -61,6 +61,10 @@ namespace ColorControl.Services.NVIDIA
miNvPresetColorEnhancementsIncluded = new System.Windows.Forms.ToolStripMenuItem();
mnuRefreshRate = new System.Windows.Forms.ToolStripMenuItem();
miRefreshRateIncluded = new System.Windows.Forms.ToolStripMenuItem();
mnuNvResolution = new System.Windows.Forms.ToolStripMenuItem();
miNvResolutionIncluded = new System.Windows.Forms.ToolStripMenuItem();
mnuNvActiveResolution = new System.Windows.Forms.ToolStripMenuItem();
mnuNvVirtualResolution = new System.Windows.Forms.ToolStripMenuItem();
miNvPresetDithering = new System.Windows.Forms.ToolStripMenuItem();
miNvPresetApplyDithering = new System.Windows.Forms.ToolStripMenuItem();
miNvPresetDitheringEnabled = new System.Windows.Forms.ToolStripMenuItem();
@@ -102,10 +106,6 @@ namespace ColorControl.Services.NVIDIA
miNvTestDithering = new System.Windows.Forms.ToolStripMenuItem();
miNVIDIAInfo = new System.Windows.Forms.ToolStripMenuItem();
lvNvPresetsToolTip = new System.Windows.Forms.ToolTip(components);
mnuNvResolution = new System.Windows.Forms.ToolStripMenuItem();
miNvResolutionIncluded = new System.Windows.Forms.ToolStripMenuItem();
mnuNvActiveResolution = new System.Windows.Forms.ToolStripMenuItem();
mnuNvVirtualResolution = new System.Windows.Forms.ToolStripMenuItem();
mnuNvPresets.SuspendLayout();
mnuNvSettings.SuspendLayout();
SuspendLayout();
@@ -385,7 +385,7 @@ namespace ColorControl.Services.NVIDIA
// miNvPresetColorSettings
//
miNvPresetColorSettings.Name = "miNvPresetColorSettings";
miNvPresetColorSettings.Size = new System.Drawing.Size(180, 22);
miNvPresetColorSettings.Size = new System.Drawing.Size(120, 22);
miNvPresetColorSettings.Text = "Included";
miNvPresetColorSettings.Click += miNvPresetColorSettings_Click;
//
@@ -399,7 +399,7 @@ namespace ColorControl.Services.NVIDIA
// miNvPresetColorEnhancementsIncluded
//
miNvPresetColorEnhancementsIncluded.Name = "miNvPresetColorEnhancementsIncluded";
miNvPresetColorEnhancementsIncluded.Size = new System.Drawing.Size(180, 22);
miNvPresetColorEnhancementsIncluded.Size = new System.Drawing.Size(120, 22);
miNvPresetColorEnhancementsIncluded.Text = "Included";
miNvPresetColorEnhancementsIncluded.Click += miNvPresetColorEnhancementsIncluded_Click;
//
@@ -409,14 +409,42 @@ namespace ColorControl.Services.NVIDIA
mnuRefreshRate.Name = "mnuRefreshRate";
mnuRefreshRate.Size = new System.Drawing.Size(184, 22);
mnuRefreshRate.Text = "Refresh Rate";
mnuRefreshRate.DropDownOpening += mnuRefreshRate_DropDownOpening;
//
// miRefreshRateIncluded
//
miRefreshRateIncluded.Name = "miRefreshRateIncluded";
miRefreshRateIncluded.Size = new System.Drawing.Size(180, 22);
miRefreshRateIncluded.Size = new System.Drawing.Size(120, 22);
miRefreshRateIncluded.Text = "Included";
miRefreshRateIncluded.Click += includedToolStripMenuItem_Click;
//
// mnuNvResolution
//
mnuNvResolution.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { miNvResolutionIncluded, mnuNvActiveResolution, mnuNvVirtualResolution });
mnuNvResolution.Name = "mnuNvResolution";
mnuNvResolution.Size = new System.Drawing.Size(184, 22);
mnuNvResolution.Text = "Resolution";
mnuNvResolution.DropDownOpening += mnuNvResolution_DropDownOpening;
//
// miNvResolutionIncluded
//
miNvResolutionIncluded.Name = "miNvResolutionIncluded";
miNvResolutionIncluded.Size = new System.Drawing.Size(180, 22);
miNvResolutionIncluded.Text = "Included";
miNvResolutionIncluded.Click += miNvResolutionIncluded_Click;
//
// mnuNvActiveResolution
//
mnuNvActiveResolution.Name = "mnuNvActiveResolution";
mnuNvActiveResolution.Size = new System.Drawing.Size(180, 22);
mnuNvActiveResolution.Text = "Active";
//
// mnuNvVirtualResolution
//
mnuNvVirtualResolution.Name = "mnuNvVirtualResolution";
mnuNvVirtualResolution.Size = new System.Drawing.Size(180, 22);
mnuNvVirtualResolution.Text = "Virtual";
//
// miNvPresetDithering
//
miNvPresetDithering.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { miNvPresetApplyDithering, miNvPresetDitheringEnabled, mnuNvDitheringBitDepth, mnuNvDitheringMode });
@@ -427,14 +455,14 @@ namespace ColorControl.Services.NVIDIA
// miNvPresetApplyDithering
//
miNvPresetApplyDithering.Name = "miNvPresetApplyDithering";
miNvPresetApplyDithering.Size = new System.Drawing.Size(180, 22);
miNvPresetApplyDithering.Size = new System.Drawing.Size(122, 22);
miNvPresetApplyDithering.Text = "Included";
miNvPresetApplyDithering.Click += miNvPresetApplyDithering_Click;
//
// miNvPresetDitheringEnabled
//
miNvPresetDitheringEnabled.Name = "miNvPresetDitheringEnabled";
miNvPresetDitheringEnabled.Size = new System.Drawing.Size(180, 22);
miNvPresetDitheringEnabled.Size = new System.Drawing.Size(122, 22);
miNvPresetDitheringEnabled.Text = "Enabled";
miNvPresetDitheringEnabled.Click += miNvPresetDitheringEnabled_Click;
//
@@ -442,7 +470,7 @@ namespace ColorControl.Services.NVIDIA
//
mnuNvDitheringBitDepth.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { miNvDithering6bit, miNvDithering8bit, miNvDithering10bit });
mnuNvDitheringBitDepth.Name = "mnuNvDitheringBitDepth";
mnuNvDitheringBitDepth.Size = new System.Drawing.Size(180, 22);
mnuNvDitheringBitDepth.Size = new System.Drawing.Size(122, 22);
mnuNvDitheringBitDepth.Text = "Bit depth";
//
// miNvDithering6bit
@@ -473,7 +501,7 @@ namespace ColorControl.Services.NVIDIA
//
mnuNvDitheringMode.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { spatial1ToolStripMenuItem, spatial2ToolStripMenuItem, spatialDynamic2x2ToolStripMenuItem, spatialStatic2x2ToolStripMenuItem, temporalToolStripMenuItem });
mnuNvDitheringMode.Name = "mnuNvDitheringMode";
mnuNvDitheringMode.Size = new System.Drawing.Size(180, 22);
mnuNvDitheringMode.Size = new System.Drawing.Size(122, 22);
mnuNvDitheringMode.Text = "Mode";
//
// spatial1ToolStripMenuItem
@@ -584,7 +612,7 @@ namespace ColorControl.Services.NVIDIA
// miNvDriverSettingsIncluded
//
miNvDriverSettingsIncluded.Name = "miNvDriverSettingsIncluded";
miNvDriverSettingsIncluded.Size = new System.Drawing.Size(180, 22);
miNvDriverSettingsIncluded.Size = new System.Drawing.Size(120, 22);
miNvDriverSettingsIncluded.Text = "Included";
miNvDriverSettingsIncluded.Click += miNvDriverSettingsIncluded_Click;
//
@@ -598,7 +626,7 @@ namespace ColorControl.Services.NVIDIA
// miNvOtherIncluded
//
miNvOtherIncluded.Name = "miNvOtherIncluded";
miNvOtherIncluded.Size = new System.Drawing.Size(180, 22);
miNvOtherIncluded.Size = new System.Drawing.Size(120, 22);
miNvOtherIncluded.Text = "Included";
miNvOtherIncluded.Click += miNvOtherIncluded_Click;
//
@@ -612,7 +640,7 @@ namespace ColorControl.Services.NVIDIA
// miNvHdmiIncluded
//
miNvHdmiIncluded.Name = "miNvHdmiIncluded";
miNvHdmiIncluded.Size = new System.Drawing.Size(180, 22);
miNvHdmiIncluded.Size = new System.Drawing.Size(120, 22);
miNvHdmiIncluded.Text = "Included";
miNvHdmiIncluded.Click += miNvHdmiIncluded_Click;
//
@@ -728,32 +756,6 @@ namespace ColorControl.Services.NVIDIA
miNVIDIAInfo.Text = "NVIDIA Info";
miNVIDIAInfo.Click += miNVIDIAInfo_Click;
//
// mnuNvResolution
//
mnuNvResolution.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { miNvResolutionIncluded, mnuNvActiveResolution, mnuNvVirtualResolution });
mnuNvResolution.Name = "mnuNvResolution";
mnuNvResolution.Size = new System.Drawing.Size(184, 22);
mnuNvResolution.Text = "Resolution";
//
// miNvResolutionIncluded
//
miNvResolutionIncluded.Name = "miNvResolutionIncluded";
miNvResolutionIncluded.Size = new System.Drawing.Size(180, 22);
miNvResolutionIncluded.Text = "Included";
miNvResolutionIncluded.Click += miNvResolutionIncluded_Click;
//
// mnuNvActiveResolution
//
mnuNvActiveResolution.Name = "mnuNvActiveResolution";
mnuNvActiveResolution.Size = new System.Drawing.Size(180, 22);
mnuNvActiveResolution.Text = "Active";
//
// mnuNvVirtualResolution
//
mnuNvVirtualResolution.Name = "mnuNvVirtualResolution";
mnuNvVirtualResolution.Size = new System.Drawing.Size(180, 22);
mnuNvVirtualResolution.Text = "Virtual";
//
// NvPanel
//
AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
+81 -132
View File
@@ -34,7 +34,6 @@ namespace ColorControl.Services.NVIDIA
private NvService _nvService;
private readonly NotifyIconManager _notifyIconManager;
private readonly GlobalContext _globalContext;
private string _lastDisplayRefreshRates = string.Empty;
private RpcClientService _rpcService;
private readonly WinApiAdminService _winApiAdminService;
private readonly KeyboardShortcutDispatcher _keyboardShortcutDispatcher;
@@ -124,7 +123,7 @@ namespace ColorControl.Services.NVIDIA
private void UpdateDisplayInfoItems()
{
var displays = _nvService?.GetDisplayInfos();
var displays = _nvService.GetDisplayInfos();
if (displays == null || Program.IsRestarting)
{
return;
@@ -135,14 +134,12 @@ namespace ColorControl.Services.NVIDIA
{
var display = displayInfo.Display;
var id = Math.Abs((int)display.Handle.MemoryAddress.ToInt64());
ListViewItem item = null;
for (var i = 0; i < lvNvPresets.Items.Count; i++)
{
item = lvNvPresets.Items[i];
if (item.Tag == null && item.ImageIndex == id)
if (item.Tag == null && item.SubItems[1].Text == displayInfo.Name)
{
break;
}
@@ -151,12 +148,10 @@ namespace ColorControl.Services.NVIDIA
if (item == null)
{
item = lvNvPresets.Items.Add(display.Name);
item.ImageIndex = id;
item = lvNvPresets.Items.Add(displayInfo.Name);
item.Font = new Font(item.Font, item.Font.Style | FontStyle.Bold);
//item.BackColor = Color.LightGray;
}
item.BackColor = _globalContext.Config.UseDarkMode ? Color.DimGray : Color.LightGray;
item.BackColor = _globalContext.Config.UseDarkMode ? DarkModeUtils.ListViewDarkModeBackColor : Color.LightGray;
var values = displayInfo.Values;
@@ -350,6 +345,7 @@ namespace ColorControl.Services.NVIDIA
mnuNvOverclocking.Visible = preset != null && _nvService.Config.ShowOverclocking;
mnuNvOtherSettings.Enabled = preset != null;
miNvOtherIncluded.Visible = presetItemsVisible;
mnuNvHdmiSettings.Visible = !isCurrentDisplay || preset?.Display?.DisplayDevice.ConnectionType == NvAPIWrapper.Native.GPU.MonitorConnectionType.HDMI;
mnuNvHdmiSettings.Enabled = preset != null;
miNvHdmiIncluded.Visible = presetItemsVisible;
miHDROuputMode.Visible = _nvService.OutputModeAvailable;
@@ -370,7 +366,7 @@ namespace ColorControl.Services.NVIDIA
miNvPresetColorSettings.Visible = !isCurrentDisplay;
miNvPresetColorEnhancementsIncluded.Visible = !isCurrentDisplay;
miNvResolutionIncluded.Visible = !isCurrentDisplay;
miRefreshRateIncluded.Visible = !isCurrentDisplay;
miRefreshRateIncluded.Visible = true; // Workaround to make arrow visible
miHDRIncluded.Visible = !isCurrentDisplay;
miHDROutputModeUnchanged.Visible = !isCurrentDisplay;
miHDROutputModeHDR10.Checked = preset.HdrSettings.OutputMode == NvHdrSettings.NV_DISPLAY_OUTPUT_MODE.NV_DISPLAY_OUTPUT_MODE_HDR10;
@@ -378,13 +374,10 @@ namespace ColorControl.Services.NVIDIA
if (mnuNvDisplay.DropDownItems.Count == 1)
{
var displays = _nvService.GetDisplays();
for (var i = 0; i < displays.Length; i++)
var displays = _nvService.GetDisplayInfos();
foreach (var display in displays)
{
var display = displays[i];
var name = FormUtils.ExtendedDisplayName(display.Name);
var item = mnuNvDisplay.DropDownItems.AddCustom(name);
var item = mnuNvDisplay.DropDownItems.AddCustom(display.Name);
item.Tag = display;
item.Click += displayMenuItem_Click;
}
@@ -395,14 +388,17 @@ namespace ColorControl.Services.NVIDIA
FormUtils.BuildDropDownMenu(mnuNvPresetsColorSettings, "Dynamic range", typeof(ColorDataDynamicRange), preset.colorData, "DynamicRange", nvPresetColorDataMenuItem_Click);
FormUtils.BuildDropDownMenu(mnuNvPresetsColorSettings, "Color space", typeof(ColorDataColorimetry), preset.colorData, "Colorimetry", nvPresetColorDataMenuItem_Click);
BuildNvRefreshRateResolutionMenu(preset);
FormUtils.BuildDropDownMenu(mnuNvResolution, "Scaling/Aspect Ratio", typeof(CCD.DisplayConfigScaling), preset.DisplayConfig, "Scaling", UpdateDisplayConfigScaling, unchanged: false,
skipValues: [CCD.DisplayConfigScaling.Zero, CCD.DisplayConfigScaling.Custom, CCD.DisplayConfigScaling.ForceUint32]);
FormUtils.BuildDropDownMenu(mnuNvResolution, "Rotation", typeof(CCD.DisplayConfigRotation), preset.DisplayConfig, "Rotation", UpdateDisplayConfigRotation, unchanged: false,
skipValues: [CCD.DisplayConfigRotation.Zero, CCD.DisplayConfigRotation.ForceUint32]);
miNvPrimaryDisplay.Checked = preset.primaryDisplay;
foreach (var item in mnuNvDisplay.DropDownItems)
{
if (item is ToolStripMenuItem menuItem && menuItem.Tag != null)
{
menuItem.Checked = ((Display)menuItem.Tag).Name.Equals(preset.displayName);
menuItem.Checked = ((NvDisplayInfo)menuItem.Tag).DisplayId.Equals(preset.DisplayId);
}
}
@@ -509,7 +505,6 @@ namespace ColorControl.Services.NVIDIA
return;
}
var menuItem = (ToolStripItem)sender;
var currentSettings = (NvGpuOcSettings)menuItem.Tag;
@@ -528,95 +523,6 @@ namespace ColorControl.Services.NVIDIA
AddOrUpdateItem();
}
private void BuildNvRefreshRateResolutionMenu(NvPreset preset)
{
var displayName = preset.primaryDisplay ? null : preset.displayName;
if (displayName != _lastDisplayRefreshRates)
{
while (mnuRefreshRate.DropDownItems.Count > 1)
{
mnuRefreshRate.DropDownItems.RemoveAt(mnuRefreshRate.DropDownItems.Count - 1);
}
mnuNvActiveResolution.DropDownItems.Clear();
mnuNvVirtualResolution.DropDownItems.Clear();
}
if (mnuRefreshRate.DropDownItems.Count == 1)
{
var refreshRates = _nvService.GetAvailableRefreshRatesV2(preset);
_lastDisplayRefreshRates = displayName;
foreach (var refreshRate in refreshRates)
{
var item = mnuRefreshRate.DropDownItems.AddCustom(refreshRate.ToString() + "Hz");
item.Tag = refreshRate;
item.Click += refreshRateMenuItem_Click;
}
}
var modes = default(List<VirtualResolution>);
if (mnuNvActiveResolution.DropDownItems.Count == 0)
{
modes = _nvService.GetAvailableResolutionsV2(preset);
foreach (var mode in modes)
{
var item = mnuNvActiveResolution.DropDownItems.AddCustom(mode.ToString());
item.Tag = mode;
item.Click += resolutionNvMenuItem_Click;
}
}
if (mnuNvVirtualResolution.DropDownItems.Count == 0)
{
modes ??= _nvService.GetAvailableResolutionsV2(preset);
foreach (var mode in modes)
{
var item = mnuNvVirtualResolution.DropDownItems.AddCustom(mode.ToString());
item.Tag = mode;
item.Click += virtualResolutionNvMenuItem_Click;
}
}
miRefreshRateIncluded.Checked = preset.DisplayConfig.ApplyRefreshRate;
foreach (var item in mnuRefreshRate.DropDownItems)
{
if (item is ToolStripMenuItem menuItem && menuItem.Tag != null)
{
menuItem.Checked = ((Rational)menuItem.Tag).Equals(preset.DisplayConfig.RefreshRate);
}
}
miNvResolutionIncluded.Checked = preset.DisplayConfig.ApplyResolution;
foreach (var item in mnuNvActiveResolution.DropDownItems)
{
if (item is ToolStripMenuItem menuItem && menuItem.Tag != null)
{
var mode = (VirtualResolution)menuItem.Tag;
menuItem.Checked = mode.ActiveWidth == preset.DisplayConfig.Resolution.ActiveWidth && mode.ActiveHeight == preset.DisplayConfig.Resolution.ActiveHeight;
}
}
foreach (var item in mnuNvVirtualResolution.DropDownItems)
{
if (item is ToolStripMenuItem menuItem && menuItem.Tag != null)
{
var mode = (VirtualResolution)menuItem.Tag;
menuItem.Checked = mode.VirtualWidth == preset.DisplayConfig.Resolution.VirtualWidth && mode.VirtualHeight == preset.DisplayConfig.Resolution.VirtualHeight;
}
}
FormUtils.BuildDropDownMenu(mnuNvResolution, "Scaling/Aspect Ratio", typeof(CCD.DisplayConfigScaling), preset.DisplayConfig, "Scaling", UpdateDisplayConfigScaling, unchanged: false,
skipValues: [CCD.DisplayConfigScaling.Zero, CCD.DisplayConfigScaling.Custom, CCD.DisplayConfigScaling.ForceUint32]);
FormUtils.BuildDropDownMenu(mnuNvResolution, "Rotation", typeof(CCD.DisplayConfigRotation), preset.DisplayConfig, "Rotation", UpdateDisplayConfigRotation, unchanged: false,
skipValues: [CCD.DisplayConfigRotation.Zero, CCD.DisplayConfigRotation.ForceUint32]);
}
private void UpdateNvPresetMenuFont(bool updateTopItems = false)
{
foreach (var menu in mnuNvPresets.Items.OfType<ToolStripMenuItem>().Where(i => i != mnuNvDriverSettings))
@@ -1135,15 +1041,17 @@ namespace ColorControl.Services.NVIDIA
var menuItem = (ToolStripItem)sender;
if (menuItem.Tag != null)
{
var display = (Display)menuItem.Tag;
var displayInfo = (NvDisplayInfo)menuItem.Tag;
preset.displayName = display.Name;
preset.displayName = displayInfo.Name;
preset.DisplayId = displayInfo.DisplayId;
preset.primaryDisplay = false;
}
else
{
preset.primaryDisplay = true;
preset.displayName = null;
preset.DisplayId = null;
}
AddOrUpdateItem();
@@ -1181,37 +1089,19 @@ namespace ColorControl.Services.NVIDIA
return;
}
var display = displays.FirstOrDefault(d => d.ToString() == displayField.Value.ToString());
var preset = new NvPreset();
preset.name = nameField.Value.ToString();
preset.primaryDisplay = displayField.Value.ToString() == "Primary display";
preset.displayName = !preset.primaryDisplay ? displays.FirstOrDefault(d => d.ToString() == displayField.Value.ToString())?.Display?.Name : null;
preset.DisplayId = preset.primaryDisplay ? null : display?.DisplayId;
preset.displayName = preset.primaryDisplay ? null : display?.Name;
AskColorData(preset, colorSelectField.ValueAsBool);
AskResolution(preset, resolutionSelectField.ValueAsBool);
AskRefreshRate(preset, refreshRateSelectField.ValueAsBool);
AddOrUpdateItem(preset);
//var presets = NvPreset.GetDefaultPresets();
//var added = false;
//foreach (var preset in presets)
//{
// if (!_nvService.GetPresets().Any(x => x.colorData.Equals(preset.colorData)))
// {
// AddOrUpdateItem(preset);
// added = true;
// }
//}
//if (added)
//{
// MessageForms.InfoOk("Missing presets added.");
//}
//else
//{
// MessageForms.InfoOk("All presets for every color setting already exist.");
//}
}
private void AskColorData(NvPreset preset, bool ask = true)
@@ -2164,5 +2054,64 @@ namespace ColorControl.Services.NVIDIA
public void Init()
{
}
private void mnuRefreshRate_DropDownOpening(object sender, EventArgs e)
{
var preset = GetSelectedNvPreset(true);
if (preset == null)
{
return;
}
miRefreshRateIncluded.Visible = !preset.IsDisplayPreset;
miRefreshRateIncluded.Checked = preset.DisplayConfig.ApplyRefreshRate;
var refreshRates = _nvService.GetAvailableRefreshRatesV2(preset);
while (mnuRefreshRate.DropDownItems.Count > 1)
{
mnuRefreshRate.DropDownItems.RemoveAt(mnuRefreshRate.DropDownItems.Count - 1);
}
foreach (var refreshRate in refreshRates)
{
var item = mnuRefreshRate.DropDownItems.AddCustom(refreshRate.ToString() + "Hz") as ToolStripMenuItem;
item.Tag = refreshRate;
item.Click += refreshRateMenuItem_Click;
item.Checked = refreshRate.Equals(preset.DisplayConfig.RefreshRate);
}
UpdateNvPresetMenuFont();
}
private void mnuNvResolution_DropDownOpening(object sender, EventArgs e)
{
var preset = GetSelectedNvPreset(true);
miNvResolutionIncluded.Checked = preset.DisplayConfig.ApplyResolution;
mnuNvActiveResolution.DropDownItems.Clear();
mnuNvVirtualResolution.DropDownItems.Clear();
var modes = _nvService.GetAvailableResolutionsV2(preset);
foreach (var mode in modes)
{
var item = mnuNvActiveResolution.DropDownItems.AddCustom(mode.ToString()) as ToolStripMenuItem;
item.Tag = mode;
item.Click += resolutionNvMenuItem_Click;
item.Checked = mode.ActiveWidth == preset.DisplayConfig.Resolution.ActiveWidth && mode.ActiveHeight == preset.DisplayConfig.Resolution.ActiveHeight;
}
foreach (var mode in modes)
{
var item = mnuNvVirtualResolution.DropDownItems.AddCustom(mode.ToString()) as ToolStripMenuItem;
item.Tag = mode;
item.Click += virtualResolutionNvMenuItem_Click;
item.Checked = mode.VirtualWidth == preset.DisplayConfig.Resolution.VirtualWidth && mode.VirtualHeight == preset.DisplayConfig.Resolution.VirtualHeight;
}
UpdateNvPresetMenuFont();
}
}
}
+3 -1
View File
@@ -30,6 +30,7 @@ namespace ColorControl.Services.NVIDIA
public DisplayConfig DisplayConfig { get; set; }
public bool primaryDisplay { get; set; }
public string displayName { get; set; }
public string DisplayId { get; set; }
public uint ditheringBits { get; set; }
public uint ditheringMode { get; set; }
public bool applyOther { get; set; }
@@ -88,6 +89,7 @@ namespace ColorControl.Services.NVIDIA
primaryDisplay = preset.primaryDisplay;
displayName = preset.displayName;
DisplayId = preset.DisplayId;
var colorData = preset.colorData;
this.colorData = new ColorData(colorData.ColorFormat, dynamicRange: colorData.DynamicRange, colorDepth: colorData.ColorDepth, colorSelectionPolicy: ColorDataSelectionPolicy.User);
@@ -139,7 +141,7 @@ namespace ColorControl.Services.NVIDIA
isCurrent ? "Current settings" : name
};
var display = isCurrent ? displayName : string.Format("{0}", primaryDisplay ? "Primary" : displayName);
var display = isCurrent ? displayName : string.Format("{0}", primaryDisplay ? "Primary" : !displayName.IsNullOrEmpty() ? displayName : DisplayId);
values.Add(display);
var colorSettings = FormatDisplaySetting(string.Format("{0}, {1}, {2}, {3}", colorData.ColorDepth, colorData.ColorFormat, colorData.DynamicRange, colorData.Colorimetry), isCurrent, applyColorData);
+49 -37
View File
@@ -12,6 +12,7 @@ using Newtonsoft.Json;
using novideo_srgb;
using nspector.Common;
using nspector.Common.Meta;
using NStandard;
using NvAPIWrapper.Display;
using NvAPIWrapper.GPU;
using NvAPIWrapper.Native;
@@ -275,9 +276,9 @@ namespace ColorControl.Services.NVIDIA
}
}
public Display GetCurrentDisplay()
public Display GetCurrentDisplay(bool checkDisplays = true)
{
if (!HasDisplaysAttached())
if (checkDisplays && !HasDisplaysAttached())
{
_currentDisplay = null;
return null;
@@ -341,12 +342,19 @@ namespace ColorControl.Services.NVIDIA
private Display GetPresetDisplay(NvPreset preset)
{
if (preset.Display != null)
{
return preset.Display;
}
if (preset.primaryDisplay)
{
return GetPrimaryDisplay();
}
return Display.GetDisplays().FirstOrDefault(x => x.Name.Equals(preset.displayName));
var displays = GetSimpleDisplayInfos();
return displays.FirstOrDefault(d => d.DisplayId == preset.DisplayId)?.Display;
}
public Display GetPrimaryDisplay()
@@ -937,25 +945,14 @@ namespace ColorControl.Services.NVIDIA
if (setRegistryKey)
{
var displays = WindowsDisplayAPI.Display.GetDisplays();
var path = displays.FirstOrDefault(x => x.DisplayName == display.Name)?.DevicePath;
var info = CCD.GetDisplayInfo(display.Name);
var regId = info?.DisplayId;
if (path == null)
if (regId.IsNullOrEmpty())
{
Logger.Debug($"Cannot find path for display {display.Name}");
return false;
}
var parts = path.Split('#');
if (parts.Length < 2)
{
Logger.Debug($"Incorrect path for display {display.Name}");
return false;
}
var regId = parts[1];
result = SetDitherRegistryKey(regId, (uint)state, bits, mode);
if (restartDriver)
@@ -1064,13 +1061,15 @@ namespace ColorControl.Services.NVIDIA
SetCurrentDisplay(preset);
}
var display = GetCurrentDisplay();
var display = GetCurrentDisplay(false);
if (display == null)
{
return [];
}
var desktopRect = GetDesktopRect(display);
var desktopRect = preset?.DisplayConfig.ApplyResolution == true && preset?.DisplayConfig.Resolution.ActiveWidth > 0 ?
new Rectangle(0, 0, (int)preset.DisplayConfig.Resolution.ActiveWidth, (int)preset.DisplayConfig.Resolution.ActiveHeight) :
GetDesktopRect(display);
return GetAvailableRefreshRatesV2(display.Name, desktopRect.Width, desktopRect.Height);
}
@@ -1082,7 +1081,7 @@ namespace ColorControl.Services.NVIDIA
SetCurrentDisplay(preset);
}
var display = GetCurrentDisplay();
var display = GetCurrentDisplay(false);
if (display == null)
{
return [];
@@ -1218,6 +1217,11 @@ namespace ColorControl.Services.NVIDIA
{
var displayDevice = display.DisplayDevice;
if (displayDevice.ConnectionType != NvAPIWrapper.Native.GPU.MonitorConnectionType.HDMI)
{
return null;
}
return Logger.Swallow(() => displayDevice.HDMIVideoFrameOverrideInformation) ?? Logger.Swallow(() => displayDevice.HDMIVideoFrameCurrentInformation);
}
@@ -1237,7 +1241,10 @@ namespace ColorControl.Services.NVIDIA
public void SetScaling(Display display, Scaling scaling)
{
var pathInfo = GetPathInfoForDisplay(display);
var pathInfos = DisplayApi.GetDisplayConfig().ToList();
var pathInfo = pathInfos.FirstOrDefault(c => c.TargetsInfo.Any(ti => ti.DisplayId == display.DisplayDevice.DisplayId));
var pathInfoIndex = pathInfos.IndexOf(pathInfo);
var pathTargetInfo = pathInfo.TargetsInfo.FirstOrDefault(ti => ti.DisplayId == display.DisplayDevice.DisplayId);
@@ -1254,7 +1261,10 @@ namespace ColorControl.Services.NVIDIA
var newPathInfo = new PathInfoV2(new[] { newPathTargetInfo }, pathInfo.SourceModeInfo);
DisplayApi.SetDisplayConfig(new IPathInfo[] { newPathInfo }, DisplayConfigFlags.SaveToPersistence);
var newPathInfos = pathInfos.ToArray();
newPathInfos[pathInfoIndex] = newPathInfo;
DisplayApi.SetDisplayConfig(newPathInfos, DisplayConfigFlags.SaveToPersistence);
}
private IPathTargetInfo? GetTargetInfoForDisplay(Display display)
@@ -1431,9 +1441,7 @@ namespace ColorControl.Services.NVIDIA
foreach (var display in displays)
{
var name = FormUtils.ExtendedDisplayName(display.Name);
var displayInfo = new NvDisplayInfo(display, null, null, name);
var displayInfo = new NvDisplayInfo(display, null, null);
list.Add(displayInfo);
}
@@ -1445,7 +1453,6 @@ namespace ColorControl.Services.NVIDIA
{
try
{
var displays = GetDisplays();
var list = new List<NvDisplayInfo>();
if (refreshSettings)
@@ -1453,12 +1460,15 @@ namespace ColorControl.Services.NVIDIA
RefreshProfileSettings();
}
foreach (var display in displays)
{
var preset = GetPresetForDisplay(display, true, displays.Count());
var displayInfos = GetSimpleDisplayInfos();
foreach (var displayInfo in displayInfos)
{
var preset = GetPresetForDisplay(displayInfo, true, displayInfos.Count());
var values = preset.GetDisplayValues(_globalContext.Config);
var displayInfo = new NvDisplayInfo(display, values, preset.InfoLine, preset.displayName);
displayInfo.Values = values;
displayInfo.InfoLine = preset.InfoLine;
list.Add(displayInfo);
}
@@ -1479,29 +1489,31 @@ namespace ColorControl.Services.NVIDIA
}
}
public NvPreset GetPresetForDisplay(string displayName, bool driverSettings = false)
public NvPreset GetPresetForDisplay(string name, bool driverSettings = false)
{
var displays = GetDisplays();
var display = displays.FirstOrDefault(d => displayName.StartsWith(d.Name));
var displays = GetSimpleDisplayInfos();
var display = displays.FirstOrDefault(d => name.StartsWith(d.Name));
return GetPresetForDisplay(display, driverSettings, displays.Count());
}
public NvPreset GetPresetForDisplay(Display display, bool driverSettings = false, int displayCount = 1)
public NvPreset GetPresetForDisplay(NvDisplayInfo displayInfo, bool driverSettings = false, int displayCount = 1)
{
if (display == null)
if (displayInfo == null)
{
return null;
}
var display = displayInfo.Display;
var isPrimaryDisplay = displayCount == 1 || display.DisplayDevice.DisplayId == DisplayDevice.GetGDIPrimaryDisplayDevice()?.DisplayId;
var preset = new NvPreset { Display = display, IsDisplayPreset = true, applyColorData = false, primaryDisplay = isPrimaryDisplay };
preset.HDREnabled = IsHDREnabled(display);
preset.HdrSettings.OutputMode = preset.HDREnabled && OutputModeAvailable ? GetOutputMode(display) : null;
preset.displayName = FormUtils.ExtendedDisplayName(display.Name);
preset.DisplayId = displayInfo.DisplayId;
preset.displayName = displayInfo.Name;
preset.colorData = GetCurrentColorData(display);
preset.ColorEnhancementSettings = GetCurrentColorEnhancements(display);
preset.HdmiInfoFrameSettings = GetHdmiSettings(display);
@@ -710,7 +710,7 @@ namespace ColorControl.Services.Samsung
SubLabel = "Both types will not reset your settings. 'FactoryMenu' is recommended for 2024 series but will also work for older ones. Click 'Next >' to continue or 'X' to stop",
FieldType = FieldType.DropDown,
Values = serviceMenuTypes,
Value = ServiceMenuType.HospitalityMenu
Value = ServiceMenuType.FactoryMenu
};
if (!MessageForms.ShowDialog($"Access Service Menu", [serviceMenuTypeField], okButtonText: "Next >").Any())
+1 -1
View File
@@ -53,7 +53,7 @@ public class CustomDisplay
public override string ToString()
{
return $"{FormUtils.ExtendedDisplayName(Display.DisplayName)} on {Display.Adapter.DeviceName}";
return $"{CCD.GetDisplayInfo(Display.DisplayName)} on {Display.Adapter.DeviceName}";
}
}
+1
View File
@@ -41,6 +41,7 @@
public List<Module> Modules { get; set; }
public bool UseRawInput { get; set; }
public bool SetMinTmlAndMaxTml { get; set; }
public bool DisableErrorPopupWhenApplyingPreset { get; set; }
public Config()
{
@@ -19,6 +19,7 @@ public class WindowMessageDispatcher : EventDispatcher<WindowMessageEventArgs>
public const string Event_WindowMessageHotKey = "WindowMessageHotKey";
public const string Event_WindowMessageInput = "WindowMessageInput";
public const string Event_WindowMessageQueryEndSession = "WindowMessageQueryEndSession";
public const string Event_WindowMessageEndSession = "WindowMessageEndSession";
public const string Event_WindowMessageClose = "WindowMessageClose";
public const string Event_WindowMessagePowerBroadcast = "WindowMessagePowerBroadcast";
public const string Event_WindowMessageShowWindow = "WindowMessageShowWindow";
@@ -27,12 +28,14 @@ public class WindowMessageDispatcher : EventDispatcher<WindowMessageEventArgs>
private static readonly NLog.Logger Logger = NLog.LogManager.GetCurrentClassLogger();
private readonly GlobalContext _globalContext;
public DummyForm MessageForm { get; set; }
public DummyForm MessageForm { get; private set; }
private static Dictionary<int, string> Messages = new() {
{ NativeConstants.WM_HOTKEY, Event_WindowMessageHotKey },
{ NativeConstants.WM_INPUT, Event_WindowMessageInput },
{ NativeConstants.WM_QUERYENDSESSION, Event_WindowMessageQueryEndSession },
{ NativeConstants.WM_ENDSESSION, Event_WindowMessageEndSession },
{ NativeConstants.WM_CLOSE, Event_WindowMessageClose },
{ NativeConstants.WM_POWERBROADCAST, Event_WindowMessagePowerBroadcast },
{ NativeConstants.WM_SHOWWINDOW, Event_WindowMessageShowWindow },
@@ -60,25 +63,12 @@ public class WindowMessageDispatcher : EventDispatcher<WindowMessageEventArgs>
{
public event EventHandler<Message> OnMessage;
private bool _systemShutdown;
public DummyForm()
{
FormBorderStyle = FormBorderStyle.None;
ShowInTaskbar = false;
Load += DummyForm_Load;
Shown += DummyForm_Shown;
FormClosing += DummyForm_FormClosing;
}
private void DummyForm_FormClosing(object sender, FormClosingEventArgs e)
{
Logger.Debug($"FormClosing: {_systemShutdown}");
if (_systemShutdown)
{
OnMessage?.Invoke(this, new Message { Msg = NativeConstants.WM_CLOSE });
}
}
private void DummyForm_Shown(object sender, EventArgs e)
@@ -95,7 +85,7 @@ public class WindowMessageDispatcher : EventDispatcher<WindowMessageEventArgs>
{
if (m.Msg == NativeConstants.WM_QUERYENDSESSION)
{
_systemShutdown = true;
Logger.Debug("WM_QUERYENDSESSION");
}
OnMessage?.Invoke(this, m);
+1
View File
@@ -12,6 +12,7 @@ namespace ColorControl.Shared.Forms
private static ToolStripRenderer _defaultRenderer;
private static Type[] _windowColorTypes = new[] { typeof(GroupBox), typeof(TabPage), typeof(UserControl) };
public const int DWMWA_USE_IMMERSIVE_DARK_MODE = 20;
public static readonly Color ListViewDarkModeBackColor = Color.FromArgb(80, 80, 80);
public class DarkModeToolStripRenderer : ToolStripProfessionalRenderer
{
-13
View File
@@ -1,6 +1,5 @@
using ColorControl.Shared.Common;
using ColorControl.Shared.Contracts;
using ColorControl.Shared.Native;
using NStandard;
using NWin32;
using System.Collections;
@@ -523,18 +522,6 @@ namespace ColorControl.Shared.Forms
eventHandlerList.Dispose();
}
public static string ExtendedDisplayName(string displayName)
{
var name = displayName;
var screen = Screen.AllScreens.FirstOrDefault(x => x.DeviceName.Equals(name));
if (screen != null)
{
name += " (" + screen.DeviceFriendlyName() + ")";
}
return name;
}
public static IntPtr GetMonitorForDisplayName(string displayName)
{
var name = displayName;
+123 -27
View File
@@ -1,6 +1,7 @@
using ColorControl.Shared.Contracts;
using ColorControl.Shared.Forms;
using MHC2Gen;
using NStandard;
using NWin32;
using System.ComponentModel;
using System.IO;
@@ -9,6 +10,30 @@ using System.Runtime.InteropServices;
namespace ColorControl.Shared.Native
{
public class DisplayInfo(string displayName, string friendlyName, string devicePath)
{
public string DisplayName { get; } = displayName;
public string FriendlyName { get; } = friendlyName;
public string DevicePath { get; } = devicePath;
private string _displayId;
public string DisplayId
{
get
{
if (_displayId == null)
{
_displayId = CCD.GetDisplayIdByPath(DevicePath);
}
return _displayId;
}
}
public string ExtendedName => $"{FriendlyName} ({DisplayId})";
public override string ToString() => ExtendedName;
}
// This class takes care of wrapping "Connecting and Configuring Displays(CCD) Win32 API"
public static class CCD
{
@@ -25,6 +50,25 @@ namespace ColorControl.Shared.Native
Clone
}
public static string GetDisplayIdByPath(string displayPath)
{
if (displayPath == null)
{
Logger.Debug($"Cannot find path for display with path {displayPath}");
return null;
}
var parts = displayPath.Split('#');
if (parts.Length < 2)
{
Logger.Debug($"Incorrect path for display with path {displayPath}");
return null;
}
return parts[1];
}
public static double GetDpiForSystem()
{
var dpi = NativeMethods.GetDpiForSystem();
@@ -119,28 +163,60 @@ namespace ColorControl.Shared.Native
return false;
}
var pathIndex = pathsArray.IndexOf(p => MatchDisplayNames(p, displayName));
if (pathIndex == -1)
{
return false;
}
var sourceIndex = pathsArray[pathIndex].sourceInfo.modeInfoIdx;
var targetIndex = pathsArray[pathIndex].targetInfo.modeInfoIdx;
var resolution = displayConfig.Resolution;
var refreshRate = displayConfig.RefreshRate;
foreach (var path in pathsArray)
var isModeChangeNeeded = false;
if (modesArray[targetIndex].targetMode.targetVideoSignalInfo.vSyncFreq.numerator != refreshRate.Numerator ||
modesArray[targetIndex].targetMode.targetVideoSignalInfo.vSyncFreq.denominator != refreshRate.Denominator)
{
if (!MatchDisplayNames(path, displayName))
{
continue;
}
modesArray[targetIndex].targetMode.targetVideoSignalInfo.vSyncFreq = new DisplayConfigRational { denominator = refreshRate.Denominator, numerator = refreshRate.Numerator };
isModeChangeNeeded = true;
}
var sourceIndex = path.sourceInfo.modeInfoIdx;
var targetIndex = path.targetInfo.modeInfoIdx;
var sourceMode = modesArray[sourceIndex];
var targetMode = modesArray[targetIndex];
if (modesArray[targetIndex].targetMode.targetVideoSignalInfo.activeSize.cx != resolution.ActiveWidth ||
modesArray[targetIndex].targetMode.targetVideoSignalInfo.activeSize.cy != resolution.ActiveHeight)
{
modesArray[targetIndex].targetMode.targetVideoSignalInfo.activeSize.cx = resolution.ActiveWidth;
modesArray[targetIndex].targetMode.targetVideoSignalInfo.activeSize.cy = resolution.ActiveHeight;
isModeChangeNeeded = true;
}
targetMode.targetMode.targetVideoSignalInfo.vSyncFreq = new DisplayConfigRational { denominator = refreshRate.Denominator, numerator = refreshRate.Numerator };
targetMode.targetMode.targetVideoSignalInfo.activeSize.cx = resolution.ActiveWidth;
targetMode.targetMode.targetVideoSignalInfo.activeSize.cy = resolution.ActiveHeight;
if (modesArray[sourceIndex].sourceMode.width != resolution.VirtualWidth || modesArray[sourceIndex].sourceMode.height != resolution.VirtualHeight)
{
modesArray[sourceIndex].sourceMode.width = resolution.VirtualWidth;
modesArray[sourceIndex].sourceMode.height = resolution.VirtualHeight;
isModeChangeNeeded = true;
}
sourceMode.sourceMode.width = resolution.VirtualWidth;
sourceMode.sourceMode.height = resolution.VirtualHeight;
var newScaling = displayConfig.Scaling == DisplayConfigScaling.Zero ? DisplayConfigScaling.Identity : displayConfig.Scaling;
if (pathsArray[pathIndex].targetInfo.scaling != newScaling)
{
pathsArray[pathIndex].targetInfo.scaling = newScaling;
isModeChangeNeeded = true;
}
var newRotation = displayConfig.Rotation == DisplayConfigRotation.Zero ? DisplayConfigRotation.Identity : displayConfig.Rotation;
if (pathsArray[pathIndex].targetInfo.rotation != newRotation)
{
pathsArray[pathIndex].targetInfo.rotation = newRotation;
isModeChangeNeeded = true;
}
//pathsArray[pathIndex].targetInfo.refreshRate = new DisplayConfigRational { numerator = displayConfig.RefreshRate.Numerator, denominator = displayConfig.RefreshRate.Denominator };
if (isModeChangeNeeded)
{
var flags = SdcFlags.Apply | SdcFlags.UseSuppliedDisplayConfig | SdcFlags.AllowChanges;
if (updateRegistry)
@@ -148,17 +224,10 @@ namespace ColorControl.Shared.Native
flags |= SdcFlags.SaveToDatabase;
}
var path2 = path;
path2.targetInfo.scaling = displayConfig.Scaling == DisplayConfigScaling.Zero ? DisplayConfigScaling.Identity : displayConfig.Scaling;
path2.targetInfo.rotation = displayConfig.Rotation == DisplayConfigRotation.Zero ? DisplayConfigRotation.Identity : displayConfig.Rotation;
path2.targetInfo.refreshRate = new DisplayConfigRational { numerator = displayConfig.RefreshRate.Numerator, denominator = displayConfig.RefreshRate.Denominator };
err = NativeMethods.SetDisplayConfig(1, [path2], 2, [targetMode, sourceMode], flags);
return err == 0;
err = NativeMethods.SetDisplayConfig(pathCount, pathsArray, modeCount, modesArray, flags);
}
return false;
return err == 0;
}
finally
{
@@ -363,7 +432,7 @@ namespace ColorControl.Shared.Native
public static bool GetUsePerUserDisplayProfiles(string displayName)
{
var deviceKey = GetDisplayDeviceKey(displayName);
var deviceKey = GetDisplayDeviceRegistryKey(displayName);
if (deviceKey == null)
{
@@ -385,7 +454,7 @@ namespace ColorControl.Shared.Native
public static bool SetUsePerUserDisplayProfiles(string displayName, bool usePerUserProfiles)
{
var deviceKey = GetDisplayDeviceKey(displayName);
var deviceKey = GetDisplayDeviceRegistryKey(displayName);
if (deviceKey == null)
{
@@ -397,7 +466,7 @@ namespace ColorControl.Shared.Native
return result;
}
private static string GetDisplayDeviceKey(string displayName)
private static string GetDisplayDeviceRegistryKey(string displayName)
{
var hMonitor = FormUtils.GetMonitorForDisplayName(displayName);
@@ -423,6 +492,33 @@ namespace ColorControl.Shared.Native
return dd.DeviceKey;
}
public static DisplayInfo GetDisplayInfo(string displayName)
{
return ExecuteForModeConfig((modeInfo) =>
{
if (modeInfo.infoType == DisplayConfigModeInfoType.Target)
{
var requestpacket = new DISPLAYCONFIG_TARGET_DEVICE_NAME();
requestpacket.header = new DISPLAYCONFIG_DEVICE_INFO_HEADER();
requestpacket.header.type = DISPLAYCONFIG_DEVICE_INFO_TYPE.DISPLAYCONFIG_DEVICE_INFO_GET_TARGET_NAME;
requestpacket.header.size = Marshal.SizeOf<DISPLAYCONFIG_TARGET_DEVICE_NAME>();
requestpacket.header.adapterId = modeInfo.adapterId;
requestpacket.header.id = modeInfo.id;
var err = NativeMethods.DisplayConfigGetDeviceInfo(ref requestpacket);
if (err == NativeConstants.ERROR_SUCCESS)
{
return (new DisplayInfo(displayName, requestpacket.monitorFriendlyDeviceName, requestpacket.monitorDevicePath), false);
}
}
return (null, true);
}, displayName
);
}
public static uint GetSDRWhiteLevel(string displayName = null)
{
return ExecuteForModeConfig<uint>((modeInfo) =>
@@ -1219,7 +1315,7 @@ namespace ColorControl.Shared.Native
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]
public string monitorFriendlyDeviceName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
public string monitorDevicePat;
public string monitorDevicePath;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
+2 -2
View File
@@ -3851,9 +3851,9 @@ public class DXWrapper : DXNativeMethods
//ADAPTER_DESC1 aDAPTER_DESC1 = new ADAPTER_DESC1();
//adapter.GetDesc1(out aDAPTER_DESC1);
for (var o = 0; ; o++)
for (uint o = 0; ; o++)
{
if (!Ok(adapter.EnumOutputs(0, out var output)))
if (!Ok(adapter.EnumOutputs(o, out var output)))
{
break;
}
-309
View File
@@ -1,309 +0,0 @@
using System.ComponentModel;
using System.Runtime.InteropServices;
namespace ColorControl.Shared.Native
{
public static class ScreenInterrogatory
{
public const int ERROR_SUCCESS = 0;
#region enums
public enum QUERY_DEVICE_CONFIG_FLAGS : uint
{
QDC_ALL_PATHS = 0x00000001,
QDC_ONLY_ACTIVE_PATHS = 0x00000002,
QDC_DATABASE_CURRENT = 0x00000004
}
public enum DISPLAYCONFIG_VIDEO_OUTPUT_TECHNOLOGY : uint
{
DISPLAYCONFIG_OUTPUT_TECHNOLOGY_OTHER = 0xFFFFFFFF,
DISPLAYCONFIG_OUTPUT_TECHNOLOGY_HD15 = 0,
DISPLAYCONFIG_OUTPUT_TECHNOLOGY_SVIDEO = 1,
DISPLAYCONFIG_OUTPUT_TECHNOLOGY_COMPOSITE_VIDEO = 2,
DISPLAYCONFIG_OUTPUT_TECHNOLOGY_COMPONENT_VIDEO = 3,
DISPLAYCONFIG_OUTPUT_TECHNOLOGY_DVI = 4,
DISPLAYCONFIG_OUTPUT_TECHNOLOGY_HDMI = 5,
DISPLAYCONFIG_OUTPUT_TECHNOLOGY_LVDS = 6,
DISPLAYCONFIG_OUTPUT_TECHNOLOGY_D_JPN = 8,
DISPLAYCONFIG_OUTPUT_TECHNOLOGY_SDI = 9,
DISPLAYCONFIG_OUTPUT_TECHNOLOGY_DISPLAYPORT_EXTERNAL = 10,
DISPLAYCONFIG_OUTPUT_TECHNOLOGY_DISPLAYPORT_EMBEDDED = 11,
DISPLAYCONFIG_OUTPUT_TECHNOLOGY_UDI_EXTERNAL = 12,
DISPLAYCONFIG_OUTPUT_TECHNOLOGY_UDI_EMBEDDED = 13,
DISPLAYCONFIG_OUTPUT_TECHNOLOGY_SDTVDONGLE = 14,
DISPLAYCONFIG_OUTPUT_TECHNOLOGY_MIRACAST = 15,
DISPLAYCONFIG_OUTPUT_TECHNOLOGY_INTERNAL = 0x80000000,
DISPLAYCONFIG_OUTPUT_TECHNOLOGY_FORCE_UINT32 = 0xFFFFFFFF
}
public enum DISPLAYCONFIG_SCANLINE_ORDERING : uint
{
DISPLAYCONFIG_SCANLINE_ORDERING_UNSPECIFIED = 0,
DISPLAYCONFIG_SCANLINE_ORDERING_PROGRESSIVE = 1,
DISPLAYCONFIG_SCANLINE_ORDERING_INTERLACED = 2,
DISPLAYCONFIG_SCANLINE_ORDERING_INTERLACED_UPPERFIELDFIRST = DISPLAYCONFIG_SCANLINE_ORDERING_INTERLACED,
DISPLAYCONFIG_SCANLINE_ORDERING_INTERLACED_LOWERFIELDFIRST = 3,
DISPLAYCONFIG_SCANLINE_ORDERING_FORCE_UINT32 = 0xFFFFFFFF
}
public enum DISPLAYCONFIG_ROTATION : uint
{
DISPLAYCONFIG_ROTATION_IDENTITY = 1,
DISPLAYCONFIG_ROTATION_ROTATE90 = 2,
DISPLAYCONFIG_ROTATION_ROTATE180 = 3,
DISPLAYCONFIG_ROTATION_ROTATE270 = 4,
DISPLAYCONFIG_ROTATION_FORCE_UINT32 = 0xFFFFFFFF
}
public enum DISPLAYCONFIG_SCALING : uint
{
DISPLAYCONFIG_SCALING_IDENTITY = 1,
DISPLAYCONFIG_SCALING_CENTERED = 2,
DISPLAYCONFIG_SCALING_STRETCHED = 3,
DISPLAYCONFIG_SCALING_ASPECTRATIOCENTEREDMAX = 4,
DISPLAYCONFIG_SCALING_CUSTOM = 5,
DISPLAYCONFIG_SCALING_PREFERRED = 128,
DISPLAYCONFIG_SCALING_FORCE_UINT32 = 0xFFFFFFFF
}
public enum DISPLAYCONFIG_PIXELFORMAT : uint
{
DISPLAYCONFIG_PIXELFORMAT_8BPP = 1,
DISPLAYCONFIG_PIXELFORMAT_16BPP = 2,
DISPLAYCONFIG_PIXELFORMAT_24BPP = 3,
DISPLAYCONFIG_PIXELFORMAT_32BPP = 4,
DISPLAYCONFIG_PIXELFORMAT_NONGDI = 5,
DISPLAYCONFIG_PIXELFORMAT_FORCE_UINT32 = 0xffffffff
}
public enum DISPLAYCONFIG_MODE_INFO_TYPE : uint
{
DISPLAYCONFIG_MODE_INFO_TYPE_SOURCE = 1,
DISPLAYCONFIG_MODE_INFO_TYPE_TARGET = 2,
DISPLAYCONFIG_MODE_INFO_TYPE_FORCE_UINT32 = 0xFFFFFFFF
}
public enum DISPLAYCONFIG_DEVICE_INFO_TYPE : uint
{
DISPLAYCONFIG_DEVICE_INFO_GET_SOURCE_NAME = 1,
DISPLAYCONFIG_DEVICE_INFO_GET_TARGET_NAME = 2,
DISPLAYCONFIG_DEVICE_INFO_GET_TARGET_PREFERRED_MODE = 3,
DISPLAYCONFIG_DEVICE_INFO_GET_ADAPTER_NAME = 4,
DISPLAYCONFIG_DEVICE_INFO_SET_TARGET_PERSISTENCE = 5,
DISPLAYCONFIG_DEVICE_INFO_GET_TARGET_BASE_TYPE = 6,
DISPLAYCONFIG_DEVICE_INFO_FORCE_UINT32 = 0xFFFFFFFF
}
#endregion
#region structs
[StructLayout(LayoutKind.Sequential)]
public struct LUID
{
public uint LowPart;
public int HighPart;
}
[StructLayout(LayoutKind.Sequential)]
public struct DISPLAYCONFIG_PATH_SOURCE_INFO
{
public LUID adapterId;
public uint id;
public uint modeInfoIdx;
public uint statusFlags;
}
[StructLayout(LayoutKind.Sequential)]
public struct DISPLAYCONFIG_PATH_TARGET_INFO
{
public LUID adapterId;
public uint id;
public uint modeInfoIdx;
private DISPLAYCONFIG_VIDEO_OUTPUT_TECHNOLOGY outputTechnology;
private DISPLAYCONFIG_ROTATION rotation;
private DISPLAYCONFIG_SCALING scaling;
private DISPLAYCONFIG_RATIONAL refreshRate;
private DISPLAYCONFIG_SCANLINE_ORDERING scanLineOrdering;
public bool targetAvailable;
public uint statusFlags;
}
[StructLayout(LayoutKind.Sequential)]
public struct DISPLAYCONFIG_RATIONAL
{
public uint Numerator;
public uint Denominator;
}
[StructLayout(LayoutKind.Sequential)]
public struct DISPLAYCONFIG_PATH_INFO
{
public DISPLAYCONFIG_PATH_SOURCE_INFO sourceInfo;
public DISPLAYCONFIG_PATH_TARGET_INFO targetInfo;
public uint flags;
}
[StructLayout(LayoutKind.Sequential)]
public struct DISPLAYCONFIG_2DREGION
{
public uint cx;
public uint cy;
}
[StructLayout(LayoutKind.Sequential)]
public struct DISPLAYCONFIG_VIDEO_SIGNAL_INFO
{
public ulong pixelRate;
public DISPLAYCONFIG_RATIONAL hSyncFreq;
public DISPLAYCONFIG_RATIONAL vSyncFreq;
public DISPLAYCONFIG_2DREGION activeSize;
public DISPLAYCONFIG_2DREGION totalSize;
public uint videoStandard;
public DISPLAYCONFIG_SCANLINE_ORDERING scanLineOrdering;
}
[StructLayout(LayoutKind.Sequential)]
public struct DISPLAYCONFIG_TARGET_MODE
{
public DISPLAYCONFIG_VIDEO_SIGNAL_INFO targetVideoSignalInfo;
}
[StructLayout(LayoutKind.Sequential)]
public struct POINTL
{
private int x;
private int y;
}
[StructLayout(LayoutKind.Sequential)]
public struct DISPLAYCONFIG_SOURCE_MODE
{
public uint width;
public uint height;
public DISPLAYCONFIG_PIXELFORMAT pixelFormat;
public POINTL position;
}
[StructLayout(LayoutKind.Explicit)]
public struct DISPLAYCONFIG_MODE_INFO_UNION
{
[FieldOffset(0)]
public DISPLAYCONFIG_TARGET_MODE targetMode;
[FieldOffset(0)]
public DISPLAYCONFIG_SOURCE_MODE sourceMode;
}
[StructLayout(LayoutKind.Sequential)]
public struct DISPLAYCONFIG_MODE_INFO
{
public DISPLAYCONFIG_MODE_INFO_TYPE infoType;
public uint id;
public LUID adapterId;
public DISPLAYCONFIG_MODE_INFO_UNION modeInfo;
}
[StructLayout(LayoutKind.Sequential)]
public struct DISPLAYCONFIG_TARGET_DEVICE_NAME_FLAGS
{
public uint value;
}
[StructLayout(LayoutKind.Sequential)]
public struct DISPLAYCONFIG_DEVICE_INFO_HEADER
{
public DISPLAYCONFIG_DEVICE_INFO_TYPE type;
public uint size;
public LUID adapterId;
public uint id;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct DISPLAYCONFIG_TARGET_DEVICE_NAME
{
public DISPLAYCONFIG_DEVICE_INFO_HEADER header;
public DISPLAYCONFIG_TARGET_DEVICE_NAME_FLAGS flags;
public DISPLAYCONFIG_VIDEO_OUTPUT_TECHNOLOGY outputTechnology;
public ushort edidManufactureId;
public ushort edidProductCodeId;
public uint connectorInstance;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]
public string monitorFriendlyDeviceName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
public string monitorDevicePath;
}
#endregion
#region DLL-Imports
[DllImport("user32.dll")]
public static extern int GetDisplayConfigBufferSizes(
QUERY_DEVICE_CONFIG_FLAGS flags, out uint numPathArrayElements, out uint numModeInfoArrayElements);
[DllImport("user32.dll")]
public static extern int QueryDisplayConfig(
QUERY_DEVICE_CONFIG_FLAGS flags,
ref uint numPathArrayElements, [Out] DISPLAYCONFIG_PATH_INFO[] PathInfoArray,
ref uint numModeInfoArrayElements, [Out] DISPLAYCONFIG_MODE_INFO[] ModeInfoArray,
IntPtr currentTopologyId
);
[DllImport("user32.dll")]
public static extern int DisplayConfigGetDeviceInfo(ref DISPLAYCONFIG_TARGET_DEVICE_NAME deviceName);
#endregion
private static string MonitorFriendlyName(LUID adapterId, uint targetId)
{
var deviceName = new DISPLAYCONFIG_TARGET_DEVICE_NAME
{
header =
{
size = (uint)Marshal.SizeOf(typeof (DISPLAYCONFIG_TARGET_DEVICE_NAME)),
adapterId = adapterId,
id = targetId,
type = DISPLAYCONFIG_DEVICE_INFO_TYPE.DISPLAYCONFIG_DEVICE_INFO_GET_TARGET_NAME
}
};
var error = DisplayConfigGetDeviceInfo(ref deviceName);
if (error != ERROR_SUCCESS)
throw new Win32Exception(error);
return deviceName.monitorFriendlyDeviceName;
}
private static IEnumerable<string> GetAllMonitorsFriendlyNames()
{
uint pathCount, modeCount;
var error = GetDisplayConfigBufferSizes(QUERY_DEVICE_CONFIG_FLAGS.QDC_ONLY_ACTIVE_PATHS, out pathCount, out modeCount);
if (error != ERROR_SUCCESS)
throw new Win32Exception(error);
var displayPaths = new DISPLAYCONFIG_PATH_INFO[pathCount];
var displayModes = new DISPLAYCONFIG_MODE_INFO[modeCount];
error = QueryDisplayConfig(QUERY_DEVICE_CONFIG_FLAGS.QDC_ONLY_ACTIVE_PATHS,
ref pathCount, displayPaths, ref modeCount, displayModes, IntPtr.Zero);
if (error != ERROR_SUCCESS)
throw new Win32Exception(error);
for (var i = 0; i < modeCount; i++)
if (displayModes[i].infoType == DISPLAYCONFIG_MODE_INFO_TYPE.DISPLAYCONFIG_MODE_INFO_TYPE_TARGET)
yield return MonitorFriendlyName(displayModes[i].adapterId, displayModes[i].id);
}
public static string DeviceFriendlyName(this Screen screen)
{
var allFriendlyNames = GetAllMonitorsFriendlyNames();
for (var index = 0; index < Screen.AllScreens.Length; index++)
if (Equals(screen, Screen.AllScreens[index]))
return allFriendlyNames.ToArray()[index];
return null;
}
}
}