diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..a3aceb6 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,31 @@ +# Change Log +All notable changes to this project will be documented in this file. + +## [Unreleased] +### Planned +- autostart opion in the app +- option to disable automatic frequency restore +- Windows Universal app + +## [0.4] - 2016-06-16 +### Added +- Restore frequency on startup + +## [0.3] - 2016-05-24 +### Removed +- Background frequency watcher. Driver access in a background task disabled because of incorrect data. + +## [0.2] - 2016-05-23 +### Added +- Save last set frequency in setting file. +- Show notification in system tray when frequency is set or error occured. + +## [0.1] - 2016-05-22 +### Added +- Windows tray app with basic functionality + +[Unreleased]: https://github.com/BALEHOK/PWM/compare/v0.4...exp +[0.4]: https://github.com/BALEHOK/PWM/compare/v0.1...v0.4 +[0.3]: https://github.com/BALEHOK/PWM/compare/v0.1...v0.3 +[0.2]: https://github.com/BALEHOK/PWM/compare/v0.1...v0.2 +[0.1]: https://github.com/BALEHOK/PWM/compare/init...v0.1 \ No newline at end of file diff --git a/PWM tool.zip b/PWM tool.zip new file mode 100644 index 0000000..68ea25e Binary files /dev/null and b/PWM tool.zip differ diff --git a/PWM.exe b/PWM.exe deleted file mode 100644 index ae6754b..0000000 Binary files a/PWM.exe and /dev/null differ diff --git a/PWM.sln b/PWM.sln index 48b4ab3..398a406 100644 --- a/PWM.sln +++ b/PWM.sln @@ -1,20 +1,36 @@  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 14 -VisualStudioVersion = 14.0.22823.1 +VisualStudioVersion = 14.0.25123.0 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PWM", "PWM\PWM.csproj", "{2F0EABF3-467D-4F47-9F90-8158AB3D64D2}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PwmLib", "PwmLib\PwmLib.csproj", "{B770C3D4-35DE-4C73-BB83-30B8F139B3FC}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Wpf", "Wpf\Wpf.csproj", "{CBCB0057-1FA5-43B2-A1DF-83D635EEDFF7}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU Debug|x64 = Debug|x64 + Release|Any CPU = Release|Any CPU Release|x64 = Release|x64 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {2F0EABF3-467D-4F47-9F90-8158AB3D64D2}.Debug|x64.ActiveCfg = Debug|x64 - {2F0EABF3-467D-4F47-9F90-8158AB3D64D2}.Debug|x64.Build.0 = Debug|x64 - {2F0EABF3-467D-4F47-9F90-8158AB3D64D2}.Release|x64.ActiveCfg = Release|x64 - {2F0EABF3-467D-4F47-9F90-8158AB3D64D2}.Release|x64.Build.0 = Release|x64 + {B770C3D4-35DE-4C73-BB83-30B8F139B3FC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B770C3D4-35DE-4C73-BB83-30B8F139B3FC}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B770C3D4-35DE-4C73-BB83-30B8F139B3FC}.Debug|x64.ActiveCfg = Debug|Any CPU + {B770C3D4-35DE-4C73-BB83-30B8F139B3FC}.Debug|x64.Build.0 = Debug|Any CPU + {B770C3D4-35DE-4C73-BB83-30B8F139B3FC}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B770C3D4-35DE-4C73-BB83-30B8F139B3FC}.Release|Any CPU.Build.0 = Release|Any CPU + {B770C3D4-35DE-4C73-BB83-30B8F139B3FC}.Release|x64.ActiveCfg = Release|Any CPU + {B770C3D4-35DE-4C73-BB83-30B8F139B3FC}.Release|x64.Build.0 = Release|Any CPU + {CBCB0057-1FA5-43B2-A1DF-83D635EEDFF7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {CBCB0057-1FA5-43B2-A1DF-83D635EEDFF7}.Debug|Any CPU.Build.0 = Debug|Any CPU + {CBCB0057-1FA5-43B2-A1DF-83D635EEDFF7}.Debug|x64.ActiveCfg = Debug|Any CPU + {CBCB0057-1FA5-43B2-A1DF-83D635EEDFF7}.Debug|x64.Build.0 = Debug|Any CPU + {CBCB0057-1FA5-43B2-A1DF-83D635EEDFF7}.Release|Any CPU.ActiveCfg = Release|Any CPU + {CBCB0057-1FA5-43B2-A1DF-83D635EEDFF7}.Release|Any CPU.Build.0 = Release|Any CPU + {CBCB0057-1FA5-43B2-A1DF-83D635EEDFF7}.Release|x64.ActiveCfg = Release|Any CPU + {CBCB0057-1FA5-43B2-A1DF-83D635EEDFF7}.Release|x64.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/PWM/PWM.Designer.cs b/PWM/PWM.Designer.cs deleted file mode 100644 index 7b25368..0000000 --- a/PWM/PWM.Designer.cs +++ /dev/null @@ -1,150 +0,0 @@ -namespace PWM -{ - partial class PWM - { - /// - /// Required designer variable. - /// - private System.ComponentModel.IContainer components = null; - - /// - /// Clean up any resources being used. - /// - /// true if managed resources should be disposed; otherwise, false. - protected override void Dispose(bool disposing) - { - if (disposing && (components != null)) - { - components.Dispose(); - } - base.Dispose(disposing); - } - - #region Windows Form Designer generated code - - /// - /// Required method for Designer support - do not modify - /// the contents of this method with the code editor. - /// - private void InitializeComponent() - { - this.flowLayoutPanel1 = new System.Windows.Forms.FlowLayoutPanel(); - this.lCurrent = new System.Windows.Forms.Label(); - this.vCurrent = new System.Windows.Forms.Label(); - this.lNew = new System.Windows.Forms.Label(); - this.tNew = new System.Windows.Forms.TextBox(); - this.bSet = new System.Windows.Forms.Button(); - this.lOne = new System.Windows.Forms.Label(); - this.vOne = new System.Windows.Forms.Label(); - this.flowLayoutPanel1.SuspendLayout(); - this.SuspendLayout(); - // - // flowLayoutPanel1 - // - this.flowLayoutPanel1.Controls.Add(this.lOne); - this.flowLayoutPanel1.Controls.Add(this.vOne); - this.flowLayoutPanel1.Controls.Add(this.lCurrent); - this.flowLayoutPanel1.Controls.Add(this.vCurrent); - this.flowLayoutPanel1.Controls.Add(this.lNew); - this.flowLayoutPanel1.Controls.Add(this.tNew); - this.flowLayoutPanel1.Controls.Add(this.bSet); - this.flowLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill; - this.flowLayoutPanel1.Location = new System.Drawing.Point(0, 0); - this.flowLayoutPanel1.Name = "flowLayoutPanel1"; - this.flowLayoutPanel1.Size = new System.Drawing.Size(254, 132); - this.flowLayoutPanel1.TabIndex = 0; - // - // lCurrent - // - this.lCurrent.AutoSize = true; - this.lCurrent.Location = new System.Drawing.Point(3, 25); - this.lCurrent.Name = "lCurrent"; - this.lCurrent.Size = new System.Drawing.Size(77, 25); - this.lCurrent.TabIndex = 0; - this.lCurrent.Text = "Current"; - // - // vCurrent - // - this.vCurrent.AutoSize = true; - this.flowLayoutPanel1.SetFlowBreak(this.vCurrent, true); - this.vCurrent.Location = new System.Drawing.Point(86, 25); - this.vCurrent.Name = "vCurrent"; - this.vCurrent.Size = new System.Drawing.Size(45, 25); - this.vCurrent.TabIndex = 1; - this.vCurrent.Text = "???"; - // - // lNew - // - this.lNew.AutoSize = true; - this.lNew.Location = new System.Drawing.Point(3, 50); - this.lNew.Name = "lNew"; - this.lNew.Size = new System.Drawing.Size(51, 25); - this.lNew.TabIndex = 2; - this.lNew.Text = "New"; - // - // tNew - // - this.flowLayoutPanel1.SetFlowBreak(this.tNew, true); - this.tNew.Location = new System.Drawing.Point(60, 53); - this.tNew.Name = "tNew"; - this.tNew.Size = new System.Drawing.Size(100, 29); - this.tNew.TabIndex = 3; - // - // bSet - // - this.bSet.Location = new System.Drawing.Point(3, 88); - this.bSet.Name = "bSet"; - this.bSet.Size = new System.Drawing.Size(102, 38); - this.bSet.TabIndex = 4; - this.bSet.Text = "Set"; - this.bSet.UseVisualStyleBackColor = true; - this.bSet.Click += new System.EventHandler(this.bSet_Click); - // - // lOne - // - this.lOne.AutoSize = true; - this.lOne.Location = new System.Drawing.Point(3, 0); - this.lOne.Name = "lOne"; - this.lOne.Size = new System.Drawing.Size(79, 25); - this.lOne.TabIndex = 5; - this.lOne.Text = "Value 1"; - // - // vOne - // - this.vOne.AutoSize = true; - this.flowLayoutPanel1.SetFlowBreak(this.vOne, true); - this.vOne.Location = new System.Drawing.Point(88, 0); - this.vOne.Name = "vOne"; - this.vOne.Size = new System.Drawing.Size(45, 25); - this.vOne.TabIndex = 6; - this.vOne.Text = "???"; - // - // PWM - // - this.AutoScaleDimensions = new System.Drawing.SizeF(11F, 24F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(254, 132); - this.Controls.Add(this.flowLayoutPanel1); - this.MaximizeBox = false; - this.MinimizeBox = false; - this.Name = "PWM"; - this.Text = "PWM"; - this.flowLayoutPanel1.ResumeLayout(false); - this.flowLayoutPanel1.PerformLayout(); - this.ResumeLayout(false); - - } - - #endregion - - private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel1; - private System.Windows.Forms.Label lCurrent; - private System.Windows.Forms.Label vCurrent; - private System.Windows.Forms.Label lNew; - private System.Windows.Forms.TextBox tNew; - private System.Windows.Forms.Button bSet; - private System.Windows.Forms.Label lOne; - private System.Windows.Forms.Label vOne; - } -} - diff --git a/PWM/PWM.cs b/PWM/PWM.cs deleted file mode 100644 index 413a008..0000000 --- a/PWM/PWM.cs +++ /dev/null @@ -1,56 +0,0 @@ -using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.Data; -using System.Drawing; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using System.Windows.Forms; -using igfxDHLib; -using System.Runtime.Remoting.Metadata.W3cXsd2001; - -namespace PWM -{ - public partial class PWM : Form - { - private byte[] baseData; - private DataHandler dh; - - public PWM() - { - InitializeComponent(); - dh = new igfxDHLib.DataHandler(); - RefreshV(); - } - void RefreshV() - { - uint error = 0; - baseData = new byte[8]; - dh.GetDataFromDriver(ESCAPEDATATYPE_ENUM.GET_SET_PWM_FREQUENCY, 4, ref error, ref baseData[0]); - if (error != 0) - MessageBox.Show(string.Format("failed to get PWM: {0:X}", error)); - vCurrent.Text = string.Format("{0}", BitConverter.ToInt32(baseData, 4)); - vOne.Text = string.Format("{0}", BitConverter.ToInt32(baseData, 0)); - } - - private void bSet_Click(object sender, EventArgs e) - { - int v; - if(!int.TryParse(tNew.Text, out v) || v < 200) - { - MessageBox.Show("Invalid value < 200"); - return; - } - byte[] b = BitConverter.GetBytes(v); - Array.Copy(b, 0, baseData, 4, 4); - - uint error = 0; - dh.SendDataToDriver(ESCAPEDATATYPE_ENUM.GET_SET_PWM_FREQUENCY, 4, ref error, ref baseData[0]); - if (error != 0) - MessageBox.Show(string.Format("failed set get PWM: {0:X}", error)); - - RefreshV(); - } - } -} diff --git a/PWM/PWM.csproj b/PWM/PWM.csproj deleted file mode 100644 index 240dd15..0000000 --- a/PWM/PWM.csproj +++ /dev/null @@ -1,134 +0,0 @@ - - - - - Debug - AnyCPU - {2F0EABF3-467D-4F47-9F90-8158AB3D64D2} - WinExe - Properties - PWM - PWM - v4.0 - 512 - true - - - - AnyCPU - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - AnyCPU - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - true - bin\x64\Debug\ - DEBUG;TRACE - full - x64 - prompt - MinimumRecommendedRules.ruleset - true - - - bin\x64\Release\ - TRACE - true - pdbonly - x64 - prompt - MinimumRecommendedRules.ruleset - true - - - true - bin\x86\Debug\ - DEBUG;TRACE - full - x86 - prompt - MinimumRecommendedRules.ruleset - - - bin\x86\Release\ - TRACE - true - pdbonly - x86 - prompt - MinimumRecommendedRules.ruleset - - - - .\igfxDHLibv2_0.dll - True - - - - - - - - - - - - - - - - Form - - - PWM.cs - - - - - PWM.cs - - - ResXFileCodeGenerator - Resources.Designer.cs - Designer - - - True - Resources.resx - True - - - SettingsSingleFileGenerator - Settings.Designer.cs - - - True - Settings.settings - True - - - - - - - - \ No newline at end of file diff --git a/PWM/PWM.resx b/PWM/PWM.resx deleted file mode 100644 index 1af7de1..0000000 --- a/PWM/PWM.resx +++ /dev/null @@ -1,120 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - \ No newline at end of file diff --git a/PWM/Program.cs b/PWM/Program.cs deleted file mode 100644 index 9ae0251..0000000 --- a/PWM/Program.cs +++ /dev/null @@ -1,22 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; -using System.Windows.Forms; - -namespace PWM -{ - static class Program - { - /// - /// The main entry point for the application. - /// - [STAThread] - static void Main() - { - Application.EnableVisualStyles(); - Application.SetCompatibleTextRenderingDefault(false); - Application.Run(new PWM()); - } - } -} diff --git a/PWM/Properties/Settings.settings b/PWM/Properties/Settings.settings deleted file mode 100644 index 3964565..0000000 --- a/PWM/Properties/Settings.settings +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/PwmLib/PWM.cs b/PwmLib/PWM.cs new file mode 100644 index 0000000..5761f8e --- /dev/null +++ b/PwmLib/PWM.cs @@ -0,0 +1,69 @@ +using igfxDHLib; +using System; + +namespace PwmLib +{ + internal class PWM + { + private DataHandler _dh = new DataHandler(); + private byte[] _someData; + + public uint GetFrequency(ref int something, ref int frequency) + { + var data = new byte[8]; + uint error = 0U; + _dh.GetDataFromDriver(ESCAPEDATATYPE_ENUM.GET_SET_PWM_FREQUENCY, 8, ref error, ref data[0]); + if (error != 0) + { + return error; + } + + something = BitConverter.ToInt32(data, 0); + frequency = BitConverter.ToInt32(data, 4); + + return 0; + } + + public uint SetFrequency(int frequency) + { + EnsureBaseDataInitialized(); + + var data = new byte[8]; + + Array.Copy(_someData, 0, data, 0, 4); + + byte[] b = BitConverter.GetBytes(frequency); + Array.Copy(b, 0, data, 4, 4); + + uint error = 0U; + _dh.SendDataToDriver(ESCAPEDATATYPE_ENUM.GET_SET_PWM_FREQUENCY, 8, ref error, ref data[0]); + + return error; + } + + /// + /// we need to know first DWORD parameter of driver register before we write new frequency + /// so if are going to update PWM freq we need to query the current settings first + /// the first call to GetFrequency method will init _baseData + /// + private void EnsureBaseDataInitialized() + { + if (_someData != null) + { + return; + } + + var data = new byte[8]; + uint error = 0U; + _dh.GetDataFromDriver(ESCAPEDATATYPE_ENUM.GET_SET_PWM_FREQUENCY, 4, ref error, ref data[0]); + + if (error != 0) + { + throw new Exception($"Failed to read data from driver. Error code {error}"); + } + + _someData = new byte[4]; + Array.Copy(data, 0, _someData, 0, 4); + } + } +} diff --git a/PWM/Properties/AssemblyInfo.cs b/PwmLib/Properties/AssemblyInfo.cs similarity index 86% rename from PWM/Properties/AssemblyInfo.cs rename to PwmLib/Properties/AssemblyInfo.cs index ac417b3..6fcd2a1 100644 --- a/PWM/Properties/AssemblyInfo.cs +++ b/PwmLib/Properties/AssemblyInfo.cs @@ -5,12 +5,12 @@ // General Information about an assembly is controlled through the following // set of attributes. Change these attribute values to modify the information // associated with an assembly. -[assembly: AssemblyTitle("PWM")] +[assembly: AssemblyTitle("PwmLib")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("PWM")] -[assembly: AssemblyCopyright("Copyright © 2015")] +[assembly: AssemblyProduct("PwmLib")] +[assembly: AssemblyCopyright("Copyright © 2016")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] @@ -20,7 +20,7 @@ [assembly: ComVisible(false)] // The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("2f0eabf3-467d-4f47-9f90-8158ab3d64d2")] +[assembly: Guid("b770c3d4-35de-4c73-bb83-30b8f139b3fc")] // Version information for an assembly consists of the following four values: // diff --git a/PWM/Properties/Settings.Designer.cs b/PwmLib/Properties/Settings.Designer.cs similarity index 67% rename from PWM/Properties/Settings.Designer.cs rename to PwmLib/Properties/Settings.Designer.cs index e50b58c..8fabc16 100644 --- a/PWM/Properties/Settings.Designer.cs +++ b/PwmLib/Properties/Settings.Designer.cs @@ -1,14 +1,14 @@ //------------------------------------------------------------------------------ // // This code was generated by a tool. -// Runtime Version:4.0.30319.0 +// Runtime Version:4.0.30319.42000 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. // //------------------------------------------------------------------------------ -namespace PWM.Properties { +namespace PwmLib.Properties { [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] @@ -22,5 +22,17 @@ public static Settings Default { return defaultInstance; } } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("-1")] + public int Freq { + get { + return ((int)(this["Freq"])); + } + set { + this["Freq"] = value; + } + } } } diff --git a/PwmLib/Properties/Settings.settings b/PwmLib/Properties/Settings.settings new file mode 100644 index 0000000..6689aa7 --- /dev/null +++ b/PwmLib/Properties/Settings.settings @@ -0,0 +1,9 @@ + + + + + + -1 + + + \ No newline at end of file diff --git a/PwmLib/PwmLib.csproj b/PwmLib/PwmLib.csproj new file mode 100644 index 0000000..f0d8d55 --- /dev/null +++ b/PwmLib/PwmLib.csproj @@ -0,0 +1,72 @@ + + + + + Debug + AnyCPU + {B770C3D4-35DE-4C73-BB83-30B8F139B3FC} + Library + Properties + PwmLib + PwmLib + v4.5.2 + 512 + + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + x64 + false + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + false + x64 + + + + ..\lib\igfxDHLibv2_0.dll + True + + + + + + + + True + True + Settings.settings + + + + + + + + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + + + \ No newline at end of file diff --git a/PwmLib/PwmManager.cs b/PwmLib/PwmManager.cs new file mode 100644 index 0000000..0bab62d --- /dev/null +++ b/PwmLib/PwmManager.cs @@ -0,0 +1,132 @@ +using System.Threading.Tasks; + +namespace PwmLib +{ + public class PwmManager + { + public delegate void PwmEventHandler(int frequency, string message); + public event PwmEventHandler OnFrequencySet; + public event PwmEventHandler OnError; + + private PWM _pwm = new PWM(); + private SettingStore _settings = new SettingStore(); + + private bool _freqWatch; + + public bool FreqWatch + { + get + { + return _freqWatch; + } + private set + { + _freqWatch = value; + } + } + + public int LastFrequency { get { return _settings.LastFreq; } } + + public PwmManager() + { + OnFrequencySet += (f, s) => { }; + OnError += (f, s) => { }; + } + + /// + /// Get current PWM frequency from video card driver + /// + /// Current frequency + public string GetFrequencyString() + { + int a = 0, currentFreq = 0; + if (_pwm.GetFrequency(ref a, ref currentFreq) == 0) + { + return currentFreq.ToString(); + } + else + { + return "driver error"; + } + } + + /// + /// Get current PWM frequency from video card driver + /// + /// Current frequency (-1 in case of error) + public int GetFrequency() + { + int a = 0, currentFreq = 0; + var result = _pwm.GetFrequency(ref a, ref currentFreq); + if (result == 0) + { + return currentFreq; + } + else + { + OnError(currentFreq, $"Failed to get frequency. Error code {result}"); + return -1; + } + } + + /// + /// Set PWM frequence + /// + /// Error code (0 if success) + public uint SetFrequency(int frequency) + { + // I've read people set values like 700 or 1200. + // I've never heard about frequencies less than 100Hz nad higher than 100kHz. + // However, feel free to change this restriction at your own risk + // Actually, I am in no way responsible for any damage of your device cause by this app, sorry :) + if (frequency < 100 || frequency > 100000) + { + OnError(frequency, $"Frequency {frequency} is not allowed. Frequency should be >= 200 and <= 2000."); + return 100500; + } + + var result = _pwm.SetFrequency(frequency); + if (result == 0) + { + _settings.LastFreq = frequency; + + OnFrequencySet(frequency, null); + } + else + { + OnError(frequency, $"Failed to set frequency. Error code {result}"); + } + + return result; + } + + /// + /// Checks the frequency periodically and sets it back to the desired value. + /// Not thread save. + /// + /// Frequency check interval + public void LookAfterFreq(int delay = 5000) + { + FreqWatch = true; + Task.Delay(delay).ContinueWith(t => + { + var f = GetFrequency(); + + // чот сломалось + if (f == -1) + { + FreqWatch = false; + return; + } + + var _lastFreq = _settings.LastFreq; + if (_lastFreq != -1 && f != _lastFreq) + { + SetFrequency(_lastFreq); + } + + LookAfterFreq(); + }); + } + } +} diff --git a/PwmLib/SettingStore.cs b/PwmLib/SettingStore.cs new file mode 100644 index 0000000..a03f498 --- /dev/null +++ b/PwmLib/SettingStore.cs @@ -0,0 +1,26 @@ +namespace PwmLib +{ + public class SettingStore + { + private int _lastFreq = -1; + public int LastFreq + { + get + { + if (_lastFreq != -1) + { + return _lastFreq; + } + + return _lastFreq = Properties.Settings.Default.Freq; + } + + set + { + Properties.Settings.Default.Freq = value; + Properties.Settings.Default.Save(); + _lastFreq = value; + } + } + } +} diff --git a/PwmLib/app.config b/PwmLib/app.config new file mode 100644 index 0000000..4e882aa --- /dev/null +++ b/PwmLib/app.config @@ -0,0 +1,15 @@ + + + + +
+ + + + + + -1 + + + + \ No newline at end of file diff --git a/README.md b/README.md index a95042e..9322ad5 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,17 @@ # WARNING: USE AT YOUR OWN RISK -Adjusting the value from the default may affect the lifetime of the lamp in your screen. You might end up looking into the abyss. You have been WARNED! +Adjusting the value from the default may affect the lifetime of the lamp in your screen. You might end up looking into the abyss. The authors are not responsible for any direct or indirect damages caused by this program. -# PWM -This is a utility to allow for adjust the PWM driver frequency delivered from Intel Graphics embedded GPU to the embedded LCD panel. It shows you the existing value and lets you pick a new one. +You have been WARNED! + +# Tool +This is a utility allowing to adjust the PWM driver frequency delivered from Intel Graphics embedded GPU to the embedded LCD panel. It shows you the existing value and lets you pick a new one. It also checks that the value you set is not overridden and restores the chosen PWM frequency if required. + +Tested under the following conditions: +Intel(R) HD Graphics 4600 +Driver Version: 20.19.15.4424 +Operating System: Windows* 10 Pro (10.0.10586) +# PWM It was inspired by this https://wiki.archlinux.org/index.php/Backlight#Backlight_PWM_modulation_frequency_.28Intel_i915_only.29 and this @@ -12,5 +20,9 @@ But its for Windows x64 instead. I think the value it reads back and writes is the frequency in Hz. The actual output was not checked via high speed camera or anything like that, but it seems to have the same behavior as sending those intel_reg_write commands from linux with the computed values. The driver actually has two configuration DWORDs, the default for me for these two values in decimal is 2 and 200. This utility just keeps the first value as read back from the driver and changes only the second value. It's possible the first value is duty cycle or mode related, or something completely different. You could experiment using the source code if you aren't afraid to explode. -# LICENSE -Public domain +# Credits +App icon made by [Freepik](http://www.freepik.com) from [www.flaticon.com](http://www.flaticon.com) is licensed by [CC 3.0 BY](http://creativecommons.org/licenses/by/3.0/) + + +# License +Public domain \ No newline at end of file diff --git a/PWM/App.config b/Wpf/App.config similarity index 59% rename from PWM/App.config rename to Wpf/App.config index 74ade9d..88fa402 100644 --- a/PWM/App.config +++ b/Wpf/App.config @@ -1,6 +1,6 @@ - + - + - + \ No newline at end of file diff --git a/Wpf/App.xaml b/Wpf/App.xaml new file mode 100644 index 0000000..af83ec3 --- /dev/null +++ b/Wpf/App.xaml @@ -0,0 +1,9 @@ + + + + + diff --git a/Wpf/App.xaml.cs b/Wpf/App.xaml.cs new file mode 100644 index 0000000..2a80938 --- /dev/null +++ b/Wpf/App.xaml.cs @@ -0,0 +1,135 @@ +using System.Windows; +using System; +using System.ComponentModel; +using NotifyIcon = System.Windows.Forms.NotifyIcon; +using PwmLib; + +namespace Wpf +{ + /// + /// Interaction logic for App.xaml + /// + public partial class App : Application + { + private Container _components; + private NotifyIcon _notifyIcon; + private PwmManager _pwm; + + private MainWindow _mainWindow; + + protected override void OnStartup(StartupEventArgs e) + { + base.OnStartup(e); + + _components = new Container(); + _notifyIcon = new NotifyIcon(_components) + { + ContextMenuStrip = new System.Windows.Forms.ContextMenuStrip(), + Icon = Wpf.Properties.Resources.tray, + Text = "PWM frequency manager", + Visible = true + }; + + AddMenuItems(_notifyIcon.ContextMenuStrip.Items); + + _notifyIcon.ContextMenuStrip.Opening += ContextMenuStrip_Opening; + + // ToDo fix position + // _notifyIcon.Click += (a, b) => _notifyIcon.ContextMenuStrip.Show(); + + _pwm = new PwmManager(); + + _pwm.OnFrequencySet += + (f, s) => _notifyIcon.ShowBalloonTip( + 1000, + "PWM Tool", + $"PWM frequency set to {f}", + System.Windows.Forms.ToolTipIcon.Info); + + _pwm.OnError += (f, s) => _notifyIcon.ShowBalloonTip( + 1000, + "PWM Tool", + s, + System.Windows.Forms.ToolTipIcon.Error); + + // by some reason _pwm.SetFrequency doesn't work if called from a background thread + // _pwm.LookAfterFreq(); + CheckLastFrequency(); + } + + private void CheckLastFrequency() + { + var lastFreq = _pwm.LastFrequency; + if (lastFreq != -1) + { + var restorFreqWindow = new RestoreFreqWindow(_pwm); + if (restorFreqWindow.IsLoaded) + { + restorFreqWindow.Show(); + } + } + } + + protected override void OnExit(ExitEventArgs e) + { + if (_notifyIcon != null) + { + _notifyIcon.Dispose(); + } + + if (_components != null) + { + _components.Dispose(); + } + + base.OnExit(e); + + } + + private System.Windows.Forms.ToolStripLabel _currentFreqLabel; + private System.Windows.Forms.ToolStripLabel _freqWatchStatus; + private void AddMenuItems(System.Windows.Forms.ToolStripItemCollection items) + { + _currentFreqLabel = new System.Windows.Forms.ToolStripLabel("???"); + items.Add(_currentFreqLabel); + + _freqWatchStatus = new System.Windows.Forms.ToolStripLabel("???"); + items.Add(_freqWatchStatus); + + items.Add(new System.Windows.Forms.ToolStripSeparator()); + + items.Add(new System.Windows.Forms.ToolStripMenuItem("Set PWM frequency", null, setFreq_Click)); + + items.Add(new System.Windows.Forms.ToolStripSeparator()); + + items.Add(new System.Windows.Forms.ToolStripMenuItem("Exit", null, onExit_Clicked)); + } + + private void ContextMenuStrip_Opening(object sender, CancelEventArgs e) + { + e.Cancel = false; + + _currentFreqLabel.Text = $"Current: {_pwm.GetFrequencyString()} Hz"; + + _freqWatchStatus.Text = $"Watching: {(_pwm.FreqWatch ? "enabled" : "disabled")}"; + } + + private void onExit_Clicked(object sender, EventArgs e) + { + Shutdown(); + } + + private void setFreq_Click(object sender, EventArgs e) + { + if (_mainWindow == null || !_mainWindow.IsLoaded) + { + _mainWindow = new MainWindow(_pwm); + + // carefull! we are modifying a var from different threads without synchronization + _mainWindow.Closing += (s, args) => _mainWindow = null; + } + + _mainWindow.Show(); + } + } +} diff --git a/Wpf/MainWindow.xaml b/Wpf/MainWindow.xaml new file mode 100644 index 0000000..300b84c --- /dev/null +++ b/Wpf/MainWindow.xaml @@ -0,0 +1,18 @@ + + +