From 8fe01e8790fa812479a24126b6c561e5d1d7f172 Mon Sep 17 00:00:00 2001 From: seerge Date: Mon, 13 Mar 2023 19:38:39 +0100 Subject: [PATCH] New sleep/wake up detection --- GHelper.csproj | 2 +- NativeMethods.cs | 76 ++++++++++++++++++++++++++++++++++++++++++------ Program.cs | 43 ++++++++++++++++++--------- Settings.cs | 32 ++++++++++++++++++++ 4 files changed, 129 insertions(+), 24 deletions(-) diff --git a/GHelper.csproj b/GHelper.csproj index ecb29b71..ed9661a4 100644 --- a/GHelper.csproj +++ b/GHelper.csproj @@ -16,7 +16,7 @@ x64 False True - 0.25 + 0.26 diff --git a/NativeMethods.cs b/NativeMethods.cs index 88d93d09..b7af3aad 100644 --- a/NativeMethods.cs +++ b/NativeMethods.cs @@ -1,9 +1,8 @@ -using System.ComponentModel; +using System.Collections; +using System; +using System.ComponentModel; using System.Diagnostics; -using System.Management; using System.Runtime.InteropServices; -using System.Windows.Forms; -using Tools; using static Tools.ScreenInterrogatory; namespace Tools @@ -310,6 +309,62 @@ namespace Tools public class NativeMethods { + // Monitor Power detection + + internal const uint DEVICE_NOTIFY_WINDOW_HANDLE = 0x0; + internal const uint DEVICE_NOTIFY_SERVICE_HANDLE = 0x1; + internal const int WM_POWERBROADCAST = 0x0218; + internal const int PBT_POWERSETTINGCHANGE = 0x8013; + + [DllImport("User32.dll", SetLastError = true)] + internal static extern IntPtr RegisterPowerSettingNotification(IntPtr hWnd, [In] Guid PowerSettingGuid, uint Flags); + + [DllImport("User32.dll", SetLastError = true)] + internal static extern bool UnregisterPowerSettingNotification(IntPtr hWnd); + + [StructLayout(LayoutKind.Sequential, Pack = 4)] + internal struct POWERBROADCAST_SETTING + { + public Guid PowerSetting; + public uint DataLength; + public byte Data; + } + + public class PowerSettingGuid + { + // 0=Powered by AC, 1=Powered by Battery, 2=Powered by short-term source (UPC) + public Guid AcdcPowerSource { get; } = new Guid("5d3e9a59-e9D5-4b00-a6bd-ff34ff516548"); + // POWERBROADCAST_SETTING.Data = 1-100 + public Guid BatteryPercentageRemaining { get; } = new Guid("a7ad8041-b45a-4cae-87a3-eecbb468a9e1"); + // Windows 8+: 0=Monitor Off, 1=Monitor On, 2=Monitor Dimmed + public Guid ConsoleDisplayState { get; } = new Guid("6fe69556-704a-47a0-8f24-c28d936fda47"); + // Windows 8+, Session 0 enabled: 0=User providing Input, 2=User Idle + public Guid GlobalUserPresence { get; } = new Guid("786E8A1D-B427-4344-9207-09E70BDCBEA9"); + // 0=Monitor Off, 1=Monitor On. + public Guid MonitorPowerGuid { get; } = new Guid("02731015-4510-4526-99e6-e5a17ebd1aea"); + // 0=Battery Saver Off, 1=Battery Saver On. + public Guid PowerSavingStatus { get; } = new Guid("E00958C0-C213-4ACE-AC77-FECCED2EEEA5"); + + // Windows 8+: 0=Off, 1=On, 2=Dimmed + public Guid SessionDisplayStatus { get; } = new Guid("2B84C20E-AD23-4ddf-93DB-05FFBD7EFCA5"); + + // Windows 8+, no Session 0: 0=User providing Input, 2=User Idle + public Guid SessionUserPresence { get; } = new Guid("3C0F4548-C03F-4c4d-B9F2-237EDE686376"); + // 0=Exiting away mode 1=Entering away mode + public Guid SystemAwaymode { get; } = new Guid("98a7f580-01f7-48aa-9c0f-44352c29e5C0"); + + /* Windows 8+ */ + // POWERBROADCAST_SETTING.Data not used + public Guid IdleBackgroundTask { get; } = new Guid(0x515C31D8, 0xF734, 0x163D, 0xA0, 0xFD, 0x11, 0xA0, 0x8C, 0x91, 0xE8, 0xF1); + + public Guid PowerSchemePersonality { get; } = new Guid(0x245D8541, 0x3943, 0x4422, 0xB0, 0x25, 0x13, 0xA7, 0x84, 0xF6, 0x79, 0xB7); + + // The Following 3 Guids are the POWERBROADCAST_SETTING.Data result of PowerSchemePersonality + public Guid MinPowerSavings { get; } = new Guid("8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c"); + public Guid MaxPowerSavings { get; } = new Guid("a1841308-3541-4fab-bc81-f71556f20b4a"); + public Guid TypicalPowerSavings { get; } = new Guid("381b4222-f694-41f0-9685-ff5bb260df2e"); + } + public const int KEYEVENTF_EXTENDEDKEY = 1; public const int KEYEVENTF_KEYUP = 2; @@ -495,27 +550,30 @@ public class NativeMethods displayNum = count; } count++; - //Debug.WriteLine(device.outputTechnology); + Debug.WriteLine(device.outputTechnology); //Debug.WriteLine(device.monitorFriendlyDeviceName); } - if (Screen.AllScreens.Length != count) + var screens = Screen.AllScreens; + + if (screens.Length != count) { Debug.WriteLine("Mismatch between enumerated and available screens"); return null; } count = 0; - foreach (var screen in Screen.AllScreens) + foreach (var screen in screens) { if (count == displayNum) { laptopScreen = screen.DeviceName; } - //Debug.WriteLine(screen.DeviceName); + Debug.WriteLine(screen.DeviceName); count++; } - } catch + } + catch { Debug.WriteLine("Can't find internal screen"); } diff --git a/Program.cs b/Program.cs index ad9ab4eb..625b6573 100644 --- a/Program.cs +++ b/Program.cs @@ -1,5 +1,4 @@ using Microsoft.Win32; -using System; using System.Diagnostics; using System.Management; using System.Reflection; @@ -47,7 +46,7 @@ public static class Logger using (StreamWriter w = File.AppendText(logFile)) { Debug.WriteLine(logMessage); - w.WriteLine($"{DateTime.Now.ToUniversalTime()}: {logMessage}"); + w.WriteLine($"{DateTime.Now}: {logMessage}"); } } @@ -98,6 +97,11 @@ namespace GHelper public static SettingsForm settingsForm = new SettingsForm(); public static ToastForm toast = new ToastForm(); + private static IntPtr unRegPowerNotify; + private static IntPtr ds; + + private static long lastAuto; + // The main entry point for the application public static void Main() { @@ -120,6 +124,8 @@ namespace GHelper Application.EnableVisualStyles(); + ds = settingsForm.Handle; + trayIcon.MouseClick += TrayIcon_MouseClick; ; wmi.SubscribeToEvents(WatcherEventArrived); @@ -134,6 +140,9 @@ namespace GHelper SetAutoModes(); + // Subscribing for native power change events + + /* IntPtr registrationHandle = new IntPtr(); DEVICE_NOTIFY_SUBSCRIBE_PARAMETERS recipient = new DEVICE_NOTIFY_SUBSCRIBE_PARAMETERS(); recipient.Callback = new DeviceNotifyCallbackRoutine(DeviceNotifyCallback); @@ -143,18 +152,21 @@ namespace GHelper Marshal.StructureToPtr(recipient, pRecipient, false); uint result = PowerRegisterSuspendResumeNotification(DEVICE_NOTIFY_CALLBACK, ref recipient, ref registrationHandle); + */ + // Subscribing for monitor power on events + var settingGuid = new NativeMethods.PowerSettingGuid(); + unRegPowerNotify = NativeMethods.RegisterPowerSettingNotification(ds, settingGuid.ConsoleDisplayState, NativeMethods.DEVICE_NOTIFY_WINDOW_HANDLE); + + // Subscribing for system power change events SystemEvents.PowerModeChanged += SystemEvents_PowerModeChanged; - IntPtr ds = settingsForm.Handle; CheckForUpdates(); - Application.Run(); } - private static int DeviceNotifyCallback(IntPtr context, int type, IntPtr setting) { Logger.WriteLine($"Power callback {type}"); @@ -163,10 +175,6 @@ namespace GHelper case PBT_APMRESUMEAUTOMATIC: settingsForm.BeginInvoke(delegate { - // Fix for bugging buios on wake up - Program.wmi.DeviceSet(ASUSWmi.PerformanceMode, (config.getConfig("performance_mode")+1) % 3); - Thread.Sleep(3000); - SetAutoModes(); }); break; @@ -191,7 +199,7 @@ namespace GHelper var config = JsonSerializer.Deserialize(json); var tag = config.GetProperty("tag_name").ToString().Replace("v", ""); var url = config.GetProperty("assets")[0].GetProperty("browser_download_url").ToString(); - + var gitVersion = new Version(tag); var appVersion = new Version(assembly); @@ -202,18 +210,24 @@ namespace GHelper } } - } catch { + } + catch + { Logger.WriteLine("Failed to get update"); } } - private static void SetAutoModes() + public static void SetAutoModes() { + + if (Math.Abs(DateTimeOffset.Now.ToUnixTimeMilliseconds() - lastAuto) < 1000) return; + lastAuto = DateTimeOffset.Now.ToUnixTimeMilliseconds(); + PowerLineStatus isPlugged = SystemInformation.PowerStatus.PowerLineStatus; - Logger.WriteLine("Power " + isPlugged.ToString()); + Logger.WriteLine("AutoSetting for " + isPlugged.ToString()); settingsForm.SetBatteryChargeLimit(config.getConfig("charge_limit")); @@ -320,7 +334,7 @@ namespace GHelper int EventID = int.Parse(e.NewEvent["EventID"].ToString()); - Logger.WriteLine("WMI event "+EventID); + Logger.WriteLine("WMI event " + EventID); switch (EventID) { @@ -368,6 +382,7 @@ namespace GHelper static void OnExit(object sender, EventArgs e) { trayIcon.Visible = false; + NativeMethods.UnregisterPowerSettingNotification(unRegPowerNotify); Application.Exit(); } } diff --git a/Settings.cs b/Settings.cs index 61cb8cab..83e789eb 100644 --- a/Settings.cs +++ b/Settings.cs @@ -98,6 +98,38 @@ namespace GHelper } + + protected override void WndProc(ref Message m) + { + switch (m.Msg) + { + case NativeMethods.WM_POWERBROADCAST: + if (m.WParam == (IntPtr)NativeMethods.PBT_POWERSETTINGCHANGE) + { + var settings = (NativeMethods.POWERBROADCAST_SETTING)m.GetLParam(typeof(NativeMethods.POWERBROADCAST_SETTING)); + switch (settings.Data) + { + case 0: + Logger.WriteLine("Monitor Power Off"); + break; + case 1: + Logger.WriteLine("Monitor Power On"); + Program.settingsForm.BeginInvoke(delegate + { + Program.SetAutoModes(); + }); + break; + case 2: + Logger.WriteLine("Monitor Dimmed"); + break; + } + } + m.Result = (IntPtr)1; + break; + } + base.WndProc(ref m); + } + private void CheckGPU_CheckedChanged(object? sender, EventArgs e) { if (sender is null) return;