diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..2031fa7 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,5 @@ +[*] +end_of_line = crlf +insert_final_newline = true +indent_style = space +indent_size = 2 \ No newline at end of file diff --git a/src/CecSharpTester/netfx/CecSharpTester.csproj b/src/CecSharpTester/netfx/CecSharpTester.csproj index 2dd6aee..38ee149 100644 --- a/src/CecSharpTester/netfx/CecSharpTester.csproj +++ b/src/CecSharpTester/netfx/CecSharpTester.csproj @@ -10,7 +10,7 @@ Properties CecSharpTester CecSharpTester - v4.5 + v4.8 512 @@ -95,4 +95,4 @@ --> - + \ No newline at end of file diff --git a/src/CecSharpTester/netfx/app.config b/src/CecSharpTester/netfx/app.config index c5e1dae..786a845 100644 --- a/src/CecSharpTester/netfx/app.config +++ b/src/CecSharpTester/netfx/app.config @@ -1,3 +1,3 @@ - + diff --git a/src/LibCecTray/LibCECTray.csproj b/src/LibCecTray/LibCECTray.csproj index 4792c5c..aac596d 100644 --- a/src/LibCecTray/LibCECTray.csproj +++ b/src/LibCecTray/LibCECTray.csproj @@ -1,5 +1,5 @@  - + true ..\..\..\..\build\$(Configuration)\$(Platform)\ @@ -43,7 +43,7 @@ Properties LibCECTray cec-tray - v4.5 + v4.8 512 false publish\ @@ -234,4 +234,4 @@ - + \ No newline at end of file diff --git a/src/LibCecTray/Properties/Resources.Designer.cs b/src/LibCecTray/Properties/Resources.Designer.cs index 0f83d89..6c26cec 100644 --- a/src/LibCecTray/Properties/Resources.Designer.cs +++ b/src/LibCecTray/Properties/Resources.Designer.cs @@ -823,6 +823,15 @@ internal static string global_tv_auto_power_on { } } + /// + /// Looks up a localized string similar to Power on the TV when the PC detects user activity. + /// + internal static string global_tv_power_on_with_activity { + get { + return ResourceManager.GetString("global_tv_power_on_with_activity", resourceCulture); + } + } + /// /// Looks up a localized string similar to TV vendor. /// diff --git a/src/LibCecTray/Properties/Resources.resx b/src/LibCecTray/Properties/Resources.resx index 5a19631..50450a2 100644 --- a/src/LibCecTray/Properties/Resources.resx +++ b/src/LibCecTray/Properties/Resources.resx @@ -663,6 +663,9 @@ CEC will not work (properly) if the TV does not support CEC, or has CEC disabled Power on the TV when the PC starts + + Power on the TV when the PC detects user activity + HDMI port of the {0} diff --git a/src/LibCecTray/app.config b/src/LibCecTray/app.config index f8bc479..add6a8a 100644 --- a/src/LibCecTray/app.config +++ b/src/LibCecTray/app.config @@ -2,5 +2,5 @@ - + diff --git a/src/LibCecTray/controller/Actions.cs b/src/LibCecTray/controller/Actions.cs index 6c8b4a9..38a89d1 100644 --- a/src/LibCecTray/controller/Actions.cs +++ b/src/LibCecTray/controller/Actions.cs @@ -139,6 +139,8 @@ private void ProcessEventHandler(object src, UpdateEvent updateEvent) _controller.Hide(true); } + _controller.InitializationCompleted(); + break; case UpdateEventType.ExitApplication: SuppressUpdates = true; diff --git a/src/LibCecTray/controller/CECController.cs b/src/LibCecTray/controller/CECController.cs index 058c045..3bb15f2 100644 --- a/src/LibCecTray/controller/CECController.cs +++ b/src/LibCecTray/controller/CECController.cs @@ -436,22 +436,53 @@ public void Hide(bool val) { _gui.SafeHide(val); } + + public void InitializationCompleted() + { + CecPowerStatus tvPowerStatus = Lib.GetDevicePowerStatus(CecLogicalAddress.Tv); + TvIsOn = tvPowerStatus == CecPowerStatus.On || tvPowerStatus == CecPowerStatus.InTransitionStandbyToOn; + } #endregion #region Callbacks called by libCEC public override int ReceiveCommand(CecCommand command) { - if (command.Opcode == CecOpcode.Standby && - (command.Destination == CecLogicalAddress.Broadcast || command.Destination == _lib.GetLogicalAddresses().Primary)) - if (Settings.StopTvStandby.Value) - { - var key = new CecKeypress(CecUserControlCode.Stop, 0); - foreach (var app in _applications) - app.SendKey(key, false); - Lib.DisableCallbacks(); - Application.SetSuspendState(PowerState.Suspend, false, false); - } - return 0; + switch (command.Opcode) + { + case CecOpcode.Standby: + { + if (command.Initiator == CecLogicalAddress.Tv) + { + TvIsOn = false; + } + + if (command.Destination == CecLogicalAddress.Broadcast || command.Destination == _lib.GetLogicalAddresses().Primary) + { + if (Settings.StopTvStandby.Value) + { + var key = new CecKeypress(CecUserControlCode.Stop, 0); + foreach (var app in _applications) + app.SendKey(key, false); + Lib.DisableCallbacks(); + Application.SetSuspendState(PowerState.Suspend, false, false); + } + } + + break; + } + + case CecOpcode.GiveDevicePowerStatus: + { + if (command.Initiator == CecLogicalAddress.Tv) + { + TvIsOn = true; + } + + break; + } + } + + return 0; } public override int ReceiveKeypress(CecKeypress key) @@ -681,6 +712,12 @@ public LibCecSharp Lib } private LibCecSharp _lib; + public bool TvIsOn + { + get; + private set; + } + private readonly CECTray _gui; public Actions CECActions; private bool _deviceChangeWarningDisplayed; diff --git a/src/LibCecTray/controller/SystemIdleMonitor.cs b/src/LibCecTray/controller/SystemIdleMonitor.cs index ff251d0..ae4337c 100644 --- a/src/LibCecTray/controller/SystemIdleMonitor.cs +++ b/src/LibCecTray/controller/SystemIdleMonitor.cs @@ -44,7 +44,6 @@ public class SystemIdleMonitor { private SystemIdleMonitor() { - _eventFired = false; _refreshThread = new Thread(Refresh); _refreshThread.Start(); } @@ -151,22 +150,22 @@ private void RefreshIdleTime() { int lastIdleTimeSeconds = IdleTimeSeconds; IdleTimeSeconds = WindowsAPI.SystemIdleSeconds(); - if (IdleTimeoutSeconds <= 0) - { - return; - } - IdleTimeChange change = new IdleTimeChange(IdleTimeSeconds, IdleTimeoutSeconds); - SystemActivity?.Invoke(this, change); + bool lastIsIdle = IsIdle; + IsIdle = IdleTimeSeconds > 0; - if (IdleTimeSeconds < lastIdleTimeSeconds && _eventFired) + if (!IsIdle) { - SystemIdle?.Invoke(this, new IdleChange(false)); - _eventFired = false; + IdleTimeChange change = new IdleTimeChange(IdleTimeSeconds, IdleTimeoutSeconds); + SystemActivity?.Invoke(this, change); } - else if ((IdleTimeSeconds > lastIdleTimeSeconds) && (IdleTimeSeconds >= IdleTimeoutSeconds) && !_eventFired) + + if (lastIsIdle != IsIdle) { - SystemIdle?.Invoke(this, new IdleChange(true)); - _eventFired = true; + bool shouldStandby = + (IdleTimeoutSeconds > 0) && + (IdleTimeSeconds > lastIdleTimeSeconds) && + (IdleTimeSeconds >= IdleTimeoutSeconds); + SystemIdle?.Invoke(this, new IdleChange(IsIdle, shouldStandby)); } } @@ -178,6 +177,15 @@ public int IdleTimeSeconds { private set; } + /// + /// Is the system currently idle? + /// + public bool IsIdle + { + get; + private set; + } + public int IdleTimeoutSeconds { get { return Program.Instance.Controller.Settings.StandbyScreen.AsSettingIdleTime.Value.Seconds; @@ -208,7 +216,6 @@ public static SystemIdleMonitor Instance { public event EventHandler ScreensaverActivated; public event EventHandler PowerStatusChanged; - private bool _eventFired; private static SystemIdleMonitor _instance = null; private bool _stopMonitor = false; private Thread _refreshThread = null; @@ -247,17 +254,24 @@ public ScreensaverChange(bool active) public class IdleChange : EventArgs { - public IdleChange(bool idle) + public IdleChange(bool idle, bool shouldStandby) { Idle = idle; + ShouldStandby = shouldStandby; } public bool Idle { get; private set; } + + public bool ShouldStandby + { + get; + private set; + } } - + public class IdleTimeChange : EventArgs { public IdleTimeChange(int idleTimeSeconds, int idleTimeoutSeconds) diff --git a/src/LibCecTray/settings/CECSettings.cs b/src/LibCecTray/settings/CECSettings.cs index 23c14cc..51f461c 100644 --- a/src/LibCecTray/settings/CECSettings.cs +++ b/src/LibCecTray/settings/CECSettings.cs @@ -56,6 +56,7 @@ class CECSettings public static string KeyStopTvStandby = "global_stop_tv_standby"; public static string KeyStandbyScreen = "global_standby_screen"; public static string KeyTVAutoPowerOn = "global_tv_auto_power_on"; + public static string KeyTVPowerOnWithActivity = "global_tv_power_on_with_activity"; public static string KeyDetectPhysicalAddress = "global_detect_physical_address"; #endregion @@ -363,6 +364,20 @@ public CECSettingBool TVAutoPowerOn { } } + public CECSettingBool TVPowerOnWithActivity + { + get { + if (!_settings.ContainsKey(KeyTVPowerOnWithActivity)) + { + CECSettingBool setting = new CECSettingBool(KeyTVPowerOnWithActivity, Resources.global_tv_power_on_with_activity, true, _changedHandler); + _settings[KeyTVPowerOnWithActivity] = setting; + setting.Load(); + setting.SettingChanged += OnSettingChanged; + } + return _settings[KeyTVPowerOnWithActivity].AsSettingBool; + } + } + public CECSettingIdleTime StandbyScreen { get { if (!_settings.ContainsKey(KeyStandbyScreen)) diff --git a/src/LibCecTray/ui/CECTray.Designer.cs b/src/LibCecTray/ui/CECTray.Designer.cs index c9d57cd..edc2db3 100644 --- a/src/LibCecTray/ui/CECTray.Designer.cs +++ b/src/LibCecTray/ui/CECTray.Designer.cs @@ -76,6 +76,7 @@ private void InitializeComponent() this.powerTab = new System.Windows.Forms.TabPage(); this.bReloadConfig2 = new System.Windows.Forms.Button(); this.cbTVAutoPowerOn = new System.Windows.Forms.CheckBox(); + this.cbTVPowerOnWithActivity = new System.Windows.Forms.CheckBox(); this.pictureBox3 = new System.Windows.Forms.PictureBox(); this.label2 = new System.Windows.Forms.Label(); this.pictureBox2 = new System.Windows.Forms.PictureBox(); @@ -694,6 +695,7 @@ private void InitializeComponent() // this.powerTab.Controls.Add(this.bReloadConfig2); this.powerTab.Controls.Add(this.cbTVAutoPowerOn); + this.powerTab.Controls.Add(this.cbTVPowerOnWithActivity); this.powerTab.Controls.Add(this.pictureBox3); this.powerTab.Controls.Add(this.label2); this.powerTab.Controls.Add(this.pictureBox2); @@ -737,6 +739,17 @@ private void InitializeComponent() this.cbTVAutoPowerOn.Text = "global_tv_auto_power_on"; this.cbTVAutoPowerOn.UseVisualStyleBackColor = true; // + // cbTVPowerOnWithActivity + // + this.cbTVPowerOnWithActivity.AutoSize = true; + this.cbTVPowerOnWithActivity.Enabled = false; + this.cbTVPowerOnWithActivity.Location = new System.Drawing.Point(282, 152); + this.cbTVPowerOnWithActivity.Name = "cbTVPowerOnWithActivity"; + this.cbTVPowerOnWithActivity.Size = new System.Drawing.Size(186, 17); + this.cbTVPowerOnWithActivity.TabIndex = 52; + this.cbTVPowerOnWithActivity.Text = "global_tv_power_on_with_activity"; + this.cbTVPowerOnWithActivity.UseVisualStyleBackColor = true; + // // pictureBox3 // this.pictureBox3.BackgroundImage = global::LibCECTray.Properties.Resources.power; @@ -1064,6 +1077,7 @@ private void InitializeComponent() public System.Windows.Forms.Label lFirmware; public System.Windows.Forms.PictureBox pbAlert; private System.Windows.Forms.CheckBox cbTVAutoPowerOn; + private System.Windows.Forms.CheckBox cbTVPowerOnWithActivity; private System.Windows.Forms.Button bReloadConfig2; private System.Windows.Forms.CheckBox cbDetectAddress; } diff --git a/src/LibCecTray/ui/CECTray.cs b/src/LibCecTray/ui/CECTray.cs index 3ea3c37..00fb5ec 100644 --- a/src/LibCecTray/ui/CECTray.cs +++ b/src/LibCecTray/ui/CECTray.cs @@ -72,10 +72,22 @@ private void SystemIdle(object sender, IdleChange e) { if (e.Idle) { - Controller.CECActions.SendStandby(CecLogicalAddress.Broadcast); - } else + if (e.ShouldStandby) + { + Controller.CECActions.SendStandby(CecLogicalAddress.Broadcast); + } + } + else { - Controller.CECActions.ActivateSource(); + if (!Controller.TvIsOn && Controller.Settings.TVPowerOnWithActivity.Value) + { + Controller.CECActions.SendImageViewOn(GetTargetDevice()); + } + + if (SystemIdleMonitor.Instance.IdleTimeoutSeconds > 0) + { + Controller.CECActions.ActivateSource(); + } } } @@ -86,23 +98,32 @@ private void SystemActivity(object sender, IdleTimeChange e) private void SetIdleTime(int idleTimeSeconds, int idleTimeoutSeconds) { - if (pbIdleTime.InvokeRequired) + if (idleTimeSeconds > 0) { - SetIdleTimeCallback cb = SetIdleTime; - try + if (pbIdleTime.InvokeRequired) { - pbIdleTime.Invoke(cb, new object[] { idleTimeSeconds, idleTimeoutSeconds }); + SetIdleTimeCallback cb = SetIdleTime; + try + { + pbIdleTime.Invoke(cb, new object[] { idleTimeSeconds, idleTimeoutSeconds }); + } + catch { } } - catch { } - } - else - { - if (idleTimeSeconds >= idleTimeoutSeconds) - pbIdleTime.Value = 100; - else if (idleTimeSeconds <= 0) - pbIdleTime.Value = 0; else - pbIdleTime.Value = (idleTimeSeconds * 100) / idleTimeoutSeconds; + { + if (idleTimeSeconds >= idleTimeoutSeconds) + { + pbIdleTime.Value = 100; + } + else if (idleTimeSeconds <= 0) + { + pbIdleTime.Value = 0; + } + else + { + pbIdleTime.Value = (idleTimeSeconds * 100) / idleTimeoutSeconds; + } + } } } private delegate void SetIdleTimeCallback(int idleTimeSeconds, int idleTimeoutSeconds); @@ -234,6 +255,7 @@ public void InitialiseSettingsComponent(CECSettings settings) settings.StopTvStandby.ReplaceControls(this, powerTab.Controls, cbStopTvStandby); settings.StandbyScreen.ReplaceControls(this, powerTab.Controls, lStandbyScreen, cbStandbyScreen); settings.TVAutoPowerOn.ReplaceControls(this, powerTab.Controls, cbTVAutoPowerOn); + settings.TVPowerOnWithActivity.ReplaceControls(this, powerTab.Controls, cbTVPowerOnWithActivity); var idleTimeSetting = settings.StandbyScreen.AsSettingIdleTime; var cbIdleTime = (idleTimeSetting.ValueControl as ComboBox); @@ -250,7 +272,7 @@ private void BSaveClick(object sender, EventArgs e) { Controller.SaveSettings(); } - + private void BReloadConfigClick(object sender, EventArgs e) { Controller.ResetDefaultSettings();