Expose OSD and Fan settings in PowerControl

This commit is contained in:
Kamil Trzciński 2022-11-16 00:33:23 +01:00
parent 44f25db836
commit 5f940c0ee4
5 changed files with 285 additions and 3 deletions

View file

@ -21,4 +21,23 @@ namespace CommonHelpers
Detail,
Full
}
public enum OverlayEnabled : uint
{
Yes = 378313,
No
}
[StructLayout(LayoutKind.Sequential)]
public struct FanModeSetting
{
public FanMode Current, Desired;
}
[StructLayout(LayoutKind.Sequential)]
public struct OverlayModeSetting
{
public OverlayMode Current, Desired;
public OverlayEnabled CurrentEnabled, DesiredEnabled;
}
}

145
CommonHelpers/SharedData.cs Normal file
View file

@ -0,0 +1,145 @@
using System;
using System.Collections.Generic;
using System.IO.MemoryMappedFiles;
using System.Linq;
using System.Runtime.InteropServices;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using System.Threading.Tasks;
namespace CommonHelpers
{
public class SharedData<T> : IDisposable where T : unmanaged
{
const int MMF_MAX_SIZE = 256;
private MemoryMappedFile mmf;
private SharedData()
{ }
public T NewValue()
{
return default(T);
}
public bool GetValue(out T value)
{
using (MemoryMappedViewStream mmvStream = mmf.CreateViewStream())
{
value = default(T);
if (!mmvStream.CanRead)
return false;
byte[] buffer = new byte[MMF_MAX_SIZE];
mmvStream.Read(buffer, 0, buffer.Length);
var handle = GCHandle.Alloc(buffer, GCHandleType.Pinned);
try
{
var output = Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(T));
if (output is null)
return false;
value = (T)output;
return true;
}
catch
{
return false;
}
finally
{
handle.Free();
}
}
}
public bool SetValue(T value)
{
using (MemoryMappedViewStream mmvStream = mmf.CreateViewStream())
{
if (!mmvStream.CanWrite)
return false;
byte[] buffer = new byte[MMF_MAX_SIZE];
var handle = GCHandle.Alloc(buffer, GCHandleType.Pinned);
try
{
Marshal.StructureToPtr(value, handle.AddrOfPinnedObject(), false);
}
catch
{
return false;
}
finally
{
handle.Free();
}
mmvStream.Write(buffer, 0, buffer.Length);
return true;
}
}
public static bool GetExistingValue(out T value)
{
try
{
using (var shared = OpenExisting())
{
if (shared.GetValue(out value))
return true;
}
}
catch
{
value = default(T);
}
return false;
}
public static bool SetExistingValue(T value)
{
try
{
using (var shared = OpenExisting())
{
if (shared.SetValue(value))
return true;
}
}
catch
{
}
return false;
}
public void Dispose()
{
mmf.Dispose();
}
public static String GetUniqueName()
{
return String.Format("Global_{0}_Setting", typeof(T).Name);
}
public static SharedData<T> CreateNew(String? name = null)
{
return new SharedData<T>()
{
mmf = MemoryMappedFile.CreateOrOpen(name ?? GetUniqueName(), MMF_MAX_SIZE)
};
}
public static SharedData<T> OpenExisting(String? name = null)
{
return new SharedData<T>()
{
mmf = MemoryMappedFile.OpenExisting(name ?? GetUniqueName())
};
}
}
}

View file

@ -1,4 +1,4 @@
using CommonHelpers;
using CommonHelpers;
using CommonHelpers.FromLibreHardwareMonitor;
using FanControl.Properties;
using System;
@ -24,6 +24,8 @@ namespace FanControl
"Starts Steam Deck Fan Control on Windows startup."
);
private SharedData<FanModeSetting> sharedData = SharedData<FanModeSetting>.CreateNew();
public FanControlForm()
{
InitializeComponent();
@ -122,8 +124,19 @@ namespace FanControl
fanControl.SetMode(FanMode.Default);
}
private void SharedData_Update()
{
if (sharedData.GetValue(out var value) && Enum.IsDefined<FanMode>(value.Desired))
{
setFanMode((FanMode)value.Desired);
}
sharedData.SetValue(new FanModeSetting() { Current = fanControl.Mode });
}
private void fanLoopTimer_Tick(object sender, EventArgs e)
{
SharedData_Update();
fanControl.Update();
}

View file

@ -1,4 +1,4 @@
using CommonHelpers;
using CommonHelpers;
using CommonHelpers.FromLibreHardwareMonitor;
using Microsoft.VisualBasic.Logging;
using PerformanceOverlay.External;
@ -32,6 +32,8 @@ namespace PerformanceOverlay
"Starts Performance Overlay on Windows startup."
);
SharedData<OverlayModeSetting> sharedData = SharedData<OverlayModeSetting>.CreateNew();
public Controller()
{
contextMenu = new System.Windows.Forms.ContextMenuStrip(components);
@ -142,8 +144,37 @@ namespace PerformanceOverlay
updateContextItems(contextMenu);
}
private void SharedData_Update()
{
if (sharedData.GetValue(out var value))
{
if (Enum.IsDefined<OverlayMode>(value.Desired))
{
Settings.Default.OSDModeParsed = (OverlayMode)value.Desired;
Settings.Default.ShowOSD = true;
Settings.Default.Save();
updateContextItems(contextMenu);
}
if (Enum.IsDefined<OverlayEnabled>(value.DesiredEnabled))
{
Settings.Default.ShowOSD = (OverlayEnabled)value.DesiredEnabled == OverlayEnabled.Yes;
Settings.Default.Save();
updateContextItems(contextMenu);
}
}
sharedData.SetValue(new OverlayModeSetting()
{
Current = Settings.Default.OSDModeParsed,
CurrentEnabled = Settings.Default.ShowOSD ? OverlayEnabled.Yes : OverlayEnabled.No
});
}
private void OsdTimer_Tick(object? sender, EventArgs e)
{
SharedData_Update();
try
{
notifyIcon.Text = TitleWithVersion + ". RTSS Version: " + OSD.Version;

View file

@ -1,4 +1,5 @@
using System;
using CommonHelpers;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
@ -101,6 +102,79 @@ namespace PowerControl
Options = { "Auto", 200, 300, 400, 500, 600, 700, 800, 900, 1000, 1100, 1200, 1300, 1400, 1500, 1600 },
ApplyDelay = 1000,
Visible = false
},
new Menu.MenuItemSeparator(),
new Menu.MenuItemWithOptions()
{
Name = "OSD",
ApplyDelay = 500,
OptionsValues = delegate()
{
return Enum.GetValues<OverlayEnabled>().Select(item => (object)item).ToArray();
},
CurrentValue = delegate()
{
if (SharedData<OverlayModeSetting>.GetExistingValue(out var value))
return value.CurrentEnabled;
return null;
},
ApplyValue = delegate(object selected)
{
if (!SharedData<OverlayModeSetting>.GetExistingValue(out var value))
return null;
value.DesiredEnabled = (OverlayEnabled)selected;
if (!SharedData<OverlayModeSetting>.SetExistingValue(value))
return null;
return selected;
}
},
new Menu.MenuItemWithOptions()
{
Name = "OSD Mode",
ApplyDelay = 500,
OptionsValues = delegate()
{
return Enum.GetValues<OverlayMode>().Select(item => (object)item).ToArray();
},
CurrentValue = delegate()
{
if (SharedData<OverlayModeSetting>.GetExistingValue(out var value))
return value.Current;
return null;
},
ApplyValue = delegate(object selected)
{
if (!SharedData<OverlayModeSetting>.GetExistingValue(out var value))
return null;
value.Desired = (OverlayMode)selected;
if (!SharedData<OverlayModeSetting>.SetExistingValue(value))
return null;
return selected;
}
},
new Menu.MenuItemWithOptions()
{
Name = "FAN",
ApplyDelay = 500,
OptionsValues = delegate()
{
return Enum.GetValues<FanMode>().Select(item => (object)item).ToArray();
},
CurrentValue = delegate()
{
if (SharedData<FanModeSetting>.GetExistingValue(out var value))
return value.Current;
return null;
},
ApplyValue = delegate(object selected)
{
if (!SharedData<FanModeSetting>.GetExistingValue(out var value))
return null;
value.Desired = (FanMode)selected;
if (!SharedData<FanModeSetting>.SetExistingValue(value))
return null;
return selected;
}
}
}
};