From 3c5c2b3e4e738c05f78e366ff2c48e47ec06a939 Mon Sep 17 00:00:00 2001 From: Vincent Maas Date: Sat, 1 Jul 2023 17:37:49 +0200 Subject: [PATCH] fix error with dark mode, add clone functionality of current settings, add SDR brightness setting --- ColorControl.sln | 10 +- ColorControl/ColorControl.csproj | 241 +++++++++--------- ColorControl/MainForm.cs | 10 +- ColorControl/Program.cs | 6 + ColorControl/Services/LG/LgGameBar.cs | 3 +- ColorControl/Services/LG/LgPanel.cs | 8 +- ColorControl/Services/LG/LgPreset.cs | 2 +- ColorControl/Services/LG/RemoteControlForm.cs | 2 +- ColorControl/Services/NVIDIA/NvPanel.cs | 97 ++++++- ColorControl/Services/NVIDIA/NvPreset.cs | 28 +- ColorControl/Services/NVIDIA/NvService.cs | 97 ++++++- ColorControl/Services/Samsung/SamsungPanel.cs | 14 +- .../Services/Samsung/SamsungPreset.cs | 2 +- NLogViewer/NLogViewer.csproj | 102 ++++---- Nspector/Nspector.csproj | 4 + NvAPIWrapper/NvAPIWrapper.csproj | 91 +++---- Shared/Common/Utils.cs | 16 -- Shared/Forms/DarkModeUtils.cs | 5 + Shared/Forms/FormUtils.cs | 49 +++- Shared/Native/CCD.cs | 28 +- Shared/Native/WinApi.cs | 3 + Shared/Shared.csproj | 3 + novideo_srgb/novideo_srgb.csproj | 68 ++--- 23 files changed, 564 insertions(+), 325 deletions(-) diff --git a/ColorControl.sln b/ColorControl.sln index 9133d2a..1b8d8f4 100644 --- a/ColorControl.sln +++ b/ColorControl.sln @@ -13,7 +13,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "novideo_srgb", "novideo_srg EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NLogViewer", "NLogViewer\NLogViewer.csproj", "{D5E4D314-CFCD-4859-98FC-68F660AC7FB4}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Shared", "Shared\Shared.csproj", "{8F38D6B0-82DA-4DD1-89EB-918D8A18AEB1}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Shared", "Shared\Shared.csproj", "{8F38D6B0-82DA-4DD1-89EB-918D8A18AEB1}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -29,8 +29,8 @@ Global {A6005D08-70F0-44CB-A384-9219EBA84F21}.Debug|x64.Build.0 = Debug|Any CPU {A6005D08-70F0-44CB-A384-9219EBA84F21}.Release|Any CPU.ActiveCfg = Release|Any CPU {A6005D08-70F0-44CB-A384-9219EBA84F21}.Release|Any CPU.Build.0 = Release|Any CPU - {A6005D08-70F0-44CB-A384-9219EBA84F21}.Release|x64.ActiveCfg = Release|x64 - {A6005D08-70F0-44CB-A384-9219EBA84F21}.Release|x64.Build.0 = Release|x64 + {A6005D08-70F0-44CB-A384-9219EBA84F21}.Release|x64.ActiveCfg = Release|Any CPU + {A6005D08-70F0-44CB-A384-9219EBA84F21}.Release|x64.Build.0 = Release|Any CPU {76797290-48F5-4A82-86C3-FAD25DAE4500}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {76797290-48F5-4A82-86C3-FAD25DAE4500}.Debug|Any CPU.Build.0 = Debug|Any CPU {76797290-48F5-4A82-86C3-FAD25DAE4500}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -53,8 +53,8 @@ Global {A6A97834-7BE1-474A-B92F-A512DB1D5186}.Debug|x64.Build.0 = Debug|Any CPU {A6A97834-7BE1-474A-B92F-A512DB1D5186}.Release|Any CPU.ActiveCfg = Release|Any CPU {A6A97834-7BE1-474A-B92F-A512DB1D5186}.Release|Any CPU.Build.0 = Release|Any CPU - {A6A97834-7BE1-474A-B92F-A512DB1D5186}.Release|x64.ActiveCfg = Release|x64 - {A6A97834-7BE1-474A-B92F-A512DB1D5186}.Release|x64.Build.0 = Release|x64 + {A6A97834-7BE1-474A-B92F-A512DB1D5186}.Release|x64.ActiveCfg = Release|Any CPU + {A6A97834-7BE1-474A-B92F-A512DB1D5186}.Release|x64.Build.0 = Release|Any CPU {D5E4D314-CFCD-4859-98FC-68F660AC7FB4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {D5E4D314-CFCD-4859-98FC-68F660AC7FB4}.Debug|Any CPU.Build.0 = Debug|Any CPU {D5E4D314-CFCD-4859-98FC-68F660AC7FB4}.Debug|x64.ActiveCfg = Debug|Any CPU diff --git a/ColorControl/ColorControl.csproj b/ColorControl/ColorControl.csproj index 6fe1787..72695d8 100644 --- a/ColorControl/ColorControl.csproj +++ b/ColorControl/ColorControl.csproj @@ -1,122 +1,123 @@  - - net7.0-windows10.0.20348.0 - WinExe - false - publish\ - true - Disk - false - Foreground - 7 - Days - false - false - false - https://www.maassoft.com/downloads/ColorControl/ - ColorControl - Maassoft - Maassoft - 0 - 9.6.1.1 - 9.6.1.1 - false - true - false - true - true - false - true - pngbarn.ico - 10.0.20348.0 - 2020-2023 Maassoft - Maassoft - CF0BC153EA664CD97AC6F234B91F45D34630958F - ColorControl_1_TemporaryKey.pfx - true - LocalIntranet - Properties\app.manifest - true - ColorControl_TemporaryKey.pfx - - - bin\x64\Debug\ - MinimumRecommendedRules.ruleset - - - bin\x64\Release\ - MinimumRecommendedRules.ruleset - - - - - - - Form - - - Form - - - UserControl - - - UserControl - - - UserControl - - - - - - PreserveNewest - - - - - - - - - - - {F935DC20-1CF0-11D0-ADB9-00C04FD58A0B} - 1 - 0 - 0 - tlbimp - False - True - - - - - - - - - - - - - - - - - MSBuild:Compile - - - - - - - - - - - - Designer - - + + net7.0-windows10.0.20348.0 + WinExe + false + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + false + https://www.maassoft.com/downloads/ColorControl/ + ColorControl + Maassoft + Maassoft + 0 + 9.6.2.0 + 9.6.2.0 + false + true + false + true + true + false + true + pngbarn.ico + 10.0.20348.0 + 2020-2023 Maassoft + Maassoft + CF0BC153EA664CD97AC6F234B91F45D34630958F + ColorControl_1_TemporaryKey.pfx + true + LocalIntranet + Properties\app.manifest + true + ColorControl_TemporaryKey.pfx + + + bin\x64\Debug\ + MinimumRecommendedRules.ruleset + + + bin\x64\Release\ + MinimumRecommendedRules.ruleset + + + $(MSBuildThisFileDirectory)=.\ + + + + + + + Form + + + Form + + + UserControl + + + + UserControl + + + + + + PreserveNewest + + + + + + + + + + + {F935DC20-1CF0-11D0-ADB9-00C04FD58A0B} + 1 + 0 + 0 + tlbimp + False + True + + + + + + + + + + + + + + + + + MSBuild:Compile + + + + + + + + + + + + Designer + + \ No newline at end of file diff --git a/ColorControl/MainForm.cs b/ColorControl/MainForm.cs index d06a342..919ec47 100644 --- a/ColorControl/MainForm.cs +++ b/ColorControl/MainForm.cs @@ -33,7 +33,6 @@ namespace ColorControl { private static bool SystemShutdown = false; private static bool EndSession = false; - private static bool UserExit = false; private static int SHORTCUTID_SCREENSAVER = -100; private static readonly Logger Logger = LogManager.GetCurrentClassLogger(); @@ -429,7 +428,7 @@ namespace ColorControl void Exit(object sender, EventArgs e) { - UserExit = true; + Program.UserExit = true; Close(); } @@ -454,11 +453,11 @@ namespace ColorControl private void MainForm_FormClosing(object sender, FormClosingEventArgs e) { - if (!(SystemShutdown || EndSession || UserExit) && _config.MinimizeOnClose) + if (!(SystemShutdown || EndSession || Program.UserExit) && _config.MinimizeOnClose) { e.Cancel = true; WindowState = FormWindowState.Minimized; - UserExit = false; + Program.UserExit = false; return; } @@ -480,6 +479,7 @@ namespace ColorControl _amdPanel?.Save(); _lgPanel?.Save(); _gamePanel?.Save(); + _samsungPanel?.Save(); SaveConfig(); } @@ -1334,8 +1334,6 @@ Currently ColorControl is {(Utils.IsAdministrator() ? "" : "not ")}running as ad //Environment.Exit(0); //InstallUpdate(""); //await Test(); - - //Utils.SetBrightness(Handle); } private async Task Test() diff --git a/ColorControl/Program.cs b/ColorControl/Program.cs index d1ef756..cb90627 100644 --- a/ColorControl/Program.cs +++ b/ColorControl/Program.cs @@ -34,6 +34,7 @@ namespace ColorControl public static Shared.Common.AppContext AppContext { get; private set; } public static bool IsRestarting { get; private set; } + public static bool UserExit = false; private static readonly Logger Logger = LogManager.GetCurrentClassLogger(); private static Mutex _mutex; @@ -292,6 +293,11 @@ namespace ColorControl private static void GlobalHandleException(Exception exception, string type) { + if (UserExit) + { + return; + } + var trace = exception.ToLogString(Environment.StackTrace); var message = $"{type}: {trace}"; diff --git a/ColorControl/Services/LG/LgGameBar.cs b/ColorControl/Services/LG/LgGameBar.cs index ec1744f..0d33699 100644 --- a/ColorControl/Services/LG/LgGameBar.cs +++ b/ColorControl/Services/LG/LgGameBar.cs @@ -1,4 +1,5 @@ using ColorControl.Shared.Common; +using ColorControl.Shared.Forms; using NWin32; using System; using System.Collections.Generic; @@ -146,7 +147,7 @@ namespace ColorControl.Services.LG return; } - BeginInvoke(new Action(UpdateValues)); + FormUtils.BeginInvokeCheck(this, UpdateValues); } private void UpdateValues() diff --git a/ColorControl/Services/LG/LgPanel.cs b/ColorControl/Services/LG/LgPanel.cs index 6f6712d..1571773 100644 --- a/ColorControl/Services/LG/LgPanel.cs +++ b/ColorControl/Services/LG/LgPanel.cs @@ -72,13 +72,13 @@ namespace ColorControl.Services.LG public void Init() { - _lgService.RefreshDevices(afterStartUp: true).ContinueWith((_) => BeginInvoke(() => AfterLgServiceRefreshDevices())); + _lgService.RefreshDevices(afterStartUp: true).ContinueWith((_) => FormUtils.BeginInvokeCheck(this, () => AfterLgServiceRefreshDevices())); _lgService.InstallEventHandlers(); } private void _lgService_SelectedDeviceChangedEvent(object sender, EventArgs e) { - BeginInvoke(() => SetLgDevicesSelectedIndex(sender)); + FormUtils.BeginInvokeCheck(this, () => SetLgDevicesSelectedIndex(sender)); } private void SetLgDevicesSelectedIndex(object sender) @@ -695,7 +695,7 @@ You can also activate this option by using the Expert-button and selecting Wake- if (e.Index == 10) { - _lgService.RefreshDevices().ContinueWith((_) => BeginInvoke(() => FillLgDevices())); + _lgService.RefreshDevices().ContinueWith((_) => FormUtils.BeginInvokeCheck(this, () => FillLgDevices())); } }); } @@ -715,7 +715,7 @@ You can also activate this option by using the Expert-button and selecting Wake- private void RefreshLgDevices() { - _lgService.RefreshDevices(false).ContinueWith((task) => BeginInvoke(() => FillLgDevices())); + _lgService.RefreshDevices(false).ContinueWith((task) => FormUtils.BeginInvokeCheck(this, () => FillLgDevices())); } private void edtShortcutLg_TextChanged(object sender, EventArgs e) diff --git a/ColorControl/Services/LG/LgPreset.cs b/ColorControl/Services/LG/LgPreset.cs index d4a080c..4005ed9 100644 --- a/ColorControl/Services/LG/LgPreset.cs +++ b/ColorControl/Services/LG/LgPreset.cs @@ -58,7 +58,7 @@ namespace ColorControl.Services.LG public static List GetColumnNames() { - return new List() { "Name", "Device|120", "App|200", "Steps|400", "Shortcut", "Trigger" }; + return new List() { "Name", "Device|140", "App|200", "Steps|400", "Shortcut", "Trigger" }; } public override List GetDisplayValues(Config config = null) diff --git a/ColorControl/Services/LG/RemoteControlForm.cs b/ColorControl/Services/LG/RemoteControlForm.cs index 5a8dc04..5d1bd2c 100644 --- a/ColorControl/Services/LG/RemoteControlForm.cs +++ b/ColorControl/Services/LG/RemoteControlForm.cs @@ -137,7 +137,7 @@ namespace ColorControl.Services.LG if (_mouseService == null) { - await _lgService.GetMouseAsync().ContinueWith((task) => BeginInvoke(new Action>(SetMouseService), new[] { task })); + await _lgService.GetMouseAsync().ContinueWith((task) => BeginInvoke(SetMouseService, new[] { task })); } } else diff --git a/ColorControl/Services/NVIDIA/NvPanel.cs b/ColorControl/Services/NVIDIA/NvPanel.cs index 08890c4..bad49be 100644 --- a/ColorControl/Services/NVIDIA/NvPanel.cs +++ b/ColorControl/Services/NVIDIA/NvPanel.cs @@ -211,6 +211,8 @@ namespace ColorControl.Services.NVIDIA FormUtils.EnableControls(this, enabled, new List { lvNvPresets, btnAddModesNv, btnChange, edtNvGpuInfo, btnNvSetClocks, btnNvSettings, edtNvOverclock, btnNvSetClocks }); + btnClone.Enabled = preset != null || GetSelectedNvPreset(true) != null; + if (enabled) { edtNvPresetName.Text = preset.name; @@ -247,7 +249,12 @@ namespace ColorControl.Services.NVIDIA private void btnClone_Click(object sender, EventArgs e) { - var preset = GetSelectedNvPreset(); + var preset = GetSelectedNvPreset(true, true); + + if (preset == null) + { + return; + } var newPreset = preset.Clone(); AddOrUpdateItem(newPreset); @@ -412,7 +419,15 @@ namespace ColorControl.Services.NVIDIA mnuNvOverclocking.Font = _menuItemFonts[preset.applyOverclocking]; mnuNvOtherSettings.Font = _menuItemFonts[preset.applyOther]; - FormUtils.BuildDropDownMenu(mnuNvOtherSettings, "Content type", typeof(InfoFrameVideoContentType), preset, "contentType", nvPresetContentTypeMenuItem_Click); + var contentTypeItem = FormUtils.BuildDropDownMenu(mnuNvOtherSettings, "Content type", typeof(InfoFrameVideoContentType), preset, "contentType", nvPresetContentTypeMenuItem_Click, unchanged: true); + contentTypeItem.DropDownItems[0].Visible = !isCurrentDisplay; + + var itemName = $"{mnuNvOtherSettings.Name}_SDRBrightness"; + var brightnessMenu = FormUtils.BuildMenuItem(mnuNvOtherSettings.DropDownItems, itemName, "SDR brightness"); + + var subItemName = $"{itemName}_SubItem"; + var subItem = FormUtils.BuildMenuItem(brightnessMenu.DropDownItems, subItemName, "", onClick: nvPresetBrightnessMenuItem_Click); + subItem.Text = (preset.SDRBrightness.HasValue ? $"{preset.SDRBrightness.Value}%" : "Unset") + " (click to change)"; BuildNvOverclockingMenu(preset); @@ -722,13 +737,18 @@ namespace ColorControl.Services.NVIDIA { var menuItem = (ToolStripMenuItem)sender; - var value = (InfoFrameVideoContentType)menuItem.Tag; + var value = (InfoFrameVideoContentType?)menuItem.Tag; var preset = GetSelectedNvPreset(true); if (preset.IsDisplayPreset) { - _nvService.SetHDMIContentType(preset.Display, value); + if (!value.HasValue) + { + return; + } + + _nvService.SetHDMIContentType(preset.Display, value.Value); UpdateDisplayInfoItems(); return; @@ -739,6 +759,41 @@ namespace ColorControl.Services.NVIDIA AddOrUpdateItem(); } + private void nvPresetBrightnessMenuItem_Click(object sender, EventArgs e) + { + var preset = GetSelectedNvPreset(true); + + var label = "SDR brightness in %"; + if (!preset.IsDisplayPreset) + { + label += " (clear to set to unchanged)"; + } + + var value = SelectValue(0, 100, preset.SDRBrightness, label); + + if (value == -1) + { + return; + } + + if (preset.IsDisplayPreset) + { + if (!value.HasValue) + { + return; + } + + _nvService.SetSDRBrightness(preset.Display, value.Value); + + UpdateDisplayInfoItems(); + return; + } + + preset.SDRBrightness = value; + + AddOrUpdateItem(); + } + private void refreshRateMenuItem_Click(object sender, EventArgs e) { var refreshRate = (uint)((ToolStripItem)sender).Tag; @@ -905,7 +960,7 @@ namespace ColorControl.Services.NVIDIA } } - private NvPreset GetSelectedNvPreset(bool currentDisplay = false) + private NvPreset GetSelectedNvPreset(bool currentDisplay = false, bool driverSettings = false) { if (lvNvPresets.SelectedItems.Count > 0) { @@ -914,7 +969,7 @@ namespace ColorControl.Services.NVIDIA if (result == null && currentDisplay) { - result = _nvService.GetPresetForDisplay(item.SubItems[1].Text); + result = _nvService.GetPresetForDisplay(item.SubItems[1].Text, driverSettings); } return result; @@ -1100,6 +1155,36 @@ namespace ColorControl.Services.NVIDIA return settingValue; } + private int? SelectValue(int min, int max, int? currentValue, string label) + { + var field = new MessageForms.FieldDefinition + { + MinValue = min, + MaxValue = max, + Label = label, + FieldType = MessageForms.FieldType.Numeric, + Value = currentValue + }; + + var resultFields = MessageForms.ShowDialog(field.Label, new[] { field }); + + if (!resultFields.Any()) + { + return -1; + } + + var strValue = (string)resultFields.First().Value; + + if (string.IsNullOrWhiteSpace(strValue)) + { + return null; + } + + var settingValue = Utils.ParseInt(strValue); + + return settingValue; + } + private void miNvProfileInspector_Click(object sender, EventArgs e) { StartNvProfileInspector(); diff --git a/ColorControl/Services/NVIDIA/NvPreset.cs b/ColorControl/Services/NVIDIA/NvPreset.cs index fac67e7..a58340a 100644 --- a/ColorControl/Services/NVIDIA/NvPreset.cs +++ b/ColorControl/Services/NVIDIA/NvPreset.cs @@ -8,6 +8,7 @@ using NvAPIWrapper.Display; using NvAPIWrapper.Native.Display; using System; using System.Collections.Generic; +using System.Linq; using System.Text; namespace ColorControl.Services.NVIDIA @@ -33,7 +34,8 @@ namespace ColorControl.Services.NVIDIA public uint ditheringBits { get; set; } public uint ditheringMode { get; set; } public bool applyOther { get; set; } - public InfoFrameVideoContentType contentType { get; set; } + public InfoFrameVideoContentType? contentType { get; set; } + public int? SDRBrightness { get; set; } public bool applyDriverSettings { get; set; } public Dictionary driverSettings { get; set; } public bool applyOverclocking { get; set; } @@ -96,6 +98,7 @@ namespace ColorControl.Services.NVIDIA driverSettings = new Dictionary(preset.driverSettings); contentType = preset.contentType; + SDRBrightness = preset.SDRBrightness; applyOther = preset.applyOther; } @@ -141,7 +144,7 @@ namespace ColorControl.Services.NVIDIA values.Add(string.Format("{0}: {1}", applyDriverSettings ? "Included" : "Excluded", GetDriverSettingsDescription())); - values.Add(string.Format("{0}: {1}", applyOther ? "Included" : "Excluded", $"Content type: {contentType}")); + values.Add(string.Format("{0}: {1}", applyOther ? "Included" : "Excluded", GetOtherDescription())); values.Add(string.Format("{0}: {1}", applyOverclocking ? "Included" : "Excluded", GetOverclockingSettingsDescription())); @@ -209,6 +212,27 @@ namespace ColorControl.Services.NVIDIA return dithering; } + public string GetOtherDescription() + { + var values = new List(); + + if (contentType.HasValue) + { + values.Add($"Content type: {contentType.Value}"); + } + if (SDRBrightness.HasValue) + { + values.Add($"SDR brightness: {SDRBrightness.Value}%"); + } + + if (!values.Any()) + { + values.Add("None"); + } + + return string.Join(", ", values); + } + public static List GetDefaultPresets() { var presets = new List(); diff --git a/ColorControl/Services/NVIDIA/NvService.cs b/ColorControl/Services/NVIDIA/NvService.cs index ac55b80..116617d 100644 --- a/ColorControl/Services/NVIDIA/NvService.cs +++ b/ColorControl/Services/NVIDIA/NvService.cs @@ -14,6 +14,7 @@ using NvAPIWrapper.GPU; using NvAPIWrapper.Native; using NvAPIWrapper.Native.Display; using NvAPIWrapper.Native.GPU.Structures; +using NWin32; using NWin32.NativeTypes; using System; using System.Collections.Generic; @@ -104,6 +105,9 @@ namespace ColorControl.Services.NVIDIA private DrsSettingsMetaService _meta; private List _settings = new List(); + private int _lastSetSDRBrightness = -1; + private int _lastReadSDRBrightness = -1; + private Semaphore _semaphore = new Semaphore(1, 1); public const uint DRS_GSYNC_APPLICATION_MODE = 294973784; @@ -312,11 +316,6 @@ namespace ColorControl.Services.NVIDIA SetHDRState(display, newHdrEnabled); } - if (hdrEnabled) - { - //CCD.SetSDRWhiteLevel(1000, display.Name); - } - if (preset.applyRefreshRate || preset.applyResolution) { if (!SetMode(preset.applyResolution ? preset.resolutionWidth : 0, preset.applyResolution ? preset.resolutionHeight : 0, preset.applyRefreshRate ? preset.refreshRate : 0, true)) @@ -327,7 +326,15 @@ namespace ColorControl.Services.NVIDIA if (preset.applyOther) { - SetHDMIContentType(display, preset.contentType); + if (preset.contentType.HasValue) + { + SetHDMIContentType(display, preset.contentType.Value); + } + + if (preset.SDRBrightness.HasValue) + { + SetSDRBrightness(display, preset.SDRBrightness.Value); + } } if (preset.applyDithering) @@ -528,6 +535,43 @@ namespace ColorControl.Services.NVIDIA CCD.SetHDRState(enabled, display.Name); } + public void SetSDRBrightness(Display display, int brightnessPercent) + { + var hmon = FormUtils.GetMonitorForDisplayName(display.Name); + + if (hmon == IntPtr.Zero) + { + hmon = NativeMethods.MonitorFromWindow(0, 1); + } + + var brightness = 1 + (double)brightnessPercent / 20; + + WinApi.DwmpSDRToHDRBoostPtr(hmon, brightness); + + _lastSetSDRBrightness = brightnessPercent; + } + + public int GetSDRBrightness(Display display) + { + var whiteLevel = CCD.GetSDRWhiteLevel(display.Name); + + if (whiteLevel >= 1000) + { + var newBrightnessPercent = (int)(whiteLevel - 1000) / 50; + + if (_lastSetSDRBrightness >= 0 && newBrightnessPercent == _lastReadSDRBrightness) + { + return _lastSetSDRBrightness; + } + + _lastReadSDRBrightness = newBrightnessPercent; + + return newBrightnessPercent; + } + + return 0; + } + public bool SetDithering(NvDitherState state, uint bits = 1, uint mode = 4, NvPreset preset = null, Display currentDisplay = null) { var result = true; @@ -832,7 +876,19 @@ namespace ColorControl.Services.NVIDIA values.Add(string.Join(", ", drsValues)); - values.Add($"Content type: {GetHDMIContentType(display)}"); + var otherValues = new List + { + $"Content type: {GetHDMIContentType(display)}" + }; + + if (hdrEnabled) + { + var sdrBrightness = GetSDRBrightness(display); + + otherValues.Add($"SDR brightness: {sdrBrightness}%"); + } + + values.Add(string.Join(", ", otherValues)); var infoLine = string.Format("{0}: {1}, {2}Hz, HDR: {3}", name, colorSettings, refreshRate, hdrEnabled ? "Yes" : "No"); @@ -850,7 +906,7 @@ namespace ColorControl.Services.NVIDIA } } - public NvPreset GetPresetForDisplay(string displayName) + public NvPreset GetPresetForDisplay(string displayName, bool driverSettings = false) { var displays = GetDisplays(); @@ -867,6 +923,7 @@ namespace ColorControl.Services.NVIDIA preset.displayName = FormUtils.ExtendedDisplayName(display.Name); preset.colorData = GetCurrentColorData(display); preset.contentType = GetHDMIContentType(display); + preset.SDRBrightness = GetSDRBrightness(display); var mode = GetCurrentMode(display.Name); @@ -905,6 +962,30 @@ namespace ColorControl.Services.NVIDIA } } + if (driverSettings) + { + var settings = GetVisibleSettings(); + + foreach (var setting in settings) + { + var settingMeta = GetSettingMeta(setting.SettingId); + + if (settingMeta == null) + { + continue; + } + + var (presetSetting, isDefault) = settingMeta.ToIntValue(setting.ValueText); + + if (isDefault) + { + continue; + } + + preset.driverSettings.Add(setting.SettingId, presetSetting); + } + } + return preset; } diff --git a/ColorControl/Services/Samsung/SamsungPanel.cs b/ColorControl/Services/Samsung/SamsungPanel.cs index bcf78f6..7eff30e 100644 --- a/ColorControl/Services/Samsung/SamsungPanel.cs +++ b/ColorControl/Services/Samsung/SamsungPanel.cs @@ -70,13 +70,13 @@ namespace ColorControl.Services.Samsung public void Init() { var _ = Handle; - _samsungService.RefreshDevices(afterStartUp: true).ContinueWith((_) => BeginInvoke(() => AfterSamsungServiceRefreshDevices())); + _samsungService.RefreshDevices(afterStartUp: true).ContinueWith((_) => FormUtils.BeginInvokeCheck(this, AfterSamsungServiceRefreshDevices)); _samsungService.InstallEventHandlers(); } private void _samsungService_SelectedDeviceChangedEvent(object sender, EventArgs e) { - BeginInvoke(() => SetSamsungDevicesSelectedIndex(sender)); + FormUtils.BeginInvokeCheck(this, () => SetSamsungDevicesSelectedIndex(sender)); } private void SetSamsungDevicesSelectedIndex(object sender) @@ -369,7 +369,7 @@ namespace ColorControl.Services.Samsung //if (cbxSamsungApps.Items.Count == 0 && device != null) //{ - // _samsungService.RefreshAppsAsync().ContinueWith((task) => BeginInvoke(() => FillApps(false))); + // _samsungService.RefreshAppsAsync().ContinueWith((task) => FormUtils.BeginInvokeCheck(this, () => FillApps(false))); //} btnSamsungDeviceConvertToCustom.Enabled = devices.Any(); @@ -480,7 +480,7 @@ namespace ColorControl.Services.Samsung private void btnSamsungRefreshApps_Click(object sender, EventArgs e) { - //_samsungService.RefreshApps(true).ContinueWith((task) => BeginInvoke(() => FillLgApps(true))); + //_samsungService.RefreshApps(true).ContinueWith((task) => FormUtils.BeginInvokeCheck(this, () => FillLgApps(true))); } private void cbxSamsungDevices_SelectedIndexChanged(object sender, EventArgs e) @@ -676,7 +676,7 @@ Use 'Settings > Test power off/on' to test this functionality." ); } - BeginInvoke(() => + FormUtils.BeginInvokeCheck(this, () => { device.Options.PowerOnAfterStartup = clbLgPower.GetItemChecked(0); device.Options.PowerOnAfterResume = clbLgPower.GetItemChecked(1); @@ -692,7 +692,7 @@ Use 'Settings > Test power off/on' to test this functionality." if (e.Index == 10) { - _samsungService.RefreshDevices().ContinueWith((_) => BeginInvoke(() => FillSamsungDevices())); + _samsungService.RefreshDevices().ContinueWith((_) => FormUtils.BeginInvokeCheck(this, () => FillSamsungDevices())); } }); } @@ -712,7 +712,7 @@ Use 'Settings > Test power off/on' to test this functionality." private void RefreshSamsungDevices() { - _samsungService.RefreshDevices(false).ContinueWith((task) => BeginInvoke(() => FillSamsungDevices())); + _samsungService.RefreshDevices(false).ContinueWith((task) => FormUtils.BeginInvokeCheck(this, () => FillSamsungDevices())); } private void edtShortcutLg_TextChanged(object sender, EventArgs e) diff --git a/ColorControl/Services/Samsung/SamsungPreset.cs b/ColorControl/Services/Samsung/SamsungPreset.cs index 5bf3806..7eb7521 100644 --- a/ColorControl/Services/Samsung/SamsungPreset.cs +++ b/ColorControl/Services/Samsung/SamsungPreset.cs @@ -48,7 +48,7 @@ namespace ColorControl.Services.Samsung public static string[] GetColumnNames() { - return new[] { "Name", "Device|120", "App|200", "Steps|400", "Shortcut", "Trigger" }; + return new[] { "Name", "Device|140", "App|200", "Steps|400", "Shortcut", "Trigger" }; } public override List GetDisplayValues(Config config = null) diff --git a/NLogViewer/NLogViewer.csproj b/NLogViewer/NLogViewer.csproj index b41efbb..d0b38da 100644 --- a/NLogViewer/NLogViewer.csproj +++ b/NLogViewer/NLogViewer.csproj @@ -1,56 +1,60 @@  - - net7.0-windows10.0.20348.0 - true - DJ - true - Sentinel.NLogViewer - false - + + net7.0-windows10.0.20348.0 + true + DJ + true + Sentinel.NLogViewer + false + - - - + + $(MSBuildThisFileDirectory)=.\ + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + - - - MSBuild:Compile - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MSBuild:Compile + + diff --git a/Nspector/Nspector.csproj b/Nspector/Nspector.csproj index 6a7cfd2..4c08aa8 100644 --- a/Nspector/Nspector.csproj +++ b/Nspector/Nspector.csproj @@ -9,6 +9,10 @@ true + + $(MSBuildThisFileDirectory)=.\ + + diff --git a/NvAPIWrapper/NvAPIWrapper.csproj b/NvAPIWrapper/NvAPIWrapper.csproj index 68ccae5..5797f40 100644 --- a/NvAPIWrapper/NvAPIWrapper.csproj +++ b/NvAPIWrapper/NvAPIWrapper.csproj @@ -1,47 +1,50 @@  - - net7.0-windows10.0.20348.0 - 0.8.1.106 - falahati.net - NvAPIWrapper is a .Net wrapper for NVIDIA public API - Soroush Falahati - Copyright © Soroush Falahati 2018 (falahati.net) - AnyCPU - NvAPIWrapper.Net - https://github.com/falahati/NvAPIWrapper - https://github.com/falahati/NvAPIWrapper/blob/master/LICENSE - https://github.com/falahati/NvAPIWrapper/blob/master/NvAPIWrapper/Icon.png?raw=true - true - true - AnyCPU - NvAPIWrapper (for NVAPI 410) - NvAPIWrapper.Net - OpenSourceStrongNameSignKey.pfx - - - ..\Debug - - - False - false - ..\Release - ..\Release\NvAPIWrapper.xml - true - - - - - - true - \ - - - true - \ - - - - - + + net7.0-windows10.0.20348.0 + 0.8.1.106 + falahati.net + NvAPIWrapper is a .Net wrapper for NVIDIA public API + Soroush Falahati + Copyright © Soroush Falahati 2018 (falahati.net) + AnyCPU + NvAPIWrapper.Net + https://github.com/falahati/NvAPIWrapper + https://github.com/falahati/NvAPIWrapper/blob/master/LICENSE + https://github.com/falahati/NvAPIWrapper/blob/master/NvAPIWrapper/Icon.png?raw=true + true + true + AnyCPU + NvAPIWrapper (for NVAPI 410) + NvAPIWrapper.Net + OpenSourceStrongNameSignKey.pfx + + + ..\Debug + + + False + false + ..\Release + ..\Release\NvAPIWrapper.xml + true + + + $(MSBuildThisFileDirectory)=.\ + + + + + + true + \ + + + true + \ + + + + + \ No newline at end of file diff --git a/Shared/Common/Utils.cs b/Shared/Common/Utils.cs index cd82637..d5b90fd 100644 --- a/Shared/Common/Utils.cs +++ b/Shared/Common/Utils.cs @@ -381,22 +381,6 @@ The best and suggested method to provide this is via a Windows Service. Only whe return values; } - public static void SetBrightness(nint handle) - { - var displays = Windows.Graphics.Display.DisplayServices.FindAll(); - - var folderPicker = new Windows.Storage.Pickers.FolderPicker(); - - // Initialize the folder picker with the window handle (HWND). - WinRT.Interop.InitializeWithWindow.Initialize(folderPicker, handle); - - folderPicker.FileTypeFilter.Add("*"); - var folder = folderPicker.PickSingleFolderAsync().GetAwaiter(); - - //var info = Windows.Graphics.Display.DisplayInformation.GetForCurrentView(); - //var colorInfo = info.GetAdvancedColorInfo(); - } - public static async Task> GetPnpDevices(string deviceName, string category = null) { var devices = new List(); diff --git a/Shared/Forms/DarkModeUtils.cs b/Shared/Forms/DarkModeUtils.cs index c0898dc..a2af32d 100644 --- a/Shared/Forms/DarkModeUtils.cs +++ b/Shared/Forms/DarkModeUtils.cs @@ -55,6 +55,11 @@ namespace ColorControl.Shared.Forms public static void InitWpfTheme() { + if (System.Windows.Application.Current == null) + { + new System.Windows.Application(); + } + var resources = System.Windows.Application.Current.Resources; if (DarkModeUtils.UseDarkMode) diff --git a/Shared/Forms/FormUtils.cs b/Shared/Forms/FormUtils.cs index df21ff5..c082487 100644 --- a/Shared/Forms/FormUtils.cs +++ b/Shared/Forms/FormUtils.cs @@ -139,7 +139,7 @@ namespace ColorControl.Shared.Forms return subMenuItem; } - public static void BuildDropDownMenu(ToolStripDropDownItem mnuParent, string name, Type enumType, object colorData, string propertyName, EventHandler clickEvent, Font font = null) + public static ToolStripMenuItem BuildDropDownMenu(ToolStripDropDownItem mnuParent, string name, Type enumType, object colorData, string propertyName, EventHandler clickEvent, Font font = null, bool unchanged = false) { PropertyInfo property = null; var subMenuItems = mnuParent.DropDownItems.Find("miColorSettings_" + name, false); @@ -159,6 +159,17 @@ namespace ColorControl.Shared.Forms subMenuItem.Tag = property; } + if (unchanged) + { + var item = subMenuItem.DropDownItems.AddCustom("Unchanged"); + item.Click += clickEvent; + + if (font != null) + { + item.Font = font; + } + } + foreach (var enumValue in Enum.GetValues(enumType)) { var item = subMenuItem.DropDownItems.AddCustom(enumValue.ToString()); @@ -180,7 +191,7 @@ namespace ColorControl.Shared.Forms if (colorData == null) { - return; + return subMenuItem; } var value = property.GetValue(colorData); @@ -193,8 +204,13 @@ namespace ColorControl.Shared.Forms { menuItem.Checked = menuItem.Tag.Equals(value); } + else + { + menuItem.Checked = value == null; + } } } + return subMenuItem; } public static ToolStripMenuItem BuildMenuItem(ToolStripItemCollection itemCollection, string name, string text, object tag = null, EventHandler onClick = null) @@ -489,6 +505,18 @@ namespace ColorControl.Shared.Forms return name; } + public static IntPtr GetMonitorForDisplayName(string displayName) + { + var name = displayName; + var screen = Screen.AllScreens.FirstOrDefault(x => x.DeviceName.Equals(name)); + if (screen != null) + { + return screen.GetHashCode(); + } + + return IntPtr.Zero; + } + public static string EditShortcut(string shortcut, string label = "Shortcut", string title = null) { var field = new MessageForms.FieldDefinition @@ -569,6 +597,23 @@ namespace ColorControl.Shared.Forms sortState.SortOrder = sorter.Order; sortState.SortIndex = sorter.SortColumn; } + + public static IAsyncResult BeginInvokeCheck(Control control, Delegate action) + { + return BeginInvokeCheck(control, action, null); + } + + public static IAsyncResult BeginInvokeCheck(Control control, Delegate action, params object[] args) + { + if (control?.IsHandleCreated != true) + { + Logger.Debug($"Skipping BeginInvoke due to missing handle of control {control.Name}"); + + return null; + } + + return control.BeginInvoke(action, args); + } } public class EnumComboBoxItem diff --git a/Shared/Native/CCD.cs b/Shared/Native/CCD.cs index 850a929..b238ebb 100644 --- a/Shared/Native/CCD.cs +++ b/Shared/Native/CCD.cs @@ -107,11 +107,6 @@ namespace ColorControl.Shared.Native NativeMethods.DisplayConfigSetDeviceInfo(ref setpacket); IsHDRActive = enabled; - - //if (enabled && SDRWhiteLevelInNits.HasValue) - //{ - // SetSDRWhiteLevel(modesArray[i], SDRWhiteLevelInNits.Value); - //} } } } @@ -125,8 +120,7 @@ namespace ColorControl.Shared.Native } } - // Does not work... - public static void SetSDRWhiteLevel(float SDRWhiteLevelInNits, string displayName = null) + public static uint GetSDRWhiteLevel(string displayName = null) { uint pathCount, modeCount; @@ -164,7 +158,7 @@ namespace ColorControl.Shared.Native if (err == NativeConstants.ERROR_SUCCESS && requestpacket.advancedColorSupported) { - SetSDRWhiteLevel(modesArray[i], SDRWhiteLevelInNits); + return GetSDRWhiteLevelForDisplayConfig(modesArray[i]); } } } @@ -176,6 +170,8 @@ namespace ColorControl.Shared.Native { throw new Win32Exception(err); } + + return 0; } public static bool IsHDREnabled(string displayName = null) @@ -258,13 +254,8 @@ namespace ColorControl.Shared.Native return true; } - private static void SetSDRWhiteLevel(DisplayConfigModeInfo displayConfigModeInfo, float value) + private static uint GetSDRWhiteLevelForDisplayConfig(DisplayConfigModeInfo displayConfigModeInfo) { - var setpacket = new DISPLAYCONFIG_SDR_WHITE_LEVEL(); - setpacket.header = new DISPLAYCONFIG_DEVICE_INFO_HEADER(); - setpacket.header.type = DISPLAYCONFIG_DEVICE_INFO_TYPE.DISPLAYCONFIG_DEVICE_INFO_SET_SDR_WHITE_LEVEL; - setpacket.header.size = Marshal.SizeOf(); - var requestpacket = new DISPLAYCONFIG_SDR_WHITE_LEVEL(); requestpacket.header = new DISPLAYCONFIG_DEVICE_INFO_HEADER(); requestpacket.header.type = DISPLAYCONFIG_DEVICE_INFO_TYPE.DISPLAYCONFIG_DEVICE_INFO_GET_SDR_WHITE_LEVEL; @@ -276,13 +267,10 @@ namespace ColorControl.Shared.Native if (error == NativeConstants.ERROR_SUCCESS) { - setpacket.header.adapterId = displayConfigModeInfo.adapterId; - setpacket.header.id = displayConfigModeInfo.id; - setpacket.SDRWhiteLevel = 2000; - - error = NativeMethods.DisplayConfigSetDeviceInfo(ref setpacket); - + return requestpacket.SDRWhiteLevel; } + + return 0; } private static bool EqualDisplayNames(string displayName1, string displayName2) diff --git a/Shared/Native/WinApi.cs b/Shared/Native/WinApi.cs index dc3d07f..0b19929 100644 --- a/Shared/Native/WinApi.cs +++ b/Shared/Native/WinApi.cs @@ -163,5 +163,8 @@ namespace ColorControl.Shared.Native [DllImport("ntdll.dll")] public static extern int NtQueryInformationProcess(IntPtr processHandle, int processInformationClass, ref ParentProcessUtilities processInformation, int processInformationLength, out int returnLength); + + [DllImport("dwmapi.dll", EntryPoint = "#171")] + public static extern void DwmpSDRToHDRBoostPtr(IntPtr monitor, double brightness); } } diff --git a/Shared/Shared.csproj b/Shared/Shared.csproj index bec1c6d..c6eb3bf 100644 --- a/Shared/Shared.csproj +++ b/Shared/Shared.csproj @@ -7,6 +7,9 @@ true true + + $(MSBuildThisFileDirectory)=.\ + diff --git a/novideo_srgb/novideo_srgb.csproj b/novideo_srgb/novideo_srgb.csproj index ecde4dd..37c432e 100644 --- a/novideo_srgb/novideo_srgb.csproj +++ b/novideo_srgb/novideo_srgb.csproj @@ -1,27 +1,31 @@  - - net7.0-windows10.0.20348.0 - enable - enable - Properties - true + + net7.0-windows10.0.20348.0 + enable + enable + Properties + true true true 10.0.20348.0 - - - - + + $(MSBuildThisFileDirectory)=.\ + - - - - - - + + + + + + + + + + + @@ -29,22 +33,22 @@ - - + + - - - True - True - Settings.settings - - + + + True + True + Settings.settings + + + + + + SettingsSingleFileGenerator + Settings.Designer.cs + + - - - SettingsSingleFileGenerator - Settings.Designer.cs - - - \ No newline at end of file