Skip to content

Commit

Permalink
add screensaver trigger, focus main window when already started, fix …
Browse files Browse the repository at this point in the history
…some bugs
  • Loading branch information
Maassoft committed Apr 3, 2021
1 parent a33543a commit 0c87762
Show file tree
Hide file tree
Showing 15 changed files with 449 additions and 134 deletions.
5 changes: 1 addition & 4 deletions ColorControl/ADLWrapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ public static bool Initialize()
{
int ADLRet = -1;

Logger.Debug("Initialize");
//Logger.Debug("Initialize");

var del = ADL.GetDelegate<ADL.ADL_Main_Control_Create>();

Expand All @@ -77,15 +77,12 @@ public static bool Initialize()
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));
}

Expand Down
6 changes: 5 additions & 1 deletion ColorControl/App.config
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down
36 changes: 19 additions & 17 deletions ColorControl/ColorControl.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -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">
Expand All @@ -137,15 +137,16 @@
<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>
<Reference Include="System.Numerics" />
<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">
Expand Down Expand Up @@ -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" />
Expand Down
3 changes: 3 additions & 0 deletions ColorControl/Config.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ class Config

public bool MinimizeOnClose { get; set; }

public bool MinimizeToTray { get; set; }

public int DisplaySettingsDelay { get; set; }

public string ScreenSaverShortcut { get; set; }
Expand All @@ -23,6 +25,7 @@ public Config()
ScreenSaverShortcut = string.Empty;
FormWidth = 900;
FormHeight = 600;
MinimizeToTray = true;
}
}
}
191 changes: 188 additions & 3 deletions ColorControl/LgService.cs
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -50,6 +53,11 @@ public PnpDev SelectedDevice

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;
Expand Down Expand Up @@ -318,7 +326,7 @@ private async Task<bool> Connected(bool reconnect = false)
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())
{
Expand All @@ -328,7 +336,11 @@ private async Task<bool> Connected(bool reconnect = false)
}
return true;
}


private bool IsConnected()
{
return !_lgTvApi?.ConnectionClosed ?? false;
}

public async Task<bool> ApplyPreset(LgPreset preset, bool reconnect = false)
{
Expand Down Expand Up @@ -523,8 +535,14 @@ internal void WakeAfterResume()
}
}

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;

Expand Down Expand Up @@ -581,5 +599,172 @@ private async Task<bool> WakeAndConnectToSelectedDevice(int wakeDelay = 5000, in
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 changes: 2 additions & 0 deletions ColorControl/LgServiceConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ class LgServiceConfig

public bool PowerOffOnStandby { get; set; }

public bool PowerSwitchOnScreenSaver { get; set; }

public int PowerOnDelayAfterResume { get; set; }

public int PowerOnRetries { get; set; }
Expand Down
Loading

0 comments on commit 0c87762

Please sign in to comment.