add screensaver trigger, focus main window when already started, fix some bugs

This commit is contained in:
Vincent Maas committed 2021-04-03 16:27:59 +02:00
1 parent a33543acd5
commit 0c877623c0
15 files changed
+449 -134

No files matched your search

+1 -4
View File
@@ -66,7 +66,7 @@ namespace ColorControl
{
int ADLRet = -1;
Logger.Debug("Initialize");
//Logger.Debug("Initialize");
var del = ADL.GetDelegate<ADL.ADL_Main_Control_Create>();
@@ -77,15 +77,12 @@ namespace ColorControl
CheckError(ADLRet, nameof(ADL.ADL_Main_Control_Create));
}
Logger.Debug("ADLRet1: " + ADLRet);
var del2 = ADL.GetDelegate<ADL.ADL2_Main_Control_Create>();
if (del2 != null)
{
// Second parameter is 1: Get only the present adapters
ADLRet = del2(ADL.ADL_Main_Memory_Alloc_Func, 1, ref context);
Logger.Debug("ADLRet2: " + ADLRet);
CheckError(ADLRet, nameof(ADL.ADL2_Main_Control_Create));
}
+5 -1
View File
@@ -15,7 +15,11 @@
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Runtime.CompilerServices.Unsafe" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.6.0" newVersion="4.0.6.0" />
<bindingRedirect oldVersion="0.0.0.0-5.0.0.0" newVersion="5.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="PacketDotNet" publicKeyToken="451414c7667b2a58" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-1.2.0.0" newVersion="1.2.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
+19 -17
View File
@@ -101,33 +101,33 @@
<ApplicationIcon>pngbarn.ico</ApplicationIcon>
</PropertyGroup>
<ItemGroup>
<Reference Include="Microsoft.Win32.TaskScheduler, Version=2.8.20.0, Culture=neutral, PublicKeyToken=c416bc1b32d97233, processorArchitecture=MSIL">
<HintPath>..\packages\TaskScheduler.2.8.20\lib\net452\Microsoft.Win32.TaskScheduler.dll</HintPath>
<Reference Include="Microsoft.Win32.TaskScheduler, Version=2.9.1.0, Culture=neutral, PublicKeyToken=e25603a88b3aa7da, processorArchitecture=MSIL">
<HintPath>..\packages\TaskScheduler.2.9.1\lib\net452\Microsoft.Win32.TaskScheduler.dll</HintPath>
</Reference>
<Reference Include="Native, Version=0.1.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Native.0.1.0\lib\net35\Native.dll</HintPath>
</Reference>
<Reference Include="Newtonsoft.Json, Version=12.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\packages\Newtonsoft.Json.12.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
<Reference Include="Newtonsoft.Json, Version=13.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\packages\Newtonsoft.Json.13.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="NLog, Version=4.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
<HintPath>..\packages\NLog.4.7.2\lib\net45\NLog.dll</HintPath>
<HintPath>..\packages\NLog.4.7.9\lib\net45\NLog.dll</HintPath>
</Reference>
<Reference Include="NStandard, Version=0.4.3.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\NStandard.0.4.3\lib\net46\NStandard.dll</HintPath>
<Reference Include="NStandard, Version=0.6.12.5, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\NStandard.0.6.12.5\lib\net46\NStandard.dll</HintPath>
</Reference>
<Reference Include="NvAPIWrapper, Version=0.8.0.98, Culture=neutral, PublicKeyToken=310fd07b25df79b3, processorArchitecture=MSIL">
<HintPath>..\packages\NvAPIWrapper.Net.0.8.0.98\lib\net45\NvAPIWrapper.dll</HintPath>
<Reference Include="NvAPIWrapper, Version=0.8.1.100, Culture=neutral, PublicKeyToken=310fd07b25df79b3, processorArchitecture=MSIL">
<HintPath>..\packages\NvAPIWrapper.Net.0.8.1.101\lib\net45\NvAPIWrapper.dll</HintPath>
</Reference>
<Reference Include="NWin32, Version=1.0.6.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\NWin32.1.0.6\lib\net46\NWin32.dll</HintPath>
<Reference Include="NWin32, Version=1.0.7.6, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\NWin32.1.0.7.6\lib\net46\NWin32.dll</HintPath>
</Reference>
<Reference Include="PacketDotNet, Version=1.0.5.0, Culture=neutral, PublicKeyToken=451414c7667b2a58, processorArchitecture=MSIL">
<HintPath>..\packages\PacketDotNet.1.0.5\lib\net45\PacketDotNet.dll</HintPath>
<Reference Include="PacketDotNet, Version=1.2.0.0, Culture=neutral, PublicKeyToken=451414c7667b2a58, processorArchitecture=MSIL">
<HintPath>..\packages\PacketDotNet.1.2.0\lib\net45\PacketDotNet.dll</HintPath>
</Reference>
<Reference Include="PresentationCore" />
<Reference Include="SharpPcap, Version=5.2.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\SharpPcap.5.2.0\lib\netstandard2.0\SharpPcap.dll</HintPath>
<Reference Include="SharpPcap, Version=5.4.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\SharpPcap.5.4.0\lib\netstandard2.0\SharpPcap.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Buffers, Version=4.0.3.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
@@ -137,6 +137,7 @@
<Reference Include="System.Configuration.Install" />
<Reference Include="System.Core" />
<Reference Include="System.IO.Compression" />
<Reference Include="System.Management" />
<Reference Include="System.Memory, Version=4.0.1.1, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.Memory.4.5.4\lib\net461\System.Memory.dll</HintPath>
</Reference>
@@ -144,8 +145,8 @@
<Reference Include="System.Numerics.Vectors, Version=4.1.4.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Numerics.Vectors.4.5.0\lib\net46\System.Numerics.Vectors.dll</HintPath>
</Reference>
<Reference Include="System.Runtime.CompilerServices.Unsafe, Version=4.0.6.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Runtime.CompilerServices.Unsafe.4.7.0\lib\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll</HintPath>
<Reference Include="System.Runtime.CompilerServices.Unsafe, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Runtime.CompilerServices.Unsafe.5.0.0\lib\net45\System.Runtime.CompilerServices.Unsafe.dll</HintPath>
</Reference>
<Reference Include="System.Runtime.Serialization" />
<Reference Include="System.Runtime.WindowsRuntime, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL">
@@ -175,6 +176,7 @@
<Compile Include="ADL.cs" />
<Compile Include="ADLWrapper.cs" />
<Compile Include="AmdDisplayInfo.cs" />
<Compile Include="UserSessionInfo.cs" />
<Compile Include="ServiceBase.cs" />
<Compile Include="NvDisplayInfo.cs" />
<Compile Include="MessageForms.cs" />
+3
View File
@@ -6,6 +6,8 @@
public bool MinimizeOnClose { get; set; }
public bool MinimizeToTray { get; set; }
public int DisplaySettingsDelay { get; set; }
public string ScreenSaverShortcut { get; set; }
@@ -23,6 +25,7 @@
ScreenSaverShortcut = string.Empty;
FormWidth = 900;
FormHeight = 600;
MinimizeToTray = true;
}
}
}
+188 -3
View File
@@ -1,7 +1,10 @@
using LgTv;
using Microsoft.Win32;
using Newtonsoft.Json;
using NWin32;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Threading;
@@ -50,6 +53,11 @@ namespace ColorControl
private Dictionary<string, Func<bool>> _invokableActions = new Dictionary<string, Func<bool>>();
private bool _poweredOffByScreenSaver;
private int _poweredOffByScreenSaverProcessId;
private Task _monitorTask;
private int _monitorTaskCounter;
public LgService(string dataDir, bool allowPowerOn)
{
_dataDir = dataDir;
@@ -318,7 +326,7 @@ namespace ColorControl
return false;
}
if (reconnect || _lgTvApi == null || _lgTvApi.ConnectionClosed || !string.Equals(_lgTvApi.GetIpAddress(), SelectedDevice.IpAddress))
if (reconnect || !IsConnected() || !string.Equals(_lgTvApi.GetIpAddress(), SelectedDevice.IpAddress))
{
if (!await ConnectToSelectedDevice())
{
@@ -328,7 +336,11 @@ namespace ColorControl
}
return true;
}
private bool IsConnected()
{
return !_lgTvApi?.ConnectionClosed ?? false;
}
public async Task<bool> ApplyPreset(LgPreset preset, bool reconnect = false)
{
@@ -523,8 +535,14 @@ namespace ColorControl
}
}
private async Task<bool> WakeAndConnectToSelectedDeviceWithRetries()
private async Task<bool> WakeAndConnectToSelectedDeviceWithRetries(bool checkUserSession = true)
{
if (checkUserSession && !UserSessionInfo.UserLocalSession)
{
Logger.Debug($"WakeAndConnectToSelectedDeviceWithRetries: not waking because session info indicates no local session");
return false;
}
var wakeDelay = 0;
var maxRetries = Config.PowerOnRetries <= 1 ? 5 : Config.PowerOnRetries;
@@ -581,5 +599,172 @@ namespace ColorControl
return false;
}
}
public void InstallEventHandlers()
{
SystemEvents.PowerModeChanged -= PowerModeChanged;
SystemEvents.PowerModeChanged += PowerModeChanged;
//SystemEvents.SessionEnded -= SessionEnded;
//SystemEvents.SessionEnded += SessionEnded;
UserSessionInfo.UserSessionSwitch -= SessionSwitched;
UserSessionInfo.UserSessionSwitch += SessionSwitched;
MonitorProcesses();
}
private void SessionSwitched(bool toLocal)
{
if (toLocal)
{
if (_poweredOffByScreenSaver)
{
Logger.Debug("User switched to local and screen was powered off due to screensaver: waking up");
_poweredOffByScreenSaver = false;
_poweredOffByScreenSaverProcessId = 0;
var _ = WakeAndConnectToSelectedDeviceWithRetries();
}
else
{
Logger.Debug("User switched to local but screen was not powered off by screensaver: NOT waking up");
}
}
}
private void PowerModeChanged(object sender, PowerModeChangedEventArgs e)
{
var powerOn = e.Mode == PowerModes.Resume;
Logger.Debug($"PowerModeChanged: {e.Mode}");
if (powerOn)
{
DisposeConnection();
WakeAfterResume();
return;
}
if (Config.PowerOffOnStandby)
{
NativeMethods.SetThreadExecutionState(NativeConstants.ES_CONTINUOUS | NativeConstants.ES_SYSTEM_REQUIRED | NativeConstants.ES_AWAYMODE_REQUIRED);
try
{
Logger.Debug("Powering off tv...");
var task = PowerOff();
Utils.WaitForTask(task);
Logger.Debug("Done powering off tv");
}
finally
{
NativeMethods.SetThreadExecutionState(NativeConstants.ES_CONTINUOUS);
}
}
}
private void SessionEnded(object sender, SessionEndedEventArgs e)
{
//if (e.Reason == SessionEndReasons.SystemShutdown)
//{
// Logger.Debug($"SessionEnded: {e.Reason}");
// if (Config.PowerOffOnShutdown)
// {
// PowerOff();
// }
//}
}
private void MonitorProcesses()
{
if (Config.PowerSwitchOnScreenSaver && _monitorTask == null)
{
_monitorTask = CheckProcesses();
}
else if (!Config.PowerSwitchOnScreenSaver && _monitorTask != null)
{
_monitorTask = null;
}
}
public async Task CheckProcesses()
{
var wasConnected = IsConnected();
_monitorTaskCounter++;
var validCounter = _monitorTaskCounter;
while (Config.PowerSwitchOnScreenSaver && validCounter == _monitorTaskCounter)
{
await Task.Delay(500);
if (_poweredOffByScreenSaver && !UserSessionInfo.UserLocalSession)
{
continue;
}
var processes = Process.GetProcesses();
if (_poweredOffByScreenSaver)
{
if (processes.Any(p => p.Id == _poweredOffByScreenSaverProcessId))
{
continue;
}
Logger.Debug("Screensaver stopped, waking");
_poweredOffByScreenSaver = false;
_poweredOffByScreenSaverProcessId = 0;
var _ = WakeAndConnectToSelectedDeviceWithRetries();
continue;
}
if (!IsConnected())
{
if (wasConnected)
{
Logger.Debug("TV was connected, but not any longer");
wasConnected = false;
}
continue;
}
if (!wasConnected)
{
Logger.Debug("TV was not connected, but connection has now been established");
wasConnected = true;
}
foreach (var process in processes)
{
var name = process.ProcessName.ToLowerInvariant();
if (name.EndsWith(".scr"))
{
var parent = process.Parent();
if (parent?.ProcessName.Contains("winlogon") ?? false)
{
Logger.Debug($"Screensaver started: {process.ProcessName}, parent: {parent.ProcessName}");
try
{
Logger.Debug("Powering off tv because of screensaver");
_poweredOffByScreenSaver = await PowerOff();
_poweredOffByScreenSaverProcessId = process.Id;
}
catch (Exception e)
{
Logger.Error("CheckProcesses: can't power off: " + e.ToLogString());
}
if (!IsConnected())
{
_poweredOffByScreenSaver = false;
}
break;
}
else
{
Logger.Debug($"Screensaver started: {process.ProcessName}, but invalid parent: {parent?.ProcessName ?? "no parent"}");
}
}
}
}
}
}
}
+2
View File
@@ -10,6 +10,8 @@
public bool PowerOffOnStandby { get; set; }
public bool PowerSwitchOnScreenSaver { get; set; }
public int PowerOnDelayAfterResume { get; set; }
public int PowerOnRetries { get; set; }
+19 -4
View File
@@ -148,6 +148,7 @@
this.edtDelayDisplaySettings = new System.Windows.Forms.NumericUpDown();
this.label6 = new System.Windows.Forms.Label();
this.grpGeneralOptions = new System.Windows.Forms.GroupBox();
this.chkMinimizeToSystemTray = new System.Windows.Forms.CheckBox();
this.chkMinimizeOnClose = new System.Windows.Forms.CheckBox();
this.chkStartMinimized = new System.Windows.Forms.CheckBox();
this.chkStartAfterLogin = new System.Windows.Forms.CheckBox();
@@ -906,10 +907,11 @@
"Automatically power off on shutdown. Because this app cannot detect a restart, re" +
"starting could also trigger this. Hold down Ctrl on restart to prevent power off" +
".",
"Automatically power off on standby"});
"Automatically power off on standby",
"Automatically power off on screensaver and power on when screensaver deactivates"});
this.clbLgPower.Location = new System.Drawing.Point(6, 33);
this.clbLgPower.Name = "clbLgPower";
this.clbLgPower.Size = new System.Drawing.Size(829, 64);
this.clbLgPower.Size = new System.Drawing.Size(829, 79);
this.clbLgPower.TabIndex = 34;
this.clbLgPower.ItemCheck += new System.Windows.Forms.ItemCheckEventHandler(this.clbLgPower_ItemCheck);
//
@@ -1154,10 +1156,10 @@
| System.Windows.Forms.AnchorStyles.Right)));
this.lvLgPresets.FullRowSelect = true;
this.lvLgPresets.HideSelection = false;
this.lvLgPresets.Location = new System.Drawing.Point(6, 103);
this.lvLgPresets.Location = new System.Drawing.Point(6, 116);
this.lvLgPresets.MultiSelect = false;
this.lvLgPresets.Name = "lvLgPresets";
this.lvLgPresets.Size = new System.Drawing.Size(829, 185);
this.lvLgPresets.Size = new System.Drawing.Size(829, 172);
this.lvLgPresets.TabIndex = 8;
this.lvLgPresets.UseCompatibleStateImageBehavior = false;
this.lvLgPresets.View = System.Windows.Forms.View.Details;
@@ -1435,6 +1437,7 @@
//
// grpGeneralOptions
//
this.grpGeneralOptions.Controls.Add(this.chkMinimizeToSystemTray);
this.grpGeneralOptions.Controls.Add(this.chkMinimizeOnClose);
this.grpGeneralOptions.Controls.Add(this.chkStartMinimized);
this.grpGeneralOptions.Controls.Add(this.chkStartAfterLogin);
@@ -1445,6 +1448,17 @@
this.grpGeneralOptions.TabStop = false;
this.grpGeneralOptions.Text = "General";
//
// chkMinimizeToSystemTray
//
this.chkMinimizeToSystemTray.AutoSize = true;
this.chkMinimizeToSystemTray.Location = new System.Drawing.Point(204, 19);
this.chkMinimizeToSystemTray.Name = "chkMinimizeToSystemTray";
this.chkMinimizeToSystemTray.Size = new System.Drawing.Size(133, 17);
this.chkMinimizeToSystemTray.TabIndex = 5;
this.chkMinimizeToSystemTray.Text = "Minimize to system tray";
this.chkMinimizeToSystemTray.UseVisualStyleBackColor = true;
this.chkMinimizeToSystemTray.CheckedChanged += new System.EventHandler(this.chkMinimizeToSystemTray_CheckedChanged);
//
// chkMinimizeOnClose
//
this.chkMinimizeOnClose.AutoSize = true;
@@ -1783,6 +1797,7 @@
private System.Windows.Forms.Button btnApplyAmd;
private System.Windows.Forms.ListView lvAmdPresets;
private System.Windows.Forms.Button btnAddAmd;
private System.Windows.Forms.CheckBox chkMinimizeToSystemTray;
}
}
+64 -82
View File
@@ -1,6 +1,5 @@
using ATI.ADL;
using LgTv;
using Microsoft.Win32;
using NLog;
using NStandard;
using NvAPIWrapper.Display;
@@ -16,8 +15,6 @@ using System.Drawing;
using System.IO;
using System.Linq;
using System.Reflection;
// 1. Import the InteropServices type
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using System.Web.Script.Serialization;
using System.Windows.Forms;
@@ -26,13 +23,6 @@ namespace ColorControl
{
public partial class MainForm : Form
{
[DllImport("user32.dll")]
public extern static bool ShutdownBlockReasonCreate(IntPtr hWnd, [MarshalAs(UnmanagedType.LPWStr)] string pwszReason);
[DllImport("user32.dll")]
public extern static bool ShutdownBlockReasonDestroy(IntPtr hWnd);
private static int WM_HOTKEY = 0x0312;
private static string TS_TASKNAME = "ColorControl";
private static bool SystemShutdown = false;
private static bool EndSession = false;
@@ -48,7 +38,7 @@ namespace ColorControl
private JavaScriptSerializer _JsonDeserializer = new JavaScriptSerializer();
private string _lastDisplayRefreshRates = string.Empty;
private NotifyIcon trayIcon;
private NotifyIcon _trayIcon;
private bool _initialized = false;
private string _configFilename;
private Config _config;
@@ -74,26 +64,29 @@ namespace ColorControl
InitLogger();
_configFilename = Path.Combine(_dataDir, "Settings.json");
LoadConfig();
MessageForms.MainForm = this;
_nvTrayMenu = new MenuItem("NVIDIA presets");
_lgTrayMenu = new MenuItem("LG presets");
trayIcon = new NotifyIcon()
_trayIcon = new NotifyIcon()
{
Icon = Icon,
ContextMenu = new ContextMenu(new MenuItem[] {
_nvTrayMenu,
_lgTrayMenu,
new MenuItem("-", OpenForm),
new MenuItem("-"),
new MenuItem("Open", OpenForm),
new MenuItem("-"),
new MenuItem("Exit", Exit)
}),
Visible = true,
Visible = _config.MinimizeToTray,
Text = Text
};
trayIcon.MouseDoubleClick += trayIcon_MouseDoubleClick;
trayIcon.ContextMenu.Popup += trayIconContextMenu_Popup;
_trayIcon.MouseDoubleClick += trayIcon_MouseDoubleClick;
_trayIcon.ContextMenu.Popup += trayIconContextMenu_Popup;
chkStartAfterLogin.Checked = Utils.TaskExists(TS_TASKNAME, true);
@@ -103,15 +96,14 @@ namespace ColorControl
chkFixChromeFonts.Checked = Utils.IsChromeFixInstalled();
}
_configFilename = Path.Combine(_dataDir, "Settings.json");
LoadConfig();
InitNvService();
InitAmdService();
InitLgService();
InitInfo();
UserSessionInfo.Install();
_restartDetector = new RestartDetector();
//Scale(new SizeF(1.25F, 1.25F));
@@ -130,7 +122,8 @@ namespace ColorControl
}
catch (Exception e)
{
Logger.Error("Error initializing NvService: " + e.ToLogString());
//Logger.Error("Error initializing NvService: " + e.ToLogString());
Logger.Debug("No NVIDIA device detected");
tcMain.TabPages.Remove(tabNVIDIA);
}
}
@@ -140,12 +133,12 @@ namespace ColorControl
try
{
_amdService = new AmdService(_dataDir);
//lblErrorAMD.Text = "If you see this message, it means you have AMD graphics drivers installed. Unfortunately, this feature is not completed yet. If I get an AMD card I might finish it.";
FillAmdPresets();
}
catch (Exception e)
{
Logger.Error("Error initializing AmdService: " + e.ToLogString());
//Logger.Error("Error initializing AmdService: " + e.ToLogString());
Logger.Debug("No AMD device detected");
tcMain.TabPages.Remove(tabAMD);
}
}
@@ -162,6 +155,7 @@ namespace ColorControl
clbLgPower.SetItemChecked(1, _lgService.Config.PowerOnAfterResume);
clbLgPower.SetItemChecked(2, _lgService.Config.PowerOffOnShutdown);
clbLgPower.SetItemChecked(3, _lgService.Config.PowerOffOnStandby);
clbLgPower.SetItemChecked(4, _lgService.Config.PowerSwitchOnScreenSaver);
edtLgMaxPowerOnRetries.Value = _lgService.Config.PowerOnRetries;
edtLgDeviceFilter.Text = _lgService.Config.DeviceSearchKey;
chkLgOldWolMechanism.Checked = _lgService.Config.UseOldNpcapWol;
@@ -188,9 +182,7 @@ namespace ColorControl
item.Click += miLgAddAction_Click;
}
SystemEvents.PowerModeChanged += new PowerModeChangedEventHandler(PowerModeChanged);
//SystemEvents.SessionEnded += new SessionEndedEventHandler(SessionEnded);
_lgService.InstallEventHandlers();
}
catch (Exception e)
{
@@ -198,49 +190,6 @@ namespace ColorControl
}
}
private void PowerModeChanged(object sender, PowerModeChangedEventArgs e)
{
var powerOn = e.Mode == PowerModes.Resume;
Logger.Debug($"PowerModeChanged: {e.Mode}");
if (powerOn)
{
_lgService.DisposeConnection();
_lgService.WakeAfterResume();
return;
}
if (_lgService.Config.PowerOffOnStandby)
{
NativeMethods.SetThreadExecutionState(NativeConstants.ES_CONTINUOUS | NativeConstants.ES_SYSTEM_REQUIRED | NativeConstants.ES_AWAYMODE_REQUIRED);
try
{
Logger.Debug("Powering off tv...");
var task = _lgService.PowerOff();
Utils.WaitForTask(task);
Logger.Debug("Done powering off tv");
}
finally
{
NativeMethods.SetThreadExecutionState(NativeConstants.ES_CONTINUOUS);
}
}
}
private void SessionEnded(object sender, SessionEndedEventArgs e)
{
//if (e.Reason == SessionEndReasons.SystemShutdown)
//{
// Logger.Debug($"SessionEnded: {e.Reason}");
// if (_lgService.Config.PowerOffOnShutdown)
// {
// _lgService.PowerOff();
// }
//}
}
private void InitLogger()
{
var config = new NLog.Config.LoggingConfiguration();
@@ -284,6 +233,7 @@ namespace ColorControl
{
Show();
WindowState = FormWindowState.Normal;
Activate();
}
void Exit(object sender, EventArgs e)
@@ -377,7 +327,7 @@ namespace ColorControl
text += "\n" + displayInfo.InfoLine;
}
Utils.SetNotifyIconText(trayIcon, text);
Utils.SetNotifyIconText(_trayIcon, text);
}
private void UpdateDisplayInfoItemsAmd()
@@ -433,7 +383,7 @@ namespace ColorControl
text += "\n" + displayInfo.InfoLine;
}
Utils.SetNotifyIconText(trayIcon, text);
Utils.SetNotifyIconText(_trayIcon, text);
}
private void AddOrUpdateItem(NvPreset preset = null)
@@ -520,7 +470,7 @@ namespace ColorControl
protected override void WndProc(ref Message m)
{
// 5. Catch when a HotKey is pressed !
if (m.Msg == WM_HOTKEY && !edtShortcut.Focused && !edtShortcutLg.Focused && !edtAmdShortcut.Focused && !edtBlankScreenSaverShortcut.Focused)
if (m.Msg == NativeConstants.WM_HOTKEY && !edtShortcut.Focused && !edtShortcutLg.Focused && !edtAmdShortcut.Focused && !edtBlankScreenSaverShortcut.Focused)
{
int id = m.WParam.ToInt32();
@@ -559,6 +509,11 @@ namespace ColorControl
{
EndSession = true;
}
else if (m.Msg == Utils.WM_BRINGTOFRONT)
{
Logger.Debug("WM_BRINGTOFRONT message received, opening form");
OpenForm(this, EventArgs.Empty);
}
base.WndProc(ref m);
}
@@ -592,14 +547,17 @@ namespace ColorControl
private void MainForm_FormClosed(object sender, FormClosedEventArgs e)
{
// Hide tray icon, otherwise it will remain shown until user mouses over it
trayIcon.Visible = false;
_trayIcon.Visible = false;
}
private void MainForm_Resize(object sender, EventArgs e)
{
if (WindowState == FormWindowState.Minimized)
{
Hide();
if (_config.MinimizeToTray)
{
Hide();
}
}
else if (WindowState == FormWindowState.Normal && _config != null)
{
@@ -632,6 +590,7 @@ namespace ColorControl
chkStartMinimized.Checked = _config.StartMinimized;
chkMinimizeOnClose.Checked = _config.MinimizeOnClose;
chkMinimizeToSystemTray.Checked = _config.MinimizeToTray;
edtDelayDisplaySettings.Value = _config.DisplaySettingsDelay;
edtBlankScreenSaverShortcut.Text = _config.ScreenSaverShortcut;
@@ -707,7 +666,14 @@ namespace ColorControl
if (!_setVisibleCalled && _config.StartMinimized)
{
_setVisibleCalled = true;
value = false;
if (_config.MinimizeToTray)
{
value = false;
}
else
{
WindowState = FormWindowState.Minimized;
}
}
if (!IsDisposed) {
base.SetVisibleCore(value);
@@ -1256,18 +1222,22 @@ namespace ColorControl
grpNvidiaOptions.Visible = _nvService != null;
if (grpNvidiaOptions.Visible)
{
if (cbxDitheringBitDepth.Items.Count == 0)
var firstTime = cbxDitheringBitDepth.Items.Count == 0;
if (firstTime)
{
cbxDitheringBitDepth.Items.AddRange(Utils.GetDescriptions<NvDitherBits>().ToArray());
cbxDitheringMode.Items.AddRange(Utils.GetDescriptions<NvDitherMode>().ToArray());
}
var preset = _nvService.GetLastAppliedPreset() ?? GetSelectedNvPreset();
chkDitheringEnabled.Checked = preset?.ditheringEnabled ?? true;
cbxDitheringBitDepth.SelectedIndex = (int)(preset?.ditheringBits ?? (int)NvDitherBits.Bits8);
cbxDitheringMode.SelectedIndex = (int)(preset?.ditheringMode ?? (int)NvDitherMode.Temporal);
FillGradient();
if (firstTime || preset != null)
{
chkDitheringEnabled.Checked = preset?.ditheringEnabled ?? true;
cbxDitheringBitDepth.SelectedIndex = (int)(preset?.ditheringBits ?? (int)NvDitherBits.Bits8);
cbxDitheringMode.SelectedIndex = (int)(preset?.ditheringMode ?? (int)NvDitherMode.Temporal);
FillGradient();
}
}
}
}
@@ -1630,12 +1600,12 @@ namespace ColorControl
return;
}
if (!(_lgService.Config.PowerOnAfterResume || _lgService.Config.PowerOnAfterStartup))
if (!(_lgService.Config.PowerOnAfterResume || _lgService.Config.PowerOnAfterStartup || _lgService.Config.PowerSwitchOnScreenSaver))
{
MessageForms.InfoOk(
@"Be sure to activate the following setting on the TV, or the app will not be able to wake the TV:
Connection > Mobile TV On > Turn on via Wi-Fi
Connection > Mobile TV On > Turn on via Wi-Fi (Networked Standby Mode)
See Options to test this functionality."
);
@@ -1647,6 +1617,9 @@ See Options to test this functionality."
_lgService.Config.PowerOnAfterResume = clbLgPower.GetItemChecked(1);
_lgService.Config.PowerOffOnShutdown = clbLgPower.GetItemChecked(2);
_lgService.Config.PowerOffOnStandby = clbLgPower.GetItemChecked(3);
_lgService.Config.PowerSwitchOnScreenSaver = clbLgPower.GetItemChecked(4);
_lgService.InstallEventHandlers();
}));
}
@@ -2218,5 +2191,14 @@ Do you want to continue?";
MessageForms.InfoOk("All presets for every color setting already exist.");
}
}
private void chkMinimizeToSystemTray_CheckedChanged(object sender, EventArgs e)
{
if (_initialized)
{
_config.MinimizeToTray = chkMinimizeToSystemTray.Checked;
_trayIcon.Visible = _config.MinimizeToTray;
}
}
}
}
+16 -2
View File
@@ -227,11 +227,24 @@ namespace ColorControl
return result;
}
private ColorData GetCurrentColorData(Display display)
{
try
{
return display.DisplayDevice.CurrentColorData;
}
catch (Exception e)
{
Logger.Error("Error while reading current color data: " + e.Message);
return new ColorData();
}
}
private bool ColorDataDiffers(ColorData colorData)
{
var display = GetCurrentDisplay();
var currentColorData = display.DisplayDevice.CurrentColorData;
var currentColorData = GetCurrentColorData(display);
var settingRange = colorData.DynamicRange == ColorDataDynamicRange.Auto ? colorData.ColorFormat == ColorDataFormat.RGB ? ColorDataDynamicRange.VESA : ColorDataDynamicRange.CEA : colorData.DynamicRange;
@@ -401,7 +414,8 @@ namespace ColorControl
values.Add(name);
var colorData = display.DisplayDevice.CurrentColorData;
var colorData = GetCurrentColorData(display);
var colorSettings = string.Format("{0}, {1}, {2}, {3}", colorData.ColorDepth, colorData.ColorFormat, colorData.DynamicRange, colorData.Colorimetry);
values.Add(colorSettings);
+27 -1
View File
@@ -1,4 +1,7 @@
using System;
using NWin32;
using System;
using System.Diagnostics;
using System.Text;
using System.Threading;
using System.Windows.Forms;
@@ -33,6 +36,22 @@ namespace ColorControl
{
if (!mutexCreated)
{
var currentProcessId = Process.GetCurrentProcess().Id;
foreach (var process in Process.GetProcesses())
{
if (process.ProcessName.Equals("ColorControl") && process.Id != currentProcessId)
{
if (process.Threads.Count > 0)
{
var thread = process.Threads[0];
NativeMethods.EnumThreadWindows((uint)thread.Id, EnumThreadWindows, IntPtr.Zero);
}
return;
}
}
MessageBox.Show("Only one instance of this program can be active.", "ColorControl");
}
else
@@ -58,6 +77,13 @@ namespace ColorControl
}
}
public static int EnumThreadWindows(IntPtr handle, IntPtr param)
{
NativeMethods.SendMessageW(handle, Utils.WM_BRINGTOFRONT, UIntPtr.Zero, IntPtr.Zero);
return 1;
}
private static void GlobalUnhandledExceptionHandler(object sender, UnhandledExceptionEventArgs e)
{
var ex = (Exception)e.ExceptionObject;
+41
View File
@@ -0,0 +1,41 @@
using Microsoft.Win32;
namespace ColorControl
{
static class UserSessionInfo
{
private static readonly NLog.Logger Logger = NLog.LogManager.GetCurrentClassLogger();
public static bool UserLocalSession { get; private set; } = true;
public static SessionSwitchReason LastSessionSwitchReason { get; private set; } = 0;
public delegate void UserSessionSwitchHandler(bool toLocal);
public static event UserSessionSwitchHandler UserSessionSwitch;
public static void Install()
{
SystemEvents.SessionSwitch += SessionSwitchHandler;
}
public static void SessionSwitchHandler(object sender, SessionSwitchEventArgs evt)
{
if (evt.Reason == SessionSwitchReason.ConsoleDisconnect)
{
Logger.Debug("Detected a disconnect from the console");
UserLocalSession = false;
UserSessionSwitch(false);
}
else if (evt.Reason == SessionSwitchReason.ConsoleConnect)
{
Logger.Debug("Detected a connect to the console");
if (!UserLocalSession)
{
Logger.Debug("Session state switched to local");
UserLocalSession = true;
UserSessionSwitch(true);
}
}
LastSessionSwitchReason = evt.Reason;
}
}
}
+48 -1
View File
@@ -1,7 +1,7 @@
using Microsoft.Win32;
using Microsoft.Win32.TaskScheduler;
using NStandard;
using NvAPIWrapper.Display;
using NWin32;
using System;
using System.Collections.Generic;
using System.ComponentModel;
@@ -33,14 +33,30 @@ namespace ColorControl
Win = 8
}
public const int WM_BRINGTOFRONT = NativeConstants.WM_USER + 1;
public static string PKEY_PNPX_IpAddress = "{656a3bb3-ecc0-43fd-8477-4ae0404a96cd} 12297";
public static string PKEY_PNPX_PhysicalAddress = "{656a3bb3-ecc0-43fd-8477-4ae0404a96cd} 12294";
public delegate void PCREATE_PROCESS_NOTIFY_ROUTINE(IntPtr ParentId, IntPtr ProcessId, bool Create);
[DllImport("user32.dll")]
public static extern bool RegisterHotKey(IntPtr hWnd, int id, int fsModifiers, int vlc);
[DllImport("user32.dll")]
public static extern bool UnregisterHotKey(IntPtr hWnd, int id);
[DllImport("user32.dll")]
public extern static bool ShutdownBlockReasonCreate(IntPtr hWnd, [MarshalAs(UnmanagedType.LPWStr)] string pwszReason);
[DllImport("user32.dll")]
public extern static bool ShutdownBlockReasonDestroy(IntPtr hWnd);
//[DllImport("Wtsapi32.dll")]
//public extern static bool WTSRegisterSessionNotification(IntPtr hWnd, uint dwFlags);
//[DllImport("Wtsapi32.dll")]
//public extern static bool WTSUnRegisterSessionNotification(IntPtr hWnd);
private static readonly NLog.Logger Logger = NLog.LogManager.GetCurrentClassLogger();
private static bool WinKeyDown = false;
@@ -602,7 +618,38 @@ namespace ColorControl
}
}
}
}
public static class ProcessExtensions
{
private static string FindIndexedProcessName(int pid)
{
var processName = Process.GetProcessById(pid).ProcessName;
var processesByName = Process.GetProcessesByName(processName);
string processIndexdName = null;
for (var index = 0; index < processesByName.Length; index++)
{
processIndexdName = index == 0 ? processName : processName + "#" + index;
var processId = new PerformanceCounter("Process", "ID Process", processIndexdName);
if ((int)processId.NextValue() == pid)
{
return processIndexdName;
}
}
return processIndexdName;
}
private static Process FindPidFromIndexedProcessName(string indexedProcessName)
{
var parentId = new PerformanceCounter("Process", "Creating Process ID", indexedProcessName);
return Process.GetProcessById((int)parentId.NextValue());
}
public static Process Parent(this Process process)
{
return FindPidFromIndexedProcessName(FindIndexedProcessName(process.Id));
}
}
}
-3
View File
@@ -1,13 +1,10 @@
using ColorControl;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Windows.Foundation;
using Windows.Storage;
namespace LgTv
{
+7 -7
View File
@@ -1,6 +1,5 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Newtonsoft.Json;
@@ -9,7 +8,6 @@ using Windows.Storage.Streams;
using Windows.Web;
using Newtonsoft.Json.Serialization;
using Newtonsoft.Json.Linq;
using Windows.Foundation;
namespace LgTv
{
@@ -32,8 +30,7 @@ namespace LgTv
public event IsConnectedDelegate IsConnected;
private readonly ConcurrentDictionary<string, TaskCompletionSource<dynamic>> _tokens = new ConcurrentDictionary<string, TaskCompletionSource<dynamic>>();
private static void Log(RawRequestMessage message) { }
private static readonly NLog.Logger Logger = NLog.LogManager.GetCurrentClassLogger();
public async Task<bool> Connect(Uri uri, bool ignoreReceiver = false)
{
@@ -67,7 +64,6 @@ namespace LgTv
}
return false;
}
}
public async void SendMessageAsync(string message)
@@ -77,8 +73,9 @@ namespace LgTv
_messageWriter.WriteString(message);
await _messageWriter.StoreAsync();
}
catch (Exception)
catch (Exception e)
{
Logger.Error("SendMessageAsync: " + e.Message);
ConnectionClosed = true;
_messageWriter?.Dispose();
}
@@ -167,7 +164,10 @@ namespace LgTv
}
catch (Exception ex)
{
WebErrorStatus status = WebSocketError.GetStatus(ex.GetBaseException().HResult);
var status = WebSocketError.GetStatus(ex.GetBaseException().HResult);
Logger.Error($"Connection_MessageReceived: status: {status}, exception: {ex.Message}");
ConnectionClosed = true;
_messageWriter?.Dispose();
}
}
public void Close()
+9 -9
View File
@@ -1,16 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Native" version="0.1.0" targetFramework="net472" />
<package id="Newtonsoft.Json" version="12.0.3" targetFramework="net472" />
<package id="NLog" version="4.7.2" targetFramework="net472" />
<package id="NStandard" version="0.4.3" targetFramework="net472" />
<package id="NvAPIWrapper.Net" version="0.8.0.98" targetFramework="net472" />
<package id="NWin32" version="1.0.6" targetFramework="net472" />
<package id="PacketDotNet" version="1.0.5" targetFramework="net472" />
<package id="SharpPcap" version="5.2.0" targetFramework="net472" />
<package id="Newtonsoft.Json" version="13.0.1" targetFramework="net472" />
<package id="NLog" version="4.7.9" targetFramework="net472" />
<package id="NStandard" version="0.6.12.5" targetFramework="net472" />
<package id="NvAPIWrapper.Net" version="0.8.1.101" targetFramework="net472" />
<package id="NWin32" version="1.0.7.6" targetFramework="net472" />
<package id="PacketDotNet" version="1.2.0" targetFramework="net472" />
<package id="SharpPcap" version="5.4.0" targetFramework="net472" />
<package id="System.Buffers" version="4.5.1" targetFramework="net472" />
<package id="System.Memory" version="4.5.4" targetFramework="net472" />
<package id="System.Numerics.Vectors" version="4.5.0" targetFramework="net472" />
<package id="System.Runtime.CompilerServices.Unsafe" version="4.7.0" targetFramework="net472" />
<package id="TaskScheduler" version="2.8.20" targetFramework="net472" />
<package id="System.Runtime.CompilerServices.Unsafe" version="5.0.0" targetFramework="net472" />
<package id="TaskScheduler" version="2.9.1" targetFramework="net472" />
</packages>