mirror of
https://github.com/jkocon/g-helper.git
synced 2026-02-23 13:00:52 +01:00
Compare commits
143 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bb5aeba9e7 | ||
|
|
2d4e794084 | ||
|
|
5f1c926527 | ||
|
|
dc40b317f8 | ||
|
|
db595d54f6 | ||
|
|
2c317d9a18 | ||
|
|
1e26696eb6 | ||
|
|
feff220a9b | ||
|
|
a05c47a05c | ||
|
|
5b08bfbe92 | ||
|
|
606f43380b | ||
|
|
657e09adb0 | ||
|
|
188c566097 | ||
|
|
828a1cd13c | ||
|
|
c69d3b7c1c | ||
|
|
767865ab19 | ||
|
|
ec7350cf5c | ||
|
|
d33813b50d | ||
|
|
d803b1eede | ||
|
|
81b73517df | ||
|
|
dbbf8b4016 | ||
|
|
c4adb1eb8b | ||
|
|
dea2b73d7f | ||
|
|
3fb61d3bf1 | ||
|
|
b83d8d35a4 | ||
|
|
8a3708e850 | ||
|
|
0e728ccc64 | ||
|
|
1a12162ba1 | ||
|
|
5b5cd0e97a | ||
|
|
1167d6c380 | ||
|
|
d0d44c3ef1 | ||
|
|
164d417b06 | ||
|
|
e1acea9ad9 | ||
|
|
083b74e739 | ||
|
|
1413fce8f1 | ||
|
|
666dea9bfd | ||
|
|
41bccc3a56 | ||
|
|
976ca50e50 | ||
|
|
81b6a6d61c | ||
|
|
7f6bdda39a | ||
|
|
96dc22072a | ||
|
|
3c02d5cd95 | ||
|
|
e58a396cbd | ||
|
|
ba9a290ad0 | ||
|
|
40ecdf0d35 | ||
|
|
f31b05dcd1 | ||
|
|
d778838ad4 | ||
|
|
b177dacf8b | ||
|
|
6e9cc51a5f | ||
|
|
58fd6650db | ||
|
|
e2a6b770a0 | ||
|
|
055e83e976 | ||
|
|
40be93b60d | ||
|
|
2c2eed4fe2 | ||
|
|
8d6b277fda | ||
|
|
d3de136dd3 | ||
|
|
8e6f54e833 | ||
|
|
0b030da41b | ||
|
|
4d0bc74179 | ||
|
|
05aae069b4 | ||
|
|
28e949bee4 | ||
|
|
9a82a54b04 | ||
|
|
8aff60546a | ||
|
|
d5039207ec | ||
|
|
66316d3016 | ||
|
|
f940d343c3 | ||
|
|
1848612434 | ||
|
|
fe253de0e1 | ||
|
|
7211fd5f22 | ||
|
|
c1a8eb12f9 | ||
|
|
0477d03ecc | ||
|
|
e923d82732 | ||
|
|
6558d66e8d | ||
|
|
ec8605dfe6 | ||
|
|
ac462b628f | ||
|
|
1cd9c30c4a | ||
|
|
c575b17aba | ||
|
|
d2e0e6f51e | ||
|
|
0dae1c9115 | ||
|
|
16e085d9f1 | ||
|
|
6b04ffa172 | ||
|
|
15e4310016 | ||
|
|
3abe924525 | ||
|
|
691f187b7d | ||
|
|
8e4c0dada7 | ||
|
|
f535818fb0 | ||
|
|
ce75d2c778 | ||
|
|
c755213472 | ||
|
|
60e8712131 | ||
|
|
2c817b46ef | ||
|
|
e16f612311 | ||
|
|
4ce4b4bbf7 | ||
|
|
f9303ced8a | ||
|
|
f000a03395 | ||
|
|
90205e9231 | ||
|
|
e65270c961 | ||
|
|
306dfe2bd7 | ||
|
|
ca7dfff357 | ||
|
|
59288b9422 | ||
|
|
46ff8deb44 | ||
|
|
e6e8877531 | ||
|
|
b13306b989 | ||
|
|
838dc039ac | ||
|
|
0702f95e0c | ||
|
|
f42fcf2f73 | ||
|
|
6a7e1ddaa3 | ||
|
|
57ffcb8c7f | ||
|
|
5425bd0128 | ||
|
|
328cd8f9f1 | ||
|
|
38739ca8f6 | ||
|
|
a3e235e886 | ||
|
|
678f4b0eb7 | ||
|
|
4bbfbd0382 | ||
|
|
4c8291c74b | ||
|
|
e9060ad8c0 | ||
|
|
f26585e73c | ||
|
|
9f7da4c20a | ||
|
|
eff45c1485 | ||
|
|
be6e5e8f23 | ||
|
|
17083eef21 | ||
|
|
d5b098335b | ||
|
|
acb2efdd00 | ||
|
|
92fa210898 | ||
|
|
6dd4e07efe | ||
|
|
ae6972db76 | ||
|
|
b3f7b1027f | ||
|
|
8929daa604 | ||
|
|
eb522214f0 | ||
|
|
1222377c33 | ||
|
|
933f07d666 | ||
|
|
8f95f6a1bb | ||
|
|
f2c32b2e9a | ||
|
|
ddb591b79a | ||
|
|
65b4192393 | ||
|
|
846cc6e867 | ||
|
|
ddac5a23be | ||
|
|
4f6db4ae0a | ||
|
|
14dd96dee3 | ||
|
|
79ff24bbb7 | ||
|
|
b715bd0391 | ||
|
|
b97a06eb56 | ||
|
|
e69845e858 | ||
|
|
b832ba6e8b |
4
.github/SECURITY.md
vendored
4
.github/SECURITY.md
vendored
@@ -4,8 +4,8 @@
|
||||
|
||||
| Version | Supported |
|
||||
| ------- | ------------------ |
|
||||
| 0.25+ | :white_check_mark: |
|
||||
| < 0.24 | :x: |
|
||||
| 0.89+ | :white_check_mark: |
|
||||
| < 0.89 | :x: |
|
||||
|
||||
## Reporting a Vulnerability
|
||||
|
||||
|
||||
4
.github/workflows/release.yml
vendored
4
.github/workflows/release.yml
vendored
@@ -20,9 +20,9 @@ jobs:
|
||||
- name: Publish
|
||||
run: |
|
||||
dotnet publish app/GHelper.sln --configuration Release --runtime win-x64 -p:PublishSingleFile=true --no-self-contained
|
||||
powershell Compress-Archive app/bin/x64/Release/net7.0-windows8.0/win-x64/publish/GHelper.exe GHelper.zip
|
||||
powershell Compress-Archive app/bin/x64/Release/net7.0-windows8.0/win-x64/publish/* GHelper.zip
|
||||
- name: Upload
|
||||
env:
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
run: |
|
||||
gh release upload ${{ github.ref_name }} app/bin/x64/Release/net7.0-windows8.0/win-x64/publish/GHelper.exe GHelper.zip
|
||||
gh release upload ${{ github.ref_name }} GHelper.zip
|
||||
|
||||
@@ -8,21 +8,26 @@ using System.Timers;
|
||||
namespace GHelper.AnimeMatrix
|
||||
{
|
||||
|
||||
public class AniMatrix
|
||||
public class AniMatrixControl
|
||||
{
|
||||
System.Timers.Timer matrixTimer = default!;
|
||||
AnimeMatrixDevice mat;
|
||||
|
||||
double[] AudioValues;
|
||||
WasapiCapture AudioDevice;
|
||||
SettingsForm settings;
|
||||
|
||||
System.Timers.Timer matrixTimer = default!;
|
||||
AnimeMatrixDevice? mat;
|
||||
|
||||
double[]? AudioValues;
|
||||
WasapiCapture? AudioDevice;
|
||||
|
||||
public bool IsValid => mat != null;
|
||||
|
||||
private long lastPresent;
|
||||
private List<double> maxes = new List<double>();
|
||||
|
||||
public AniMatrix()
|
||||
public AniMatrixControl(SettingsForm settingsForm)
|
||||
{
|
||||
settings = settingsForm;
|
||||
|
||||
try
|
||||
{
|
||||
mat = new AnimeMatrixDevice();
|
||||
@@ -42,10 +47,10 @@ namespace GHelper.AnimeMatrix
|
||||
|
||||
if (!IsValid) return;
|
||||
|
||||
int brightness = AppConfig.getConfig("matrix_brightness");
|
||||
int running = AppConfig.getConfig("matrix_running");
|
||||
int brightness = AppConfig.Get("matrix_brightness");
|
||||
int running = AppConfig.Get("matrix_running");
|
||||
|
||||
bool auto = AppConfig.getConfig("matrix_auto") == 1;
|
||||
bool auto = AppConfig.Is("matrix_auto");
|
||||
|
||||
if (brightness < 0) brightness = 0;
|
||||
if (running < 0) running = 0;
|
||||
@@ -75,7 +80,7 @@ namespace GHelper.AnimeMatrix
|
||||
switch (running)
|
||||
{
|
||||
case 2:
|
||||
SetMatrixPicture(AppConfig.getConfigString("matrix_picture"));
|
||||
SetMatrixPicture(AppConfig.GetString("matrix_picture"));
|
||||
break;
|
||||
case 3:
|
||||
SetMatrixClock();
|
||||
@@ -110,7 +115,7 @@ namespace GHelper.AnimeMatrix
|
||||
{
|
||||
//if (!IsValid) return;
|
||||
|
||||
switch (AppConfig.getConfig("matrix_running"))
|
||||
switch (AppConfig.Get("matrix_running"))
|
||||
{
|
||||
case 2:
|
||||
mat.PresentNextFrame();
|
||||
@@ -251,12 +256,43 @@ namespace GHelper.AnimeMatrix
|
||||
if (maxes.Count > 20) maxes.RemoveAt(0);
|
||||
maxAverage = maxes.Average();
|
||||
|
||||
for (int i = 0; i < size; i++) DrawBar(20 - i, bars[i]*20/maxAverage);
|
||||
for (int i = 0; i < size; i++) DrawBar(20 - i, bars[i] * 20 / maxAverage);
|
||||
|
||||
mat.Present();
|
||||
}
|
||||
|
||||
|
||||
public void OpenMatrixPicture()
|
||||
{
|
||||
string fileName = null;
|
||||
|
||||
Thread t = new Thread(() =>
|
||||
{
|
||||
OpenFileDialog of = new OpenFileDialog();
|
||||
of.Filter = "Image Files (*.bmp;*.jpg;*.jpeg,*.png,*.gif)|*.BMP;*.JPG;*.JPEG;*.PNG;*.GIF";
|
||||
if (of.ShowDialog() == DialogResult.OK)
|
||||
{
|
||||
fileName = of.FileName;
|
||||
}
|
||||
return;
|
||||
});
|
||||
|
||||
t.SetApartmentState(ApartmentState.STA);
|
||||
t.Start();
|
||||
t.Join();
|
||||
|
||||
if (fileName is not null)
|
||||
{
|
||||
AppConfig.Set("matrix_picture", fileName);
|
||||
AppConfig.Set("matrix_running", 2);
|
||||
|
||||
SetMatrixPicture(fileName);
|
||||
settings.SetMatrixRunning(2);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void SetMatrixPicture(string fileName)
|
||||
{
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// Source thanks to https://github.com/vddCore/Starlight with some adjustments from me
|
||||
|
||||
using Starlight.Communication;
|
||||
using GHelper.AnimeMatrix.Communication;
|
||||
using System.Drawing.Drawing2D;
|
||||
using System.Drawing.Text;
|
||||
using System.Globalization;
|
||||
@@ -369,7 +369,7 @@ namespace Starlight.AnimeMatrix
|
||||
g.CompositingQuality = CompositingQuality.HighQuality;
|
||||
g.SmoothingMode = SmoothingMode.AntiAlias;
|
||||
|
||||
using (Font font = new Font("Consolas", 24F, FontStyle.Regular, GraphicsUnit.Pixel))
|
||||
using (Font font = new Font("Consolas", 21F, FontStyle.Regular, GraphicsUnit.Pixel))
|
||||
{
|
||||
SizeF textSize = g.MeasureString(text1, font);
|
||||
g.DrawString(text1, font, Brushes.White, (MaxColumns * 3 - textSize.Width) + 3, -4);
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
// Source thanks to https://github.com/vddCore/Starlight :)
|
||||
|
||||
using Starlight.Communication.Platform;
|
||||
using System.Configuration;
|
||||
using GHelper.AnimeMatrix.Communication.Platform;
|
||||
|
||||
namespace Starlight.Communication
|
||||
namespace GHelper.AnimeMatrix.Communication
|
||||
{
|
||||
public abstract class Device : IDisposable
|
||||
{
|
||||
@@ -1,6 +1,6 @@
|
||||
// Source thanks to https://github.com/vddCore/Starlight :)
|
||||
|
||||
namespace Starlight.Communication
|
||||
namespace GHelper.AnimeMatrix.Communication
|
||||
{
|
||||
public abstract class Packet
|
||||
{
|
||||
@@ -1,4 +1,4 @@
|
||||
namespace Starlight.Communication.Platform
|
||||
namespace GHelper.AnimeMatrix.Communication.Platform
|
||||
{
|
||||
internal abstract class UsbProvider : IDisposable
|
||||
{
|
||||
@@ -13,7 +13,7 @@ namespace Starlight.Communication.Platform
|
||||
|
||||
public abstract void Set(byte[] data);
|
||||
public abstract byte[] Get(byte[] data);
|
||||
|
||||
|
||||
public abstract void Dispose();
|
||||
}
|
||||
}
|
||||
@@ -1,14 +1,14 @@
|
||||
using System.ComponentModel;
|
||||
using HidSharp;
|
||||
|
||||
namespace Starlight.Communication.Platform
|
||||
namespace GHelper.AnimeMatrix.Communication.Platform
|
||||
{
|
||||
internal class WindowsUsbProvider : UsbProvider
|
||||
{
|
||||
protected HidDevice HidDevice { get; }
|
||||
protected HidStream HidStream { get; }
|
||||
|
||||
public WindowsUsbProvider(ushort vendorId, ushort productId, int maxFeatureReportLength)
|
||||
public WindowsUsbProvider(ushort vendorId, ushort productId, int maxFeatureReportLength)
|
||||
: base(vendorId, productId)
|
||||
{
|
||||
try
|
||||
@@ -43,7 +43,7 @@ namespace Starlight.Communication.Platform
|
||||
{
|
||||
var outData = new byte[data.Length];
|
||||
Array.Copy(data, outData, data.Length);
|
||||
|
||||
|
||||
WrapException(() =>
|
||||
{
|
||||
HidStream.GetFeature(outData);
|
||||
@@ -57,7 +57,7 @@ namespace Starlight.Communication.Platform
|
||||
{
|
||||
HidStream.Dispose();
|
||||
}
|
||||
|
||||
|
||||
private void WrapException(Action action)
|
||||
{
|
||||
try
|
||||
115
app/AppConfig.cs
115
app/AppConfig.cs
@@ -1,4 +1,5 @@
|
||||
using System.Diagnostics;
|
||||
using GHelper.Mode;
|
||||
using System.Diagnostics;
|
||||
using System.Management;
|
||||
using System.Text.Json;
|
||||
|
||||
@@ -13,8 +14,18 @@ public static class AppConfig
|
||||
static AppConfig()
|
||||
{
|
||||
|
||||
string startupPath = Application.StartupPath.Trim('\\');
|
||||
string appPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\GHelper";
|
||||
configFile = appPath + "\\config.json";
|
||||
string configName = "\\config.json";
|
||||
|
||||
if (File.Exists(startupPath + configName))
|
||||
{
|
||||
configFile = startupPath + configName;
|
||||
} else
|
||||
{
|
||||
configFile = appPath + configName;
|
||||
}
|
||||
|
||||
|
||||
if (!System.IO.Directory.Exists(appPath))
|
||||
System.IO.Directory.CreateDirectory(appPath);
|
||||
@@ -28,12 +39,13 @@ public static class AppConfig
|
||||
}
|
||||
catch
|
||||
{
|
||||
initConfig();
|
||||
Logger.WriteLine("Broken config: " + text);
|
||||
Init();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
initConfig();
|
||||
Init();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -56,14 +68,24 @@ public static class AppConfig
|
||||
|
||||
return _model;
|
||||
}
|
||||
|
||||
public static string GetModelShort()
|
||||
{
|
||||
string model = GetModel();
|
||||
int trim = model.LastIndexOf("_");
|
||||
if (trim > 0) model = model.Substring(0, trim);
|
||||
return model;
|
||||
}
|
||||
|
||||
public static bool ContainsModel(string contains)
|
||||
{
|
||||
|
||||
GetModel();
|
||||
return (_model is not null && _model.ToLower().Contains(contains.ToLower()));
|
||||
|
||||
}
|
||||
private static void initConfig()
|
||||
|
||||
|
||||
private static void Init()
|
||||
{
|
||||
config = new Dictionary<string, object>();
|
||||
config["performance_mode"] = 0;
|
||||
@@ -71,41 +93,27 @@ public static class AppConfig
|
||||
File.WriteAllText(configFile, jsonString);
|
||||
}
|
||||
|
||||
public static int getConfig(string name, int empty = -1)
|
||||
public static int Get(string name, int empty = -1)
|
||||
{
|
||||
if (config.ContainsKey(name))
|
||||
return int.Parse(config[name].ToString());
|
||||
else return empty;
|
||||
}
|
||||
|
||||
public static bool isConfig(string name)
|
||||
public static bool Is(string name)
|
||||
{
|
||||
return getConfig(name) == 1;
|
||||
return Get(name) == 1;
|
||||
}
|
||||
|
||||
public static string getConfigString(string name, string empty = null)
|
||||
public static string GetString(string name, string empty = null)
|
||||
{
|
||||
if (config.ContainsKey(name))
|
||||
return config[name].ToString();
|
||||
else return empty;
|
||||
}
|
||||
|
||||
public static void setConfig(string name, int value)
|
||||
private static void Write()
|
||||
{
|
||||
config[name] = value;
|
||||
string jsonString = JsonSerializer.Serialize(config, new JsonSerializerOptions { WriteIndented = true });
|
||||
try
|
||||
{
|
||||
File.WriteAllText(configFile, jsonString);
|
||||
} catch (Exception e)
|
||||
{
|
||||
Debug.Write(e.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
public static void setConfig(string name, string value)
|
||||
{
|
||||
config[name] = value;
|
||||
string jsonString = JsonSerializer.Serialize(config, new JsonSerializerOptions { WriteIndented = true });
|
||||
try
|
||||
{
|
||||
@@ -117,9 +125,26 @@ public static class AppConfig
|
||||
}
|
||||
}
|
||||
|
||||
public static string getParamName(AsusFan device, string paramName = "fan_profile")
|
||||
public static void Set(string name, int value)
|
||||
{
|
||||
int mode = getConfig("performance_mode");
|
||||
config[name] = value;
|
||||
Write();
|
||||
}
|
||||
|
||||
public static void Set(string name, string value)
|
||||
{
|
||||
config[name] = value;
|
||||
Write();
|
||||
}
|
||||
public static void Remove(string name)
|
||||
{
|
||||
config.Remove(name);
|
||||
Write();
|
||||
}
|
||||
|
||||
public static string GgetParamName(AsusFan device, string paramName = "fan_profile")
|
||||
{
|
||||
int mode = Modes.GetCurrent();
|
||||
string name;
|
||||
|
||||
switch (device)
|
||||
@@ -142,9 +167,9 @@ public static class AppConfig
|
||||
return paramName + "_" + name + "_" + mode;
|
||||
}
|
||||
|
||||
public static byte[] getFanConfig(AsusFan device)
|
||||
public static byte[] GetFanConfig(AsusFan device)
|
||||
{
|
||||
string curveString = getConfigString(getParamName(device));
|
||||
string curveString = GetString(GgetParamName(device));
|
||||
byte[] curve = { };
|
||||
|
||||
if (curveString is not null)
|
||||
@@ -153,10 +178,10 @@ public static class AppConfig
|
||||
return curve;
|
||||
}
|
||||
|
||||
public static void setFanConfig(AsusFan device, byte[] curve)
|
||||
public static void SetFanConfig(AsusFan device, byte[] curve)
|
||||
{
|
||||
string bitCurve = BitConverter.ToString(curve);
|
||||
setConfig(getParamName(device), bitCurve);
|
||||
Set(GgetParamName(device), bitCurve);
|
||||
}
|
||||
|
||||
|
||||
@@ -168,9 +193,9 @@ public static class AppConfig
|
||||
return array;
|
||||
}
|
||||
|
||||
public static byte[] getDefaultCurve(AsusFan device)
|
||||
public static byte[] GetDefaultCurve(AsusFan device)
|
||||
{
|
||||
int mode = getConfig("performance_mode");
|
||||
int mode = Modes.GetCurrentBase();
|
||||
byte[] curve;
|
||||
|
||||
switch (mode)
|
||||
@@ -198,23 +223,29 @@ public static class AppConfig
|
||||
return curve;
|
||||
}
|
||||
|
||||
public static string getConfigPerfString(string name)
|
||||
public static string GetModeString(string name)
|
||||
{
|
||||
int mode = getConfig("performance_mode");
|
||||
return getConfigString(name + "_" + mode);
|
||||
return GetString(name + "_" + Modes.GetCurrent());
|
||||
}
|
||||
|
||||
public static int getConfigPerf(string name)
|
||||
public static int GetMode(string name, int empty = -1)
|
||||
{
|
||||
int mode = getConfig("performance_mode");
|
||||
return getConfig(name + "_" + mode);
|
||||
return Get(name + "_" + Modes.GetCurrent(), empty);
|
||||
}
|
||||
|
||||
public static void setConfigPerf(string name, int value)
|
||||
public static bool IsMode(string name)
|
||||
{
|
||||
int mode = getConfig("performance_mode");
|
||||
setConfig(name + "_" + mode, value);
|
||||
return Get(name + "_" + Modes.GetCurrent()) == 1;
|
||||
}
|
||||
|
||||
public static void SetMode(string name, int value)
|
||||
{
|
||||
Set(name + "_" + Modes.GetCurrent(), value);
|
||||
}
|
||||
|
||||
public static void SetMode(string name, string value)
|
||||
{
|
||||
Set(name + "_" + Modes.GetCurrent(), value);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using GHelper;
|
||||
using System.Management;
|
||||
using System.Management;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
public enum AsusFan
|
||||
@@ -35,8 +34,16 @@ public class AsusACPI
|
||||
const uint INIT = 0x54494E49;
|
||||
|
||||
public const uint UniversalControl = 0x00100021;
|
||||
|
||||
public const int KB_Light_Up = 0xc4;
|
||||
public const int KB_Light_Down = 0xc5;
|
||||
public const int Brightness_Down = 0x10;
|
||||
public const int Brightness_Up = 0x20;
|
||||
public const int KB_Sleep = 0x6c;
|
||||
public const int KB_DUO_PgUpDn = 0x4B;
|
||||
public const int KB_DUO_SecondDisplay = 0x6A;
|
||||
|
||||
|
||||
public const int Touchpad_Toggle = 0x6B;
|
||||
|
||||
public const int ChargerMode = 0x0012006C;
|
||||
@@ -66,10 +73,10 @@ public class AsusACPI
|
||||
public const int Temp_CPU = 0x00120094;
|
||||
public const int Temp_GPU = 0x00120097;
|
||||
|
||||
public const int PPT_TotalA0 = 0x001200A0; // SPL (Total limit for all-AMD models)
|
||||
public const int PPT_TotalA0 = 0x001200A0; // SPL (Total limit for all-AMD models) / PL1
|
||||
public const int PPT_EDCA1 = 0x001200A1; // CPU EDC
|
||||
public const int PPT_TDCA2 = 0x001200A2; // CPU TDC
|
||||
public const int PPT_APUA3 = 0x001200A3; // sPPT (long boost limit)
|
||||
public const int PPT_APUA3 = 0x001200A3; // sPPT (long boost limit) / PL2
|
||||
|
||||
public const int PPT_CPUB0 = 0x001200B0; // CPU PPT on 2022 (PPT_LIMIT_APU)
|
||||
public const int PPT_CPUB1 = 0x001200B1; // Total PPT on 2022 (PPT_LIMIT_SLOW)
|
||||
@@ -93,17 +100,17 @@ public class AsusACPI
|
||||
public const int PerformanceBalanced = 0;
|
||||
public const int PerformanceTurbo = 1;
|
||||
public const int PerformanceSilent = 2;
|
||||
public const int PerformanceManual = 4;
|
||||
|
||||
public const int GPUModeEco = 0;
|
||||
public const int GPUModeStandard = 1;
|
||||
public const int GPUModeUltimate = 2;
|
||||
|
||||
|
||||
public const int MaxTotal = 250;
|
||||
public static int MaxTotal => AppConfig.ContainsModel("13QY") ? 250 : 150;
|
||||
public const int MinTotal = 5;
|
||||
public const int DefaultTotal = 125;
|
||||
|
||||
public const int MaxCPU = 130;
|
||||
public const int MaxCPU = 100;
|
||||
public const int MinCPU = 5;
|
||||
public const int DefaultCPU = 80;
|
||||
|
||||
@@ -389,7 +396,7 @@ public class AsusACPI
|
||||
if (count == 0 && pair.Key >= 40)
|
||||
{
|
||||
fix = true;
|
||||
pointsFixed.Add(20, 0);
|
||||
pointsFixed.Add(30, 0);
|
||||
}
|
||||
|
||||
if (count != 3 || !fix)
|
||||
@@ -420,6 +427,25 @@ public class AsusACPI
|
||||
return DeviceGet(PPT_CPUB0) >= 0 && DeviceGet(PPT_GPUC0) < 0;
|
||||
}
|
||||
|
||||
|
||||
public void ScanRange()
|
||||
{
|
||||
int value;
|
||||
string appPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\GHelper";
|
||||
string logFile = appPath + "\\scan.txt";
|
||||
for (uint i = 0x00000000; i <= 0x00160000; i++)
|
||||
{
|
||||
value = DeviceGet(i);
|
||||
if (value >= 0)
|
||||
using (StreamWriter w = File.AppendText(logFile))
|
||||
{
|
||||
w.WriteLine(i.ToString("X8") + ": " + value.ToString("X4") + " (" + value + ")");
|
||||
w.Close();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void TUFKeyboardBrightness(int brightness)
|
||||
{
|
||||
int param = 0x80 | (brightness & 0x7F);
|
||||
|
||||
@@ -66,7 +66,7 @@ namespace GHelper
|
||||
static byte[] MESSAGE_SET = { AURA_HID_ID, 0xb5, 0, 0, 0 };
|
||||
static byte[] MESSAGE_APPLY = { AURA_HID_ID, 0xb4 };
|
||||
|
||||
static int[] deviceIds = { 0x1a30, 0x1854, 0x1869, 0x1866, 0x19b6, 0x1822, 0x1837, 0x1854, 0x184a, 0x183d, 0x8502, 0x1807, 0x17e0, 0x18c6 };
|
||||
static int[] deviceIds = { 0x1a30, 0x1854, 0x1869, 0x1866, 0x19b6, 0x1822, 0x1837, 0x1854, 0x184a, 0x183d, 0x8502, 0x1807, 0x17e0, 0x18c6, 0x1abe };
|
||||
|
||||
private static int mode = 0;
|
||||
private static int speed = 1;
|
||||
@@ -118,13 +118,14 @@ namespace GHelper
|
||||
_modes.Remove(3);
|
||||
}
|
||||
|
||||
if (AppConfig.ContainsModel("401"))
|
||||
if (AppConfig.ContainsModel("401") || AppConfig.ContainsModel("X13"))
|
||||
{
|
||||
_modes.Remove(2);
|
||||
_modes.Remove(3);
|
||||
}
|
||||
|
||||
if (AppConfig.ContainsModel("G513")) {
|
||||
if (AppConfig.ContainsModel("G513QY"))
|
||||
{
|
||||
return _modes;
|
||||
}
|
||||
|
||||
@@ -149,6 +150,11 @@ namespace GHelper
|
||||
}
|
||||
}
|
||||
|
||||
public static bool HasColor()
|
||||
{
|
||||
return AppConfig.ContainsModel("GA401") || AppConfig.ContainsModel("X13");
|
||||
}
|
||||
|
||||
public static bool HasSecondColor()
|
||||
{
|
||||
return (mode == 1 && !AppConfig.ContainsModel("TUF"));
|
||||
@@ -178,13 +184,11 @@ namespace GHelper
|
||||
}
|
||||
|
||||
|
||||
private static IEnumerable<HidDevice> GetHidDevices(int[] deviceIds, int minInput = 18, int minFeatures = 1)
|
||||
private static IEnumerable<HidDevice> GetHidDevices(int[] deviceIds, int minFeatures = 1)
|
||||
{
|
||||
HidDevice[] HidDeviceList = HidDevices.Enumerate(ASUS_ID, deviceIds).ToArray();
|
||||
foreach (HidDevice device in HidDeviceList)
|
||||
if (device.IsConnected
|
||||
&& device.Capabilities.FeatureReportByteLength >= minFeatures
|
||||
&& device.Capabilities.InputReportByteLength >= minInput)
|
||||
if (device.IsConnected && device.Capabilities.FeatureReportByteLength >= minFeatures)
|
||||
yield return device;
|
||||
}
|
||||
|
||||
@@ -234,7 +238,7 @@ namespace GHelper
|
||||
{
|
||||
Task.Run(async () =>
|
||||
{
|
||||
var devices = GetHidDevices(deviceIds, 0);
|
||||
var devices = GetHidDevices(deviceIds);
|
||||
foreach (HidDevice device in devices)
|
||||
{
|
||||
device.OpenDevice();
|
||||
@@ -249,7 +253,7 @@ namespace GHelper
|
||||
}
|
||||
|
||||
|
||||
public static void ApplyBrightness(int brightness)
|
||||
public static void ApplyBrightness(int brightness, string log = "Backlight")
|
||||
{
|
||||
|
||||
if (AppConfig.ContainsModel("TUF"))
|
||||
@@ -260,22 +264,35 @@ namespace GHelper
|
||||
{
|
||||
|
||||
byte[] msg = { AURA_HID_ID, 0xba, 0xc5, 0xc4, (byte)brightness };
|
||||
byte[] msgBackup = { INPUT_HID_ID, 0xba, 0xc5, 0xc4, (byte)brightness };
|
||||
|
||||
var devices = GetHidDevices(deviceIds);
|
||||
foreach (HidDevice device in devices)
|
||||
{
|
||||
device.OpenDevice();
|
||||
device.WriteFeatureData(msg);
|
||||
Logger.WriteLine("KB Backlight:" + BitConverter.ToString(msg));
|
||||
|
||||
if (device.ReadFeatureData(out byte[] data, AURA_HID_ID))
|
||||
{
|
||||
device.WriteFeatureData(msg);
|
||||
Logger.WriteLine(log + ":" + BitConverter.ToString(msg));
|
||||
}
|
||||
|
||||
if (AppConfig.ContainsModel("GA503") && device.ReadFeatureData(out byte[] dataBackkup, INPUT_HID_ID))
|
||||
{
|
||||
device.WriteFeatureData(msgBackup);
|
||||
Logger.WriteLine(log + ":" + BitConverter.ToString(msgBackup));
|
||||
}
|
||||
|
||||
device.CloseDevice();
|
||||
}
|
||||
|
||||
// Backup payload for old models
|
||||
if (AppConfig.ContainsModel("503"))
|
||||
/*
|
||||
if (AppConfig.ContainsModel("GA503RW"))
|
||||
{
|
||||
byte[] msgBackup = { INPUT_HID_ID, 0xba, 0xc5, 0xc4, (byte)brightness };
|
||||
|
||||
var devicesBackup = GetHidDevices(deviceIds, 0);
|
||||
var devicesBackup = GetHidDevices(deviceIds);
|
||||
foreach (HidDevice device in devicesBackup)
|
||||
{
|
||||
device.OpenDevice();
|
||||
@@ -283,6 +300,7 @@ namespace GHelper
|
||||
device.CloseDevice();
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
});
|
||||
|
||||
@@ -297,13 +315,15 @@ namespace GHelper
|
||||
|
||||
|
||||
var devices = GetHidDevices(deviceIds);
|
||||
//Logger.WriteLine("USB-KB = " + BitConverter.ToString(msg));
|
||||
|
||||
foreach (HidDevice device in devices)
|
||||
{
|
||||
device.OpenDevice();
|
||||
device.WriteFeatureData(msg);
|
||||
Logger.WriteLine("USB-KB " + device.Attributes.ProductHexId + ":" + BitConverter.ToString(msg));
|
||||
if (device.ReadFeatureData(out byte[] data, AURA_HID_ID))
|
||||
{
|
||||
device.WriteFeatureData(msg);
|
||||
Logger.WriteLine("USB-KB " + device.Attributes.ProductHexId + ":" + BitConverter.ToString(msg));
|
||||
}
|
||||
device.CloseDevice();
|
||||
}
|
||||
|
||||
@@ -336,23 +356,19 @@ namespace GHelper
|
||||
}
|
||||
|
||||
byte[] msg = AuraMessage(Mode, Color1, Color2, _speed);
|
||||
|
||||
var devices = GetHidDevices(deviceIds);
|
||||
|
||||
if (devices.Count() == 0)
|
||||
{
|
||||
Logger.WriteLine("USB-KB : not found");
|
||||
devices = GetHidDevices(deviceIds, 1);
|
||||
}
|
||||
|
||||
foreach (HidDevice device in devices)
|
||||
{
|
||||
device.OpenDevice();
|
||||
device.WriteFeatureData(msg);
|
||||
device.WriteFeatureData(MESSAGE_SET);
|
||||
device.WriteFeatureData(MESSAGE_APPLY);
|
||||
if (device.ReadFeatureData(out byte[] data, AURA_HID_ID))
|
||||
{
|
||||
device.WriteFeatureData(msg);
|
||||
device.WriteFeatureData(MESSAGE_SET);
|
||||
device.WriteFeatureData(MESSAGE_APPLY);
|
||||
Logger.WriteLine("USB-KB " + device.Capabilities.FeatureReportByteLength + "|" + device.Capabilities.InputReportByteLength + device.Description + device.DevicePath + ":" + BitConverter.ToString(msg));
|
||||
}
|
||||
device.CloseDevice();
|
||||
Logger.WriteLine("USB-KB " + device.Capabilities.FeatureReportByteLength + "|" + device.Capabilities.InputReportByteLength + device.Description + device.DevicePath + ":" + BitConverter.ToString(msg));
|
||||
}
|
||||
|
||||
if (AppConfig.ContainsModel("TUF"))
|
||||
@@ -370,7 +386,7 @@ namespace GHelper
|
||||
var payload = new byte[300];
|
||||
Array.Copy(msg, payload, msg.Length);
|
||||
|
||||
foreach (HidDevice device in GetHidDevices(new int[] { 0x1970 }, 0, 300))
|
||||
foreach (HidDevice device in GetHidDevices(new int[] { 0x1970 }, 300))
|
||||
{
|
||||
device.OpenDevice();
|
||||
Logger.WriteLine("XGM " + device.Attributes.ProductHexId + "|" + device.Capabilities.FeatureReportByteLength + ":" + BitConverter.ToString(msg));
|
||||
|
||||
130
app/AutoUpdate/AutoUpdateControl.cs
Normal file
130
app/AutoUpdate/AutoUpdateControl.cs
Normal file
@@ -0,0 +1,130 @@
|
||||
using System.Diagnostics;
|
||||
using System.Net;
|
||||
using System.Reflection;
|
||||
using System.Text.Json;
|
||||
|
||||
namespace GHelper.AutoUpdate
|
||||
{
|
||||
public class AutoUpdateControl
|
||||
{
|
||||
|
||||
SettingsForm settings;
|
||||
|
||||
public string versionUrl = "http://github.com/seerge/g-helper/releases";
|
||||
static long lastUpdate;
|
||||
|
||||
public AutoUpdateControl(SettingsForm settingsForm)
|
||||
{
|
||||
settings = settingsForm;
|
||||
settings.SetVersionLabel(Properties.Strings.VersionLabel + ": " + Assembly.GetExecutingAssembly().GetName().Version);
|
||||
}
|
||||
|
||||
public void CheckForUpdates()
|
||||
{
|
||||
// Run update once per 12 hours
|
||||
if (Math.Abs(DateTimeOffset.Now.ToUnixTimeSeconds() - lastUpdate) < 43200) return;
|
||||
lastUpdate = DateTimeOffset.Now.ToUnixTimeSeconds();
|
||||
|
||||
Task.Run(async () =>
|
||||
{
|
||||
await Task.Delay(TimeSpan.FromSeconds(1));
|
||||
CheckForUpdatesAsync();
|
||||
});
|
||||
}
|
||||
|
||||
public void LoadReleases()
|
||||
{
|
||||
Process.Start(new ProcessStartInfo(versionUrl) { UseShellExecute = true });
|
||||
}
|
||||
|
||||
async void CheckForUpdatesAsync()
|
||||
{
|
||||
|
||||
try
|
||||
{
|
||||
|
||||
using (var httpClient = new HttpClient())
|
||||
{
|
||||
httpClient.DefaultRequestHeaders.Add("User-Agent", "C# App");
|
||||
var json = await httpClient.GetStringAsync("https://api.github.com/repos/seerge/g-helper/releases/latest");
|
||||
var config = JsonSerializer.Deserialize<JsonElement>(json);
|
||||
var tag = config.GetProperty("tag_name").ToString().Replace("v", "");
|
||||
var assets = config.GetProperty("assets");
|
||||
|
||||
string url = null;
|
||||
|
||||
for (int i = 0; i < assets.GetArrayLength(); i++)
|
||||
{
|
||||
if (assets[i].GetProperty("browser_download_url").ToString().Contains(".zip"))
|
||||
url = assets[i].GetProperty("browser_download_url").ToString();
|
||||
}
|
||||
|
||||
if (url is null)
|
||||
url = assets[0].GetProperty("browser_download_url").ToString();
|
||||
|
||||
var gitVersion = new Version(tag);
|
||||
var appVersion = new Version(Assembly.GetExecutingAssembly().GetName().Version.ToString());
|
||||
//appVersion = new Version("0.50.0.0");
|
||||
|
||||
if (gitVersion.CompareTo(appVersion) > 0)
|
||||
{
|
||||
versionUrl = url;
|
||||
settings.SetVersionLabel(Properties.Strings.DownloadUpdate + ": " + tag, true);
|
||||
|
||||
if (AppConfig.GetString("skip_version") != tag)
|
||||
{
|
||||
DialogResult dialogResult = MessageBox.Show(Properties.Strings.DownloadUpdate + ": G-Helper " + tag + "?", "Update", MessageBoxButtons.YesNo);
|
||||
if (dialogResult == DialogResult.Yes)
|
||||
AutoUpdate(url);
|
||||
else
|
||||
AppConfig.Set("skip_version", tag);
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger.WriteLine($"Latest version {appVersion}");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.WriteLine("Failed to check for updates:" + ex.Message);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
async void AutoUpdate(string requestUri)
|
||||
{
|
||||
|
||||
Uri uri = new Uri(requestUri);
|
||||
string zipName = Path.GetFileName(uri.LocalPath);
|
||||
|
||||
string exeLocation = Application.ExecutablePath;
|
||||
string exeDir = Path.GetDirectoryName(exeLocation);
|
||||
string zipLocation = exeDir + "\\" + zipName;
|
||||
|
||||
using (WebClient client = new WebClient())
|
||||
{
|
||||
client.DownloadFile(uri, zipLocation);
|
||||
|
||||
Logger.WriteLine(requestUri);
|
||||
Logger.WriteLine(zipLocation);
|
||||
Logger.WriteLine(exeLocation);
|
||||
|
||||
var cmd = new Process();
|
||||
cmd.StartInfo.UseShellExecute = false;
|
||||
cmd.StartInfo.CreateNoWindow = true;
|
||||
cmd.StartInfo.FileName = "powershell";
|
||||
cmd.StartInfo.Arguments = $"Start-Sleep -Seconds 1; Expand-Archive {zipLocation} -DestinationPath {exeDir} -Force; Remove-Item {zipLocation} -Force; {exeLocation}";
|
||||
cmd.Start();
|
||||
|
||||
Application.Exit();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
33
app/Battery/BatteryControl.cs
Normal file
33
app/Battery/BatteryControl.cs
Normal file
@@ -0,0 +1,33 @@
|
||||
using GHelper.Helpers;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace GHelper.Battery
|
||||
{
|
||||
internal class BatteryControl
|
||||
{
|
||||
|
||||
public static void SetBatteryChargeLimit(int limit = -1)
|
||||
{
|
||||
|
||||
if (limit < 0) limit = AppConfig.Get("charge_limit");
|
||||
if (limit < 40 || limit > 100) return;
|
||||
|
||||
Program.settingsForm.VisualiseBattery(limit);
|
||||
|
||||
Program.acpi.DeviceSet(AsusACPI.BatteryLimit, limit, "BatteryLimit");
|
||||
|
||||
try
|
||||
{
|
||||
OptimizationService.SetChargeLimit(limit);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.WriteLine(ex);
|
||||
}
|
||||
|
||||
AppConfig.Set("charge_limit", limit);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
99
app/Display/ScreenControl.cs
Normal file
99
app/Display/ScreenControl.cs
Normal file
@@ -0,0 +1,99 @@
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace GHelper.Display
|
||||
{
|
||||
public class ScreenControl
|
||||
{
|
||||
public void AutoScreen(bool force = false)
|
||||
{
|
||||
if (force || AppConfig.Is("screen_auto"))
|
||||
{
|
||||
if (SystemInformation.PowerStatus.PowerLineStatus == PowerLineStatus.Online)
|
||||
SetScreen(1000, 1);
|
||||
else
|
||||
SetScreen(60, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetScreen(overdrive: AppConfig.Get("overdrive"));
|
||||
}
|
||||
}
|
||||
|
||||
public void SetScreen(int frequency = -1, int overdrive = -1, int miniled = -1)
|
||||
{
|
||||
|
||||
if (ScreenNative.GetRefreshRate() < 0) // Laptop screen not detected or has unknown refresh rate
|
||||
{
|
||||
InitScreen();
|
||||
return;
|
||||
}
|
||||
|
||||
if (frequency >= 1000)
|
||||
{
|
||||
frequency = ScreenNative.GetRefreshRate(true);
|
||||
}
|
||||
|
||||
if (frequency > 0)
|
||||
{
|
||||
ScreenNative.SetRefreshRate(frequency);
|
||||
}
|
||||
|
||||
if (overdrive >= 0)
|
||||
{
|
||||
if (AppConfig.Get("no_overdrive") == 1) overdrive = 0;
|
||||
Program.acpi.DeviceSet(AsusACPI.ScreenOverdrive, overdrive, "ScreenOverdrive");
|
||||
|
||||
}
|
||||
|
||||
if (miniled >= 0)
|
||||
{
|
||||
Program.acpi.DeviceSet(AsusACPI.ScreenMiniled, miniled, "Miniled");
|
||||
Debug.WriteLine("Miniled " + miniled);
|
||||
}
|
||||
|
||||
InitScreen();
|
||||
}
|
||||
|
||||
|
||||
public void ToogleMiniled()
|
||||
{
|
||||
int miniled = (AppConfig.Get("miniled") == 1) ? 0 : 1;
|
||||
AppConfig.Set("miniled", miniled);
|
||||
SetScreen(-1, -1, miniled);
|
||||
}
|
||||
|
||||
public void InitScreen()
|
||||
{
|
||||
int frequency = ScreenNative.GetRefreshRate();
|
||||
int maxFrequency = ScreenNative.GetRefreshRate(true);
|
||||
|
||||
bool screenAuto = AppConfig.Is("screen_auto");
|
||||
bool overdriveSetting = !AppConfig.Is("no_overdrive");
|
||||
|
||||
int overdrive = Program.acpi.DeviceGet(AsusACPI.ScreenOverdrive);
|
||||
int miniled = Program.acpi.DeviceGet(AsusACPI.ScreenMiniled);
|
||||
|
||||
if (miniled >= 0)
|
||||
AppConfig.Set("miniled", miniled);
|
||||
|
||||
bool screenEnabled = (frequency >= 0);
|
||||
|
||||
AppConfig.Set("frequency", frequency);
|
||||
AppConfig.Set("overdrive", overdrive);
|
||||
|
||||
Program.settingsForm.Invoke(delegate
|
||||
{
|
||||
Program.settingsForm.VisualiseScreen(
|
||||
screenEnabled: screenEnabled,
|
||||
screenAuto: screenAuto,
|
||||
frequency: frequency,
|
||||
maxFrequency: maxFrequency,
|
||||
overdrive: overdrive,
|
||||
overdriveSetting: overdriveSetting,
|
||||
miniled: miniled
|
||||
);
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
303
app/Display/ScreenInterrogatory.cs
Normal file
303
app/Display/ScreenInterrogatory.cs
Normal file
@@ -0,0 +1,303 @@
|
||||
using System.ComponentModel;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace GHelper.Display
|
||||
{
|
||||
public static class ScreenInterrogatory
|
||||
{
|
||||
public const int ERROR_SUCCESS = 0;
|
||||
|
||||
#region enums
|
||||
|
||||
public enum QUERY_DEVICE_CONFIG_FLAGS : uint
|
||||
{
|
||||
QDC_ALL_PATHS = 0x00000001,
|
||||
QDC_ONLY_ACTIVE_PATHS = 0x00000002,
|
||||
QDC_DATABASE_CURRENT = 0x00000004
|
||||
}
|
||||
|
||||
public enum DISPLAYCONFIG_VIDEO_OUTPUT_TECHNOLOGY : uint
|
||||
{
|
||||
DISPLAYCONFIG_OUTPUT_TECHNOLOGY_OTHER = 0xFFFFFFFF,
|
||||
DISPLAYCONFIG_OUTPUT_TECHNOLOGY_HD15 = 0,
|
||||
DISPLAYCONFIG_OUTPUT_TECHNOLOGY_SVIDEO = 1,
|
||||
DISPLAYCONFIG_OUTPUT_TECHNOLOGY_COMPOSITE_VIDEO = 2,
|
||||
DISPLAYCONFIG_OUTPUT_TECHNOLOGY_COMPONENT_VIDEO = 3,
|
||||
DISPLAYCONFIG_OUTPUT_TECHNOLOGY_DVI = 4,
|
||||
DISPLAYCONFIG_OUTPUT_TECHNOLOGY_HDMI = 5,
|
||||
DISPLAYCONFIG_OUTPUT_TECHNOLOGY_LVDS = 6,
|
||||
DISPLAYCONFIG_OUTPUT_TECHNOLOGY_D_JPN = 8,
|
||||
DISPLAYCONFIG_OUTPUT_TECHNOLOGY_SDI = 9,
|
||||
DISPLAYCONFIG_OUTPUT_TECHNOLOGY_DISPLAYPORT_EXTERNAL = 10,
|
||||
DISPLAYCONFIG_OUTPUT_TECHNOLOGY_DISPLAYPORT_EMBEDDED = 11,
|
||||
DISPLAYCONFIG_OUTPUT_TECHNOLOGY_UDI_EXTERNAL = 12,
|
||||
DISPLAYCONFIG_OUTPUT_TECHNOLOGY_UDI_EMBEDDED = 13,
|
||||
DISPLAYCONFIG_OUTPUT_TECHNOLOGY_SDTVDONGLE = 14,
|
||||
DISPLAYCONFIG_OUTPUT_TECHNOLOGY_MIRACAST = 15,
|
||||
DISPLAYCONFIG_OUTPUT_TECHNOLOGY_INTERNAL = 0x80000000,
|
||||
DISPLAYCONFIG_OUTPUT_TECHNOLOGY_FORCE_UINT32 = 0xFFFFFFFF
|
||||
}
|
||||
|
||||
public enum DISPLAYCONFIG_SCANLINE_ORDERING : uint
|
||||
{
|
||||
DISPLAYCONFIG_SCANLINE_ORDERING_UNSPECIFIED = 0,
|
||||
DISPLAYCONFIG_SCANLINE_ORDERING_PROGRESSIVE = 1,
|
||||
DISPLAYCONFIG_SCANLINE_ORDERING_INTERLACED = 2,
|
||||
DISPLAYCONFIG_SCANLINE_ORDERING_INTERLACED_UPPERFIELDFIRST = DISPLAYCONFIG_SCANLINE_ORDERING_INTERLACED,
|
||||
DISPLAYCONFIG_SCANLINE_ORDERING_INTERLACED_LOWERFIELDFIRST = 3,
|
||||
DISPLAYCONFIG_SCANLINE_ORDERING_FORCE_UINT32 = 0xFFFFFFFF
|
||||
}
|
||||
|
||||
public enum DISPLAYCONFIG_ROTATION : uint
|
||||
{
|
||||
DISPLAYCONFIG_ROTATION_IDENTITY = 1,
|
||||
DISPLAYCONFIG_ROTATION_ROTATE90 = 2,
|
||||
DISPLAYCONFIG_ROTATION_ROTATE180 = 3,
|
||||
DISPLAYCONFIG_ROTATION_ROTATE270 = 4,
|
||||
DISPLAYCONFIG_ROTATION_FORCE_UINT32 = 0xFFFFFFFF
|
||||
}
|
||||
|
||||
public enum DISPLAYCONFIG_SCALING : uint
|
||||
{
|
||||
DISPLAYCONFIG_SCALING_IDENTITY = 1,
|
||||
DISPLAYCONFIG_SCALING_CENTERED = 2,
|
||||
DISPLAYCONFIG_SCALING_STRETCHED = 3,
|
||||
DISPLAYCONFIG_SCALING_ASPECTRATIOCENTEREDMAX = 4,
|
||||
DISPLAYCONFIG_SCALING_CUSTOM = 5,
|
||||
DISPLAYCONFIG_SCALING_PREFERRED = 128,
|
||||
DISPLAYCONFIG_SCALING_FORCE_UINT32 = 0xFFFFFFFF
|
||||
}
|
||||
|
||||
public enum DISPLAYCONFIG_PIXELFORMAT : uint
|
||||
{
|
||||
DISPLAYCONFIG_PIXELFORMAT_8BPP = 1,
|
||||
DISPLAYCONFIG_PIXELFORMAT_16BPP = 2,
|
||||
DISPLAYCONFIG_PIXELFORMAT_24BPP = 3,
|
||||
DISPLAYCONFIG_PIXELFORMAT_32BPP = 4,
|
||||
DISPLAYCONFIG_PIXELFORMAT_NONGDI = 5,
|
||||
DISPLAYCONFIG_PIXELFORMAT_FORCE_UINT32 = 0xffffffff
|
||||
}
|
||||
|
||||
public enum DISPLAYCONFIG_MODE_INFO_TYPE : uint
|
||||
{
|
||||
DISPLAYCONFIG_MODE_INFO_TYPE_SOURCE = 1,
|
||||
DISPLAYCONFIG_MODE_INFO_TYPE_TARGET = 2,
|
||||
DISPLAYCONFIG_MODE_INFO_TYPE_FORCE_UINT32 = 0xFFFFFFFF
|
||||
}
|
||||
|
||||
public enum DISPLAYCONFIG_DEVICE_INFO_TYPE : uint
|
||||
{
|
||||
DISPLAYCONFIG_DEVICE_INFO_GET_SOURCE_NAME = 1,
|
||||
DISPLAYCONFIG_DEVICE_INFO_GET_TARGET_NAME = 2,
|
||||
DISPLAYCONFIG_DEVICE_INFO_GET_TARGET_PREFERRED_MODE = 3,
|
||||
DISPLAYCONFIG_DEVICE_INFO_GET_ADAPTER_NAME = 4,
|
||||
DISPLAYCONFIG_DEVICE_INFO_SET_TARGET_PERSISTENCE = 5,
|
||||
DISPLAYCONFIG_DEVICE_INFO_GET_TARGET_BASE_TYPE = 6,
|
||||
DISPLAYCONFIG_DEVICE_INFO_FORCE_UINT32 = 0xFFFFFFFF
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region structs
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct LUID
|
||||
{
|
||||
public uint LowPart;
|
||||
public int HighPart;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct DISPLAYCONFIG_PATH_SOURCE_INFO
|
||||
{
|
||||
public LUID adapterId;
|
||||
public uint id;
|
||||
public uint modeInfoIdx;
|
||||
public uint statusFlags;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct DISPLAYCONFIG_PATH_TARGET_INFO
|
||||
{
|
||||
public LUID adapterId;
|
||||
public uint id;
|
||||
public uint modeInfoIdx;
|
||||
private DISPLAYCONFIG_VIDEO_OUTPUT_TECHNOLOGY outputTechnology;
|
||||
private DISPLAYCONFIG_ROTATION rotation;
|
||||
private DISPLAYCONFIG_SCALING scaling;
|
||||
private DISPLAYCONFIG_RATIONAL refreshRate;
|
||||
private DISPLAYCONFIG_SCANLINE_ORDERING scanLineOrdering;
|
||||
public bool targetAvailable;
|
||||
public uint statusFlags;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct DISPLAYCONFIG_RATIONAL
|
||||
{
|
||||
public uint Numerator;
|
||||
public uint Denominator;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct DISPLAYCONFIG_PATH_INFO
|
||||
{
|
||||
public DISPLAYCONFIG_PATH_SOURCE_INFO sourceInfo;
|
||||
public DISPLAYCONFIG_PATH_TARGET_INFO targetInfo;
|
||||
public uint flags;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct DISPLAYCONFIG_2DREGION
|
||||
{
|
||||
public uint cx;
|
||||
public uint cy;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct DISPLAYCONFIG_VIDEO_SIGNAL_INFO
|
||||
{
|
||||
public ulong pixelRate;
|
||||
public DISPLAYCONFIG_RATIONAL hSyncFreq;
|
||||
public DISPLAYCONFIG_RATIONAL vSyncFreq;
|
||||
public DISPLAYCONFIG_2DREGION activeSize;
|
||||
public DISPLAYCONFIG_2DREGION totalSize;
|
||||
public uint videoStandard;
|
||||
public DISPLAYCONFIG_SCANLINE_ORDERING scanLineOrdering;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct DISPLAYCONFIG_TARGET_MODE
|
||||
{
|
||||
public DISPLAYCONFIG_VIDEO_SIGNAL_INFO targetVideoSignalInfo;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct POINTL
|
||||
{
|
||||
private int x;
|
||||
private int y;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct DISPLAYCONFIG_SOURCE_MODE
|
||||
{
|
||||
public uint width;
|
||||
public uint height;
|
||||
public DISPLAYCONFIG_PIXELFORMAT pixelFormat;
|
||||
public POINTL position;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Explicit)]
|
||||
public struct DISPLAYCONFIG_MODE_INFO_UNION
|
||||
{
|
||||
[FieldOffset(0)]
|
||||
public DISPLAYCONFIG_TARGET_MODE targetMode;
|
||||
|
||||
[FieldOffset(0)]
|
||||
public DISPLAYCONFIG_SOURCE_MODE sourceMode;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct DISPLAYCONFIG_MODE_INFO
|
||||
{
|
||||
public DISPLAYCONFIG_MODE_INFO_TYPE infoType;
|
||||
public uint id;
|
||||
public LUID adapterId;
|
||||
public DISPLAYCONFIG_MODE_INFO_UNION modeInfo;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct DISPLAYCONFIG_TARGET_DEVICE_NAME_FLAGS
|
||||
{
|
||||
public uint value;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct DISPLAYCONFIG_DEVICE_INFO_HEADER
|
||||
{
|
||||
public DISPLAYCONFIG_DEVICE_INFO_TYPE type;
|
||||
public uint size;
|
||||
public LUID adapterId;
|
||||
public uint id;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
|
||||
public struct DISPLAYCONFIG_TARGET_DEVICE_NAME
|
||||
{
|
||||
public DISPLAYCONFIG_DEVICE_INFO_HEADER header;
|
||||
public DISPLAYCONFIG_TARGET_DEVICE_NAME_FLAGS flags;
|
||||
public DISPLAYCONFIG_VIDEO_OUTPUT_TECHNOLOGY outputTechnology;
|
||||
public ushort edidManufactureId;
|
||||
public ushort edidProductCodeId;
|
||||
public uint connectorInstance;
|
||||
|
||||
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]
|
||||
public string monitorFriendlyDeviceName;
|
||||
|
||||
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
|
||||
public string monitorDevicePath;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region DLL-Imports
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
public static extern int GetDisplayConfigBufferSizes(
|
||||
QUERY_DEVICE_CONFIG_FLAGS flags, out uint numPathArrayElements, out uint numModeInfoArrayElements);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
public static extern int QueryDisplayConfig(
|
||||
QUERY_DEVICE_CONFIG_FLAGS flags,
|
||||
ref uint numPathArrayElements, [Out] DISPLAYCONFIG_PATH_INFO[] PathInfoArray,
|
||||
ref uint numModeInfoArrayElements, [Out] DISPLAYCONFIG_MODE_INFO[] ModeInfoArray,
|
||||
nint currentTopologyId
|
||||
);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
public static extern int DisplayConfigGetDeviceInfo(ref DISPLAYCONFIG_TARGET_DEVICE_NAME deviceName);
|
||||
|
||||
#endregion
|
||||
|
||||
private static DISPLAYCONFIG_TARGET_DEVICE_NAME DeviceName(LUID adapterId, uint targetId)
|
||||
{
|
||||
var deviceName = new DISPLAYCONFIG_TARGET_DEVICE_NAME
|
||||
{
|
||||
header =
|
||||
{
|
||||
size = (uint)Marshal.SizeOf(typeof (DISPLAYCONFIG_TARGET_DEVICE_NAME)),
|
||||
adapterId = adapterId,
|
||||
id = targetId,
|
||||
type = DISPLAYCONFIG_DEVICE_INFO_TYPE.DISPLAYCONFIG_DEVICE_INFO_GET_TARGET_NAME
|
||||
}
|
||||
};
|
||||
var error = DisplayConfigGetDeviceInfo(ref deviceName);
|
||||
if (error != ERROR_SUCCESS)
|
||||
throw new Win32Exception(error);
|
||||
|
||||
return deviceName;
|
||||
}
|
||||
|
||||
public static IEnumerable<DISPLAYCONFIG_TARGET_DEVICE_NAME> GetAllDevices()
|
||||
{
|
||||
uint pathCount, modeCount;
|
||||
var error = GetDisplayConfigBufferSizes(QUERY_DEVICE_CONFIG_FLAGS.QDC_ONLY_ACTIVE_PATHS, out pathCount, out modeCount);
|
||||
if (error != ERROR_SUCCESS)
|
||||
throw new Win32Exception(error);
|
||||
|
||||
var displayPaths = new DISPLAYCONFIG_PATH_INFO[pathCount];
|
||||
var displayModes = new DISPLAYCONFIG_MODE_INFO[modeCount];
|
||||
error = QueryDisplayConfig(QUERY_DEVICE_CONFIG_FLAGS.QDC_ONLY_ACTIVE_PATHS,
|
||||
ref pathCount, displayPaths, ref modeCount, displayModes, nint.Zero);
|
||||
if (error != ERROR_SUCCESS)
|
||||
throw new Win32Exception(error);
|
||||
|
||||
for (var i = 0; i < modeCount; i++)
|
||||
if (displayModes[i].infoType == DISPLAYCONFIG_MODE_INFO_TYPE.DISPLAYCONFIG_MODE_INFO_TYPE_TARGET)
|
||||
yield return DeviceName(displayModes[i].adapterId, displayModes[i].id);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
233
app/Display/ScreenNative.cs
Normal file
233
app/Display/ScreenNative.cs
Normal file
@@ -0,0 +1,233 @@
|
||||
using System.Runtime.InteropServices;
|
||||
using static GHelper.Display.ScreenInterrogatory;
|
||||
|
||||
namespace GHelper.Display
|
||||
{
|
||||
internal class ScreenNative
|
||||
{
|
||||
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
|
||||
public struct DEVMODE
|
||||
{
|
||||
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
|
||||
public string dmDeviceName;
|
||||
|
||||
public short dmSpecVersion;
|
||||
public short dmDriverVersion;
|
||||
public short dmSize;
|
||||
public short dmDriverExtra;
|
||||
public int dmFields;
|
||||
public int dmPositionX;
|
||||
public int dmPositionY;
|
||||
public int dmDisplayOrientation;
|
||||
public int dmDisplayFixedOutput;
|
||||
public short dmColor;
|
||||
public short dmDuplex;
|
||||
public short dmYResolution;
|
||||
public short dmTTOption;
|
||||
public short dmCollate;
|
||||
|
||||
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
|
||||
public string dmFormName;
|
||||
|
||||
public short dmLogPixels;
|
||||
public short dmBitsPerPel;
|
||||
public int dmPelsWidth;
|
||||
public int dmPelsHeight;
|
||||
public int dmDisplayFlags;
|
||||
public int dmDisplayFrequency;
|
||||
public int dmICMMethod;
|
||||
public int dmICMIntent;
|
||||
public int dmMediaType;
|
||||
public int dmDitherType;
|
||||
public int dmReserved1;
|
||||
public int dmReserved2;
|
||||
public int dmPanningWidth;
|
||||
public int dmPanningHeight;
|
||||
};
|
||||
|
||||
[Flags()]
|
||||
public enum DisplaySettingsFlags : int
|
||||
{
|
||||
CDS_UPDATEREGISTRY = 1,
|
||||
CDS_TEST = 2,
|
||||
CDS_FULLSCREEN = 4,
|
||||
CDS_GLOBAL = 8,
|
||||
CDS_SET_PRIMARY = 0x10,
|
||||
CDS_RESET = 0x40000000,
|
||||
CDS_NORESET = 0x10000000
|
||||
}
|
||||
|
||||
// PInvoke declaration for EnumDisplaySettings Win32 API
|
||||
[DllImport("user32.dll")]
|
||||
public static extern int EnumDisplaySettingsEx(
|
||||
string lpszDeviceName,
|
||||
int iModeNum,
|
||||
ref DEVMODE lpDevMode);
|
||||
|
||||
// PInvoke declaration for ChangeDisplaySettings Win32 API
|
||||
[DllImport("user32.dll")]
|
||||
public static extern int ChangeDisplaySettingsEx(
|
||||
string lpszDeviceName, ref DEVMODE lpDevMode, IntPtr hwnd,
|
||||
DisplaySettingsFlags dwflags, IntPtr lParam);
|
||||
|
||||
public static DEVMODE CreateDevmode()
|
||||
{
|
||||
DEVMODE dm = new DEVMODE();
|
||||
dm.dmDeviceName = new String(new char[32]);
|
||||
dm.dmFormName = new String(new char[32]);
|
||||
dm.dmSize = (short)Marshal.SizeOf(dm);
|
||||
return dm;
|
||||
}
|
||||
|
||||
public enum COLORPROFILETYPE
|
||||
{
|
||||
CPT_ICC,
|
||||
CPT_DMP,
|
||||
CPT_CAMP,
|
||||
CPT_GMMP
|
||||
}
|
||||
public enum COLORPROFILESUBTYPE
|
||||
{
|
||||
CPST_PERCEPTUAL,
|
||||
CPST_RELATIVE_COLORIMETRIC,
|
||||
CPST_SATURATION,
|
||||
CPST_ABSOLUTE_COLORIMETRIC,
|
||||
CPST_NONE,
|
||||
CPST_RGB_WORKING_SPACE,
|
||||
CPST_CUSTOM_WORKING_SPACE,
|
||||
CPST_STANDARD_DISPLAY_COLOR_MODE,
|
||||
CPST_EXTENDED_DISPLAY_COLOR_MODE
|
||||
}
|
||||
public enum WCS_PROFILE_MANAGEMENT_SCOPE
|
||||
{
|
||||
WCS_PROFILE_MANAGEMENT_SCOPE_SYSTEM_WIDE,
|
||||
WCS_PROFILE_MANAGEMENT_SCOPE_CURRENT_USER
|
||||
}
|
||||
|
||||
[DllImport("mscms.dll", CharSet = CharSet.Unicode)]
|
||||
public static extern bool WcsSetDefaultColorProfile(
|
||||
WCS_PROFILE_MANAGEMENT_SCOPE scope,
|
||||
string pDeviceName,
|
||||
COLORPROFILETYPE cptColorProfileType,
|
||||
COLORPROFILESUBTYPE cpstColorProfileSubType,
|
||||
uint dwProfileID,
|
||||
string pProfileName
|
||||
);
|
||||
|
||||
|
||||
public const int ENUM_CURRENT_SETTINGS = -1;
|
||||
public const string defaultDevice = "\\\\.\\DISPLAY1";
|
||||
|
||||
public static string? FindLaptopScreen()
|
||||
{
|
||||
string? laptopScreen = null;
|
||||
|
||||
try
|
||||
{
|
||||
var devices = GetAllDevices().ToArray();
|
||||
int count = 0, displayNum = -1;
|
||||
|
||||
string internalName = AppConfig.GetString("internal_display");
|
||||
|
||||
foreach (var device in devices)
|
||||
{
|
||||
if (device.outputTechnology == DISPLAYCONFIG_VIDEO_OUTPUT_TECHNOLOGY.DISPLAYCONFIG_OUTPUT_TECHNOLOGY_INTERNAL ||
|
||||
device.outputTechnology == DISPLAYCONFIG_VIDEO_OUTPUT_TECHNOLOGY.DISPLAYCONFIG_OUTPUT_TECHNOLOGY_DISPLAYPORT_EMBEDDED ||
|
||||
device.monitorFriendlyDeviceName == internalName)
|
||||
{
|
||||
displayNum = count;
|
||||
AppConfig.Set("internal_display", device.monitorFriendlyDeviceName);
|
||||
}
|
||||
count++;
|
||||
//Logger.WriteLine(device.monitorFriendlyDeviceName + ":" + device.outputTechnology.ToString());
|
||||
}
|
||||
|
||||
var screens = Screen.AllScreens;
|
||||
|
||||
if (screens.Length != count) return null;
|
||||
|
||||
count = 0;
|
||||
foreach (var screen in screens)
|
||||
{
|
||||
if (count == displayNum)
|
||||
{
|
||||
laptopScreen = screen.DeviceName;
|
||||
}
|
||||
//Logger.WriteLine(screen.DeviceName);
|
||||
count++;
|
||||
}
|
||||
|
||||
if (displayNum > 0 && count == 0) laptopScreen = defaultDevice;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.WriteLine(ex.ToString());
|
||||
Logger.WriteLine("Can't detect internal screen");
|
||||
laptopScreen = Screen.PrimaryScreen.DeviceName;
|
||||
}
|
||||
|
||||
|
||||
return laptopScreen;
|
||||
}
|
||||
|
||||
public static int GetRefreshRate(bool max = false)
|
||||
{
|
||||
DEVMODE dm = CreateDevmode();
|
||||
|
||||
string? laptopScreen = FindLaptopScreen();
|
||||
int frequency = -1;
|
||||
|
||||
if (laptopScreen is null)
|
||||
return -1;
|
||||
|
||||
if (max)
|
||||
{
|
||||
int i = 0;
|
||||
while (0 != EnumDisplaySettingsEx(laptopScreen, i, ref dm))
|
||||
{
|
||||
if (dm.dmDisplayFrequency > frequency) frequency = dm.dmDisplayFrequency;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (0 != EnumDisplaySettingsEx(laptopScreen, ENUM_CURRENT_SETTINGS, ref dm))
|
||||
{
|
||||
frequency = dm.dmDisplayFrequency;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return frequency;
|
||||
}
|
||||
|
||||
public static int SetRefreshRate(int frequency = 120)
|
||||
{
|
||||
DEVMODE dm = CreateDevmode();
|
||||
string? laptopScreen = FindLaptopScreen();
|
||||
|
||||
if (laptopScreen is null)
|
||||
return -1;
|
||||
|
||||
if (0 != EnumDisplaySettingsEx(laptopScreen, ENUM_CURRENT_SETTINGS, ref dm))
|
||||
{
|
||||
dm.dmDisplayFrequency = frequency;
|
||||
int iRet = ChangeDisplaySettingsEx(laptopScreen, ref dm, IntPtr.Zero, DisplaySettingsFlags.CDS_UPDATEREGISTRY, IntPtr.Zero);
|
||||
Logger.WriteLine("Screen = " + frequency.ToString() + "Hz : " + (iRet == 0 ? "OK" : iRet));
|
||||
|
||||
//Fallback scenario
|
||||
if (iRet != 0)
|
||||
{
|
||||
Thread.Sleep(300);
|
||||
iRet = ChangeDisplaySettingsEx(laptopScreen, ref dm, IntPtr.Zero, DisplaySettingsFlags.CDS_UPDATEREGISTRY, IntPtr.Zero);
|
||||
Logger.WriteLine("Screen = " + frequency.ToString() + "Hz : " + (iRet == 0 ? "OK" : iRet));
|
||||
}
|
||||
|
||||
return iRet;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
613
app/Extra.Designer.cs
generated
613
app/Extra.Designer.cs
generated
File diff suppressed because it is too large
Load Diff
240
app/Extra.cs
240
app/Extra.cs
@@ -1,5 +1,8 @@
|
||||
using CustomControls;
|
||||
using Microsoft.VisualBasic.Devices;
|
||||
using GHelper.Display;
|
||||
using GHelper.Gpu.AMD;
|
||||
using GHelper.Helpers;
|
||||
using GHelper.Input;
|
||||
using GHelper.UI;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace GHelper
|
||||
@@ -7,6 +10,8 @@ namespace GHelper
|
||||
public partial class Extra : RForm
|
||||
{
|
||||
|
||||
ScreenControl screenControl = new ScreenControl();
|
||||
|
||||
Dictionary<string, string> customActions = new Dictionary<string, string>
|
||||
{
|
||||
{"","--------------" },
|
||||
@@ -17,6 +22,9 @@ namespace GHelper
|
||||
{"performance", Properties.Strings.PerformanceMode},
|
||||
{"screen", Properties.Strings.ToggleScreen},
|
||||
{"miniled", Properties.Strings.ToggleMiniled},
|
||||
{"fnlock", Properties.Strings.ToggleFnLock},
|
||||
{"brightness_down", Properties.Strings.BrightnessDown},
|
||||
{"brightness_up", Properties.Strings.BrightnessUp},
|
||||
{"custom", Properties.Strings.Custom}
|
||||
};
|
||||
|
||||
@@ -41,6 +49,10 @@ namespace GHelper
|
||||
customActions[""] = Properties.Strings.ToggleAura;
|
||||
customActions.Remove("aura");
|
||||
break;
|
||||
case "fnc":
|
||||
customActions[""] = Properties.Strings.ToggleFnLock;
|
||||
customActions.Remove("fnlock");
|
||||
break;
|
||||
}
|
||||
|
||||
combo.DropDownStyle = ComboBoxStyle.DropDownList;
|
||||
@@ -48,7 +60,7 @@ namespace GHelper
|
||||
combo.DisplayMember = "Value";
|
||||
combo.ValueMember = "Key";
|
||||
|
||||
string action = AppConfig.getConfigString(name);
|
||||
string action = AppConfig.GetString(name);
|
||||
|
||||
combo.SelectedValue = (action is not null) ? action : "";
|
||||
if (combo.SelectedValue is null) combo.SelectedValue = "";
|
||||
@@ -56,17 +68,17 @@ namespace GHelper
|
||||
combo.SelectedValueChanged += delegate
|
||||
{
|
||||
if (combo.SelectedValue is not null)
|
||||
AppConfig.setConfig(name, combo.SelectedValue.ToString());
|
||||
AppConfig.Set(name, combo.SelectedValue.ToString());
|
||||
|
||||
if (name == "m1" || name == "m2")
|
||||
Program.inputDispatcher.RegisterKeys();
|
||||
|
||||
};
|
||||
|
||||
txbox.Text = AppConfig.getConfigString(name + "_custom");
|
||||
txbox.Text = AppConfig.GetString(name + "_custom");
|
||||
txbox.TextChanged += delegate
|
||||
{
|
||||
AppConfig.setConfig(name + "_custom", txbox.Text);
|
||||
AppConfig.Set(name + "_custom", txbox.Text);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -89,7 +101,6 @@ namespace GHelper
|
||||
labelBacklightTimeout.Text = Properties.Strings.BacklightTimeout;
|
||||
labelBacklightTimeoutPlugged.Text = Properties.Strings.BacklightTimeoutPlugged;
|
||||
|
||||
checkKeyboardAuto.Text = Properties.Strings.KeyboardAuto;
|
||||
checkNoOverdrive.Text = Properties.Strings.DisableOverdrive;
|
||||
checkTopmost.Text = Properties.Strings.WindowTop;
|
||||
checkUSBC.Text = Properties.Strings.OptimizedUSBC;
|
||||
@@ -112,6 +123,7 @@ namespace GHelper
|
||||
SetKeyCombo(comboM3, textM3, "m3");
|
||||
SetKeyCombo(comboM4, textM4, "m4");
|
||||
SetKeyCombo(comboFNF4, textFNF4, "fnf4");
|
||||
SetKeyCombo(comboFNC, textFNC, "fnc");
|
||||
|
||||
Shown += Keyboard_Shown;
|
||||
|
||||
@@ -123,28 +135,28 @@ namespace GHelper
|
||||
comboKeyboardSpeed.SelectedValueChanged += ComboKeyboardSpeed_SelectedValueChanged;
|
||||
|
||||
// Keyboard
|
||||
checkAwake.Checked = !(AppConfig.getConfig("keyboard_awake") == 0);
|
||||
checkBoot.Checked = !(AppConfig.getConfig("keyboard_boot") == 0);
|
||||
checkSleep.Checked = !(AppConfig.getConfig("keyboard_sleep") == 0);
|
||||
checkShutdown.Checked = !(AppConfig.getConfig("keyboard_shutdown") == 0);
|
||||
checkAwake.Checked = !(AppConfig.Get("keyboard_awake") == 0);
|
||||
checkBoot.Checked = !(AppConfig.Get("keyboard_boot") == 0);
|
||||
checkSleep.Checked = !(AppConfig.Get("keyboard_sleep") == 0);
|
||||
checkShutdown.Checked = !(AppConfig.Get("keyboard_shutdown") == 0);
|
||||
|
||||
// Lightbar
|
||||
checkAwakeBar.Checked = !(AppConfig.getConfig("keyboard_awake_bar") == 0);
|
||||
checkBootBar.Checked = !(AppConfig.getConfig("keyboard_boot_bar") == 0);
|
||||
checkSleepBar.Checked = !(AppConfig.getConfig("keyboard_sleep_bar") == 0);
|
||||
checkShutdownBar.Checked = !(AppConfig.getConfig("keyboard_shutdown_bar") == 0);
|
||||
checkAwakeBar.Checked = !(AppConfig.Get("keyboard_awake_bar") == 0);
|
||||
checkBootBar.Checked = !(AppConfig.Get("keyboard_boot_bar") == 0);
|
||||
checkSleepBar.Checked = !(AppConfig.Get("keyboard_sleep_bar") == 0);
|
||||
checkShutdownBar.Checked = !(AppConfig.Get("keyboard_shutdown_bar") == 0);
|
||||
|
||||
// Lid
|
||||
checkAwakeLid.Checked = !(AppConfig.getConfig("keyboard_awake_lid") == 0);
|
||||
checkBootLid.Checked = !(AppConfig.getConfig("keyboard_boot_lid") == 0);
|
||||
checkSleepLid.Checked = !(AppConfig.getConfig("keyboard_sleep_lid") == 0);
|
||||
checkShutdownLid.Checked = !(AppConfig.getConfig("keyboard_shutdown_lid") == 0);
|
||||
checkAwakeLid.Checked = !(AppConfig.Get("keyboard_awake_lid") == 0);
|
||||
checkBootLid.Checked = !(AppConfig.Get("keyboard_boot_lid") == 0);
|
||||
checkSleepLid.Checked = !(AppConfig.Get("keyboard_sleep_lid") == 0);
|
||||
checkShutdownLid.Checked = !(AppConfig.Get("keyboard_shutdown_lid") == 0);
|
||||
|
||||
// Logo
|
||||
checkAwakeLogo.Checked = !(AppConfig.getConfig("keyboard_awake_logo") == 0);
|
||||
checkBootLogo.Checked = !(AppConfig.getConfig("keyboard_boot_logo") == 0);
|
||||
checkSleepLogo.Checked = !(AppConfig.getConfig("keyboard_sleep_logo") == 0);
|
||||
checkShutdownLogo.Checked = !(AppConfig.getConfig("keyboard_shutdown_logo") == 0);
|
||||
checkAwakeLogo.Checked = !(AppConfig.Get("keyboard_awake_logo") == 0);
|
||||
checkBootLogo.Checked = !(AppConfig.Get("keyboard_boot_logo") == 0);
|
||||
checkSleepLogo.Checked = !(AppConfig.Get("keyboard_sleep_logo") == 0);
|
||||
checkShutdownLogo.Checked = !(AppConfig.Get("keyboard_shutdown_logo") == 0);
|
||||
|
||||
checkAwake.CheckedChanged += CheckPower_CheckedChanged;
|
||||
checkBoot.CheckedChanged += CheckPower_CheckedChanged;
|
||||
@@ -190,48 +202,135 @@ namespace GHelper
|
||||
}
|
||||
}
|
||||
|
||||
checkTopmost.Checked = (AppConfig.getConfig("topmost") == 1);
|
||||
checkTopmost.Checked = AppConfig.Is("topmost");
|
||||
checkTopmost.CheckedChanged += CheckTopmost_CheckedChanged; ;
|
||||
|
||||
checkKeyboardAuto.Checked = (AppConfig.getConfig("keyboard_auto") == 1);
|
||||
checkKeyboardAuto.CheckedChanged += CheckKeyboardAuto_CheckedChanged;
|
||||
|
||||
checkNoOverdrive.Checked = (AppConfig.getConfig("no_overdrive") == 1);
|
||||
checkNoOverdrive.Checked = AppConfig.Is("no_overdrive");
|
||||
checkNoOverdrive.CheckedChanged += CheckNoOverdrive_CheckedChanged;
|
||||
|
||||
checkUSBC.Checked = (AppConfig.getConfig("optimized_usbc") == 1);
|
||||
checkUSBC.Checked = AppConfig.Is("optimized_usbc");
|
||||
checkUSBC.CheckedChanged += CheckUSBC_CheckedChanged;
|
||||
|
||||
checkAutoApplyWindowsPowerMode.Checked = (AppConfig.getConfig("auto_apply_power_plan") != 0);
|
||||
checkAutoApplyWindowsPowerMode.Checked = (AppConfig.Get("auto_apply_power_plan") != 0);
|
||||
checkAutoApplyWindowsPowerMode.CheckedChanged += checkAutoApplyWindowsPowerMode_CheckedChanged;
|
||||
|
||||
int kb_brightness = AppConfig.getConfig("keyboard_brightness");
|
||||
trackBrightness.Value = (kb_brightness >= 0 && kb_brightness <= 3) ? kb_brightness : 3;
|
||||
|
||||
pictureHelp.Click += PictureHelp_Click;
|
||||
trackBrightness.Value = InputDispatcher.GetBacklight();
|
||||
trackBrightness.Scroll += TrackBrightness_Scroll;
|
||||
|
||||
panelXMG.Visible = (Program.acpi.DeviceGet(AsusACPI.GPUXGConnected) == 1);
|
||||
checkXMG.Checked = !(AppConfig.getConfig("xmg_light") == 0);
|
||||
checkXMG.Checked = !(AppConfig.Get("xmg_light") == 0);
|
||||
checkXMG.CheckedChanged += CheckXMG_CheckedChanged;
|
||||
|
||||
numericBacklightTime.Value = AppConfig.getConfig("keyboard_timeout", 60);
|
||||
numericBacklightPluggedTime.Value = AppConfig.getConfig("keyboard_ac_timeout", 0);
|
||||
numericBacklightTime.Value = AppConfig.Get("keyboard_timeout", 60);
|
||||
numericBacklightPluggedTime.Value = AppConfig.Get("keyboard_ac_timeout", 0);
|
||||
|
||||
numericBacklightTime.ValueChanged += NumericBacklightTime_ValueChanged;
|
||||
numericBacklightPluggedTime.ValueChanged += NumericBacklightTime_ValueChanged;
|
||||
|
||||
checkGpuApps.Checked = AppConfig.isConfig("kill_gpu_apps");
|
||||
checkGpuApps.Checked = AppConfig.Is("kill_gpu_apps");
|
||||
checkGpuApps.CheckedChanged += CheckGpuApps_CheckedChanged;
|
||||
|
||||
checkFnLock.Checked = AppConfig.isConfig("fn_lock");
|
||||
checkFnLock.Checked = AppConfig.Is("fn_lock");
|
||||
checkFnLock.CheckedChanged += CheckFnLock_CheckedChanged; ;
|
||||
|
||||
pictureHelp.Click += PictureHelp_Click;
|
||||
|
||||
buttonServices.Click += ButtonServices_Click;
|
||||
|
||||
InitVariBright();
|
||||
InitServices();
|
||||
}
|
||||
|
||||
|
||||
private void InitServices()
|
||||
{
|
||||
if (OptimizationService.IsRunning()) buttonServices.Text = Properties.Strings.Stop;
|
||||
else buttonServices.Text = Properties.Strings.Start;
|
||||
|
||||
labelServices.Text = Properties.Strings.AsusServicesRunning + ": " + OptimizationService.GetRunningCount();
|
||||
buttonServices.Enabled = true;
|
||||
|
||||
}
|
||||
|
||||
public void ServiesToggle()
|
||||
{
|
||||
buttonServices.Enabled = false;
|
||||
|
||||
if (OptimizationService.IsRunning())
|
||||
{
|
||||
labelServices.Text = Properties.Strings.StoppingServices + " ...";
|
||||
Task.Run(() =>
|
||||
{
|
||||
OptimizationService.StopAsusServices();
|
||||
BeginInvoke(delegate
|
||||
{
|
||||
InitServices();
|
||||
});
|
||||
Program.inputDispatcher.Init();
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
labelServices.Text = Properties.Strings.StartingServices + " ...";
|
||||
Task.Run(() =>
|
||||
{
|
||||
OptimizationService.StartAsusServices();
|
||||
BeginInvoke(delegate
|
||||
{
|
||||
InitServices();
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void ButtonServices_Click(object? sender, EventArgs e)
|
||||
{
|
||||
if (ProcessHelper.IsUserAdministrator())
|
||||
ServiesToggle();
|
||||
else
|
||||
ProcessHelper.RunAsAdmin("services");
|
||||
}
|
||||
|
||||
private void InitVariBright()
|
||||
{
|
||||
try
|
||||
{
|
||||
using (var amdControl = new AmdGpuControl())
|
||||
{
|
||||
int variBrightSupported = 0, VariBrightEnabled;
|
||||
if (amdControl.GetVariBright(out variBrightSupported, out VariBrightEnabled))
|
||||
{
|
||||
Logger.WriteLine("Varibright: " + variBrightSupported + "," + VariBrightEnabled);
|
||||
checkVariBright.Checked = (VariBrightEnabled == 3);
|
||||
}
|
||||
|
||||
checkVariBright.Visible = (variBrightSupported > 0);
|
||||
checkVariBright.CheckedChanged += CheckVariBright_CheckedChanged;
|
||||
}
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.WriteLine(ex.ToString());
|
||||
checkVariBright.Visible = false;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
private void CheckVariBright_CheckedChanged(object? sender, EventArgs e)
|
||||
{
|
||||
using (var amdControl = new AmdGpuControl())
|
||||
{
|
||||
amdControl.SetVariBright(checkVariBright.Checked ? 1 : 0);
|
||||
ProcessHelper.KillByName("RadeonSoftware");
|
||||
}
|
||||
}
|
||||
|
||||
private void CheckFnLock_CheckedChanged(object? sender, EventArgs e)
|
||||
{
|
||||
int fnLock = checkFnLock.Checked ? 1 : 0;
|
||||
AppConfig.setConfig("fn_lock", fnLock);
|
||||
AppConfig.Set("fn_lock", fnLock);
|
||||
Program.acpi.DeviceSet(AsusACPI.FnLock, (fnLock == 1) ? 0 : 1, "FnLock");
|
||||
|
||||
Program.inputDispatcher.RegisterKeys();
|
||||
@@ -239,31 +338,32 @@ namespace GHelper
|
||||
|
||||
private void CheckGpuApps_CheckedChanged(object? sender, EventArgs e)
|
||||
{
|
||||
AppConfig.setConfig("kill_gpu_apps", (checkGpuApps.Checked ? 1 : 0));
|
||||
AppConfig.Set("kill_gpu_apps", (checkGpuApps.Checked ? 1 : 0));
|
||||
}
|
||||
|
||||
private void NumericBacklightTime_ValueChanged(object? sender, EventArgs e)
|
||||
{
|
||||
AppConfig.setConfig("keyboard_timeout", (int)numericBacklightTime.Value);
|
||||
AppConfig.setConfig("keyboard_ac_timeout", (int)numericBacklightPluggedTime.Value);
|
||||
AppConfig.Set("keyboard_timeout", (int)numericBacklightTime.Value);
|
||||
AppConfig.Set("keyboard_ac_timeout", (int)numericBacklightPluggedTime.Value);
|
||||
Program.inputDispatcher.InitBacklightTimer();
|
||||
}
|
||||
|
||||
private void CheckXMG_CheckedChanged(object? sender, EventArgs e)
|
||||
{
|
||||
AppConfig.setConfig("xmg_light", (checkXMG.Checked ? 1 : 0));
|
||||
AppConfig.Set("xmg_light", (checkXMG.Checked ? 1 : 0));
|
||||
AsusUSB.ApplyXGMLight(checkXMG.Checked);
|
||||
}
|
||||
|
||||
private void CheckUSBC_CheckedChanged(object? sender, EventArgs e)
|
||||
{
|
||||
AppConfig.setConfig("optimized_usbc", (checkUSBC.Checked ? 1 : 0));
|
||||
AppConfig.Set("optimized_usbc", (checkUSBC.Checked ? 1 : 0));
|
||||
}
|
||||
|
||||
private void TrackBrightness_Scroll(object? sender, EventArgs e)
|
||||
{
|
||||
AppConfig.setConfig("keyboard_brightness", trackBrightness.Value);
|
||||
AsusUSB.ApplyBrightness(trackBrightness.Value);
|
||||
AppConfig.Set("keyboard_brightness", trackBrightness.Value);
|
||||
AppConfig.Set("keyboard_brightness_ac", trackBrightness.Value);
|
||||
AsusUSB.ApplyBrightness(trackBrightness.Value, "Slider");
|
||||
}
|
||||
|
||||
private void PictureHelp_Click(object? sender, EventArgs e)
|
||||
@@ -273,42 +373,38 @@ namespace GHelper
|
||||
|
||||
private void CheckNoOverdrive_CheckedChanged(object? sender, EventArgs e)
|
||||
{
|
||||
AppConfig.setConfig("no_overdrive", (checkNoOverdrive.Checked ? 1 : 0));
|
||||
Program.settingsForm.AutoScreen(true);
|
||||
AppConfig.Set("no_overdrive", (checkNoOverdrive.Checked ? 1 : 0));
|
||||
screenControl.AutoScreen(true);
|
||||
}
|
||||
|
||||
private void CheckKeyboardAuto_CheckedChanged(object? sender, EventArgs e)
|
||||
{
|
||||
AppConfig.setConfig("keyboard_auto", (checkKeyboardAuto.Checked ? 1 : 0));
|
||||
}
|
||||
|
||||
private void CheckTopmost_CheckedChanged(object? sender, EventArgs e)
|
||||
{
|
||||
AppConfig.setConfig("topmost", (checkTopmost.Checked ? 1 : 0));
|
||||
AppConfig.Set("topmost", (checkTopmost.Checked ? 1 : 0));
|
||||
Program.settingsForm.TopMost = checkTopmost.Checked;
|
||||
}
|
||||
|
||||
private void CheckPower_CheckedChanged(object? sender, EventArgs e)
|
||||
{
|
||||
AppConfig.setConfig("keyboard_awake", (checkAwake.Checked ? 1 : 0));
|
||||
AppConfig.setConfig("keyboard_boot", (checkBoot.Checked ? 1 : 0));
|
||||
AppConfig.setConfig("keyboard_sleep", (checkSleep.Checked ? 1 : 0));
|
||||
AppConfig.setConfig("keyboard_shutdown", (checkShutdown.Checked ? 1 : 0));
|
||||
AppConfig.Set("keyboard_awake", (checkAwake.Checked ? 1 : 0));
|
||||
AppConfig.Set("keyboard_boot", (checkBoot.Checked ? 1 : 0));
|
||||
AppConfig.Set("keyboard_sleep", (checkSleep.Checked ? 1 : 0));
|
||||
AppConfig.Set("keyboard_shutdown", (checkShutdown.Checked ? 1 : 0));
|
||||
|
||||
AppConfig.setConfig("keyboard_awake_bar", (checkAwakeBar.Checked ? 1 : 0));
|
||||
AppConfig.setConfig("keyboard_boot_bar", (checkBootBar.Checked ? 1 : 0));
|
||||
AppConfig.setConfig("keyboard_sleep_bar", (checkSleepBar.Checked ? 1 : 0));
|
||||
AppConfig.setConfig("keyboard_shutdown_bar", (checkShutdownBar.Checked ? 1 : 0));
|
||||
AppConfig.Set("keyboard_awake_bar", (checkAwakeBar.Checked ? 1 : 0));
|
||||
AppConfig.Set("keyboard_boot_bar", (checkBootBar.Checked ? 1 : 0));
|
||||
AppConfig.Set("keyboard_sleep_bar", (checkSleepBar.Checked ? 1 : 0));
|
||||
AppConfig.Set("keyboard_shutdown_bar", (checkShutdownBar.Checked ? 1 : 0));
|
||||
|
||||
AppConfig.setConfig("keyboard_awake_lid", (checkAwakeLid.Checked ? 1 : 0));
|
||||
AppConfig.setConfig("keyboard_boot_lid", (checkBootLid.Checked ? 1 : 0));
|
||||
AppConfig.setConfig("keyboard_sleep_lid", (checkSleepLid.Checked ? 1 : 0));
|
||||
AppConfig.setConfig("keyboard_shutdown_lid", (checkShutdownLid.Checked ? 1 : 0));
|
||||
AppConfig.Set("keyboard_awake_lid", (checkAwakeLid.Checked ? 1 : 0));
|
||||
AppConfig.Set("keyboard_boot_lid", (checkBootLid.Checked ? 1 : 0));
|
||||
AppConfig.Set("keyboard_sleep_lid", (checkSleepLid.Checked ? 1 : 0));
|
||||
AppConfig.Set("keyboard_shutdown_lid", (checkShutdownLid.Checked ? 1 : 0));
|
||||
|
||||
AppConfig.setConfig("keyboard_awake_logo", (checkAwakeLogo.Checked ? 1 : 0));
|
||||
AppConfig.setConfig("keyboard_boot_logo", (checkBootLogo.Checked ? 1 : 0));
|
||||
AppConfig.setConfig("keyboard_sleep_logo", (checkSleepLogo.Checked ? 1 : 0));
|
||||
AppConfig.setConfig("keyboard_shutdown_logo", (checkShutdownLogo.Checked ? 1 : 0));
|
||||
AppConfig.Set("keyboard_awake_logo", (checkAwakeLogo.Checked ? 1 : 0));
|
||||
AppConfig.Set("keyboard_boot_logo", (checkBootLogo.Checked ? 1 : 0));
|
||||
AppConfig.Set("keyboard_sleep_logo", (checkSleepLogo.Checked ? 1 : 0));
|
||||
AppConfig.Set("keyboard_shutdown_logo", (checkShutdownLogo.Checked ? 1 : 0));
|
||||
|
||||
List<AuraDev19b6> flags = new List<AuraDev19b6>();
|
||||
|
||||
@@ -338,7 +434,7 @@ namespace GHelper
|
||||
|
||||
private void ComboKeyboardSpeed_SelectedValueChanged(object? sender, EventArgs e)
|
||||
{
|
||||
AppConfig.setConfig("aura_speed", (int)comboKeyboardSpeed.SelectedValue);
|
||||
AppConfig.Set("aura_speed", (int)comboKeyboardSpeed.SelectedValue);
|
||||
Program.settingsForm.SetAura();
|
||||
}
|
||||
|
||||
@@ -359,7 +455,7 @@ namespace GHelper
|
||||
|
||||
private void checkAutoApplyWindowsPowerMode_CheckedChanged(object? sender, EventArgs e)
|
||||
{
|
||||
AppConfig.setConfig("auto_apply_power_plan", checkAutoApplyWindowsPowerMode.Checked ? 1 : 0);
|
||||
AppConfig.Set("auto_apply_power_plan", checkAutoApplyWindowsPowerMode.Checked ? 1 : 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
961
app/Fans.Designer.cs
generated
961
app/Fans.Designer.cs
generated
File diff suppressed because it is too large
Load Diff
464
app/Fans.cs
464
app/Fans.cs
@@ -1,5 +1,7 @@
|
||||
using CustomControls;
|
||||
using GHelper.Gpu;
|
||||
using GHelper.Gpu.NVidia;
|
||||
using GHelper.Mode;
|
||||
using GHelper.UI;
|
||||
using Ryzen;
|
||||
using System.Diagnostics;
|
||||
using System.Windows.Forms.DataVisualization.Charting;
|
||||
|
||||
@@ -8,7 +10,9 @@ namespace GHelper
|
||||
public partial class Fans : RForm
|
||||
{
|
||||
|
||||
DataPoint curPoint = null;
|
||||
int curIndex = -1;
|
||||
DataPoint? curPoint = null;
|
||||
|
||||
Series seriesCPU;
|
||||
Series seriesGPU;
|
||||
Series seriesMid;
|
||||
@@ -16,20 +20,24 @@ namespace GHelper
|
||||
|
||||
static int MinRPM, MaxRPM;
|
||||
|
||||
static bool powerVisible = true, gpuVisible = true;
|
||||
static bool gpuVisible = true;
|
||||
|
||||
const int fansMax = 100;
|
||||
|
||||
NvidiaGpuControl? nvControl = null;
|
||||
ModeControl modeControl = Program.modeControl;
|
||||
|
||||
public Fans()
|
||||
{
|
||||
|
||||
InitializeComponent();
|
||||
|
||||
//float dpi = ControlHelper.GetDpiScale(this).Value;
|
||||
//comboModes.Size = new Size(comboModes.Width, (int)dpi * 18);
|
||||
comboModes.ClientSize = new Size(comboModes.Width, comboModes.Height - 4);
|
||||
|
||||
Text = Properties.Strings.FansAndPower;
|
||||
labelPowerLimits.Text = Properties.Strings.PowerLimits;
|
||||
labelInfo.Text = Properties.Strings.PPTExperimental;
|
||||
checkApplyPower.Text = Properties.Strings.ApplyPowerLimits;
|
||||
|
||||
labelFans.Text = Properties.Strings.FanCurves;
|
||||
@@ -44,7 +52,9 @@ namespace GHelper
|
||||
labelGPUBoostTitle.Text = Properties.Strings.GPUBoost;
|
||||
labelGPUTempTitle.Text = Properties.Strings.GPUTempTarget;
|
||||
|
||||
InitTheme();
|
||||
labelRisky.Text = Properties.Strings.UndervoltingRisky;
|
||||
|
||||
InitTheme(true);
|
||||
|
||||
MinRPM = 18;
|
||||
MaxRPM = HardwareControl.GetFanMax();
|
||||
@@ -121,34 +131,268 @@ namespace GHelper
|
||||
trackGPUTemp.MouseUp += TrackGPU_MouseUp;
|
||||
|
||||
//labelInfo.MaximumSize = new Size(280, 0);
|
||||
labelInfo.Text = Properties.Strings.PPTExperimental;
|
||||
labelFansResult.Visible = false;
|
||||
|
||||
InitFans();
|
||||
InitPower();
|
||||
InitBoost();
|
||||
InitGPU(true);
|
||||
|
||||
trackUV.Minimum = RyzenControl.MinCPUUV;
|
||||
trackUV.Maximum = RyzenControl.MaxCPUUV;
|
||||
|
||||
trackUViGPU.Minimum = RyzenControl.MinIGPUUV;
|
||||
trackUViGPU.Maximum = RyzenControl.MaxIGPUUV;
|
||||
|
||||
trackTemp.Minimum = RyzenControl.MinTemp;
|
||||
trackTemp.Maximum = RyzenControl.MaxTemp;
|
||||
|
||||
|
||||
FillModes();
|
||||
InitAll();
|
||||
|
||||
comboBoost.SelectedValueChanged += ComboBoost_Changed;
|
||||
|
||||
comboModes.SelectionChangeCommitted += ComboModes_SelectedValueChanged;
|
||||
comboModes.TextChanged += ComboModes_TextChanged;
|
||||
comboModes.KeyPress += ComboModes_KeyPress;
|
||||
|
||||
Shown += Fans_Shown;
|
||||
|
||||
buttonAdd.Click += ButtonAdd_Click;
|
||||
buttonRemove.Click += ButtonRemove_Click;
|
||||
buttonRename.Click += ButtonRename_Click;
|
||||
|
||||
|
||||
trackUV.Scroll += TrackUV_Scroll;
|
||||
trackUViGPU.Scroll += TrackUV_Scroll;
|
||||
trackTemp.Scroll += TrackUV_Scroll;
|
||||
|
||||
buttonApplyAdvanced.Click += ButtonApplyAdvanced_Click;
|
||||
|
||||
buttonCPU.BorderColor = colorStandard;
|
||||
buttonGPU.BorderColor = colorTurbo;
|
||||
buttonAdvanced.BorderColor = Color.Gray;
|
||||
|
||||
buttonCPU.Click += ButtonCPU_Click;
|
||||
buttonGPU.Click += ButtonGPU_Click;
|
||||
buttonAdvanced.Click += ButtonAdvanced_Click;
|
||||
|
||||
checkApplyUV.Click += CheckApplyUV_Click;
|
||||
|
||||
ToggleNavigation(0);
|
||||
|
||||
FormClosed += Fans_FormClosed;
|
||||
|
||||
}
|
||||
|
||||
private void Fans_FormClosed(object? sender, FormClosedEventArgs e)
|
||||
{
|
||||
//Because windows charts seem to eat a lot of memory :(
|
||||
GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced);
|
||||
}
|
||||
|
||||
private void CheckApplyUV_Click(object? sender, EventArgs e)
|
||||
{
|
||||
AppConfig.SetMode("auto_uv", checkApplyUV.Checked ? 1 : 0);
|
||||
modeControl.AutoRyzen();
|
||||
}
|
||||
|
||||
public void InitAll()
|
||||
{
|
||||
InitMode();
|
||||
InitFans();
|
||||
InitPower();
|
||||
InitBoost();
|
||||
InitUV();
|
||||
InitGPU();
|
||||
}
|
||||
|
||||
public void ToggleNavigation(int index = 0)
|
||||
{
|
||||
|
||||
SuspendLayout();
|
||||
|
||||
buttonCPU.Activated = false;
|
||||
buttonGPU.Activated = false;
|
||||
buttonAdvanced.Activated = false;
|
||||
|
||||
panelPower.Visible = false;
|
||||
panelGPU.Visible = false;
|
||||
panelAdvanced.Visible = false;
|
||||
|
||||
switch (index)
|
||||
{
|
||||
case 1:
|
||||
buttonGPU.Activated = true;
|
||||
panelGPU.Visible = true;
|
||||
break;
|
||||
case 2:
|
||||
buttonAdvanced.Activated = true;
|
||||
panelAdvanced.Visible = true;
|
||||
break;
|
||||
default:
|
||||
buttonCPU.Activated = true;
|
||||
panelPower.Visible = true;
|
||||
break;
|
||||
}
|
||||
|
||||
ResumeLayout(false);
|
||||
PerformLayout();
|
||||
}
|
||||
|
||||
private void ButtonAdvanced_Click(object? sender, EventArgs e)
|
||||
{
|
||||
ToggleNavigation(2);
|
||||
}
|
||||
|
||||
private void ButtonGPU_Click(object? sender, EventArgs e)
|
||||
{
|
||||
ToggleNavigation(1);
|
||||
}
|
||||
|
||||
private void ButtonCPU_Click(object? sender, EventArgs e)
|
||||
{
|
||||
ToggleNavigation(0);
|
||||
}
|
||||
|
||||
private void ButtonApplyAdvanced_Click(object? sender, EventArgs e)
|
||||
{
|
||||
modeControl.SetRyzen(true);
|
||||
checkApplyUV.Enabled = true;
|
||||
}
|
||||
|
||||
public void InitUV()
|
||||
{
|
||||
|
||||
//if (!ProcessHelper.IsUserAdministrator()) return;
|
||||
|
||||
int cpuUV = Math.Max(trackUV.Minimum, Math.Min(trackUV.Maximum, AppConfig.GetMode("cpu_uv", 0)));
|
||||
int igpuUV = Math.Max(trackUViGPU.Minimum, Math.Min(trackUViGPU.Maximum, AppConfig.GetMode("igpu_uv", 0)));
|
||||
|
||||
int temp = AppConfig.GetMode("cpu_temp");
|
||||
if (temp < RyzenControl.MinTemp || temp > RyzenControl.MaxTemp) temp = RyzenControl.MaxTemp;
|
||||
|
||||
checkApplyUV.Enabled = checkApplyUV.Checked = AppConfig.IsMode("auto_uv");
|
||||
|
||||
trackUV.Value = cpuUV;
|
||||
trackUViGPU.Value = igpuUV;
|
||||
trackTemp.Value = temp;
|
||||
|
||||
VisualiseAdvanced();
|
||||
|
||||
buttonAdvanced.Visible = RyzenControl.IsAMD();
|
||||
|
||||
}
|
||||
|
||||
private void VisualiseAdvanced()
|
||||
{
|
||||
labelUV.Text = trackUV.Value.ToString();
|
||||
labelUViGPU.Text = trackUViGPU.Value.ToString();
|
||||
labelTemp.Text = (trackTemp.Value < RyzenControl.MaxTemp) ? trackTemp.Value.ToString() + "°C" : "Default";
|
||||
}
|
||||
|
||||
private void AdvancedScroll()
|
||||
{
|
||||
AppConfig.SetMode("auto_uv", 0);
|
||||
checkApplyUV.Enabled = checkApplyUV.Checked = false;
|
||||
|
||||
VisualiseAdvanced();
|
||||
|
||||
AppConfig.SetMode("cpu_temp", trackTemp.Value);
|
||||
AppConfig.SetMode("cpu_uv", trackUV.Value);
|
||||
AppConfig.SetMode("igpu_uv", trackUViGPU.Value);
|
||||
}
|
||||
|
||||
|
||||
private void TrackUV_Scroll(object? sender, EventArgs e)
|
||||
{
|
||||
AdvancedScroll();
|
||||
}
|
||||
|
||||
private void ComboModes_KeyPress(object? sender, KeyPressEventArgs e)
|
||||
{
|
||||
if (e.KeyChar == 13) RenameToggle();
|
||||
}
|
||||
|
||||
private void ComboModes_TextChanged(object? sender, EventArgs e)
|
||||
{
|
||||
if (comboModes.DropDownStyle == ComboBoxStyle.DropDownList) return;
|
||||
if (!Modes.IsCurrentCustom()) return;
|
||||
AppConfig.SetMode("mode_name", comboModes.Text);
|
||||
}
|
||||
|
||||
private void RenameToggle()
|
||||
{
|
||||
if (comboModes.DropDownStyle == ComboBoxStyle.DropDownList)
|
||||
comboModes.DropDownStyle = ComboBoxStyle.Simple;
|
||||
else
|
||||
{
|
||||
var mode = Modes.GetCurrent();
|
||||
FillModes();
|
||||
comboModes.SelectedValue = mode;
|
||||
}
|
||||
}
|
||||
|
||||
private void ButtonRename_Click(object? sender, EventArgs e)
|
||||
{
|
||||
RenameToggle();
|
||||
}
|
||||
|
||||
private void ButtonRemove_Click(object? sender, EventArgs e)
|
||||
{
|
||||
int mode = Modes.GetCurrent();
|
||||
if (!Modes.IsCurrentCustom()) return;
|
||||
|
||||
Modes.Remove(mode);
|
||||
FillModes();
|
||||
|
||||
modeControl.SetPerformanceMode(AsusACPI.PerformanceBalanced);
|
||||
|
||||
}
|
||||
|
||||
private void FillModes()
|
||||
{
|
||||
comboModes.DropDownStyle = ComboBoxStyle.DropDownList;
|
||||
comboModes.DataSource = new BindingSource(Modes.GetDictonary(), null);
|
||||
comboModes.DisplayMember = "Value";
|
||||
comboModes.ValueMember = "Key";
|
||||
}
|
||||
|
||||
private void ButtonAdd_Click(object? sender, EventArgs e)
|
||||
{
|
||||
int mode = Modes.Add();
|
||||
FillModes();
|
||||
modeControl.SetPerformanceMode(mode);
|
||||
}
|
||||
|
||||
public void InitMode()
|
||||
{
|
||||
int mode = Modes.GetCurrent();
|
||||
comboModes.SelectedValue = mode;
|
||||
buttonRename.Visible = buttonRemove.Visible = Modes.IsCurrentCustom();
|
||||
}
|
||||
|
||||
private void ComboModes_SelectedValueChanged(object? sender, EventArgs e)
|
||||
{
|
||||
var selectedMode = comboModes.SelectedValue;
|
||||
|
||||
if (selectedMode == null) return;
|
||||
if ((int)selectedMode == Modes.GetCurrent()) return;
|
||||
|
||||
Debug.WriteLine(selectedMode);
|
||||
|
||||
modeControl.SetPerformanceMode((int)selectedMode);
|
||||
}
|
||||
|
||||
private void TrackGPU_MouseUp(object? sender, MouseEventArgs e)
|
||||
{
|
||||
Program.settingsForm.SetGPUPower();
|
||||
Program.settingsForm.SetGPUClocks(true);
|
||||
modeControl.SetGPUPower();
|
||||
modeControl.SetGPUClocks(true);
|
||||
}
|
||||
|
||||
public void InitGPU(bool readClocks = false)
|
||||
public void InitGPU()
|
||||
{
|
||||
|
||||
if (Program.acpi.DeviceGet(AsusACPI.GPUEco) == 1)
|
||||
{
|
||||
gpuVisible = panelGPU.Visible = false;
|
||||
gpuVisible = buttonGPU.Visible = false;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -160,18 +404,18 @@ namespace GHelper
|
||||
}
|
||||
else
|
||||
{
|
||||
gpuVisible = panelGPU.Visible = false;
|
||||
gpuVisible = buttonGPU.Visible = false;
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
gpuVisible = panelGPU.Visible = true;
|
||||
gpuVisible = buttonGPU.Visible = true;
|
||||
|
||||
int gpu_boost = AppConfig.getConfigPerf("gpu_boost");
|
||||
int gpu_temp = AppConfig.getConfigPerf("gpu_temp");
|
||||
int core = AppConfig.getConfigPerf("gpu_core");
|
||||
int memory = AppConfig.getConfigPerf("gpu_memory");
|
||||
int gpu_boost = AppConfig.GetMode("gpu_boost");
|
||||
int gpu_temp = AppConfig.GetMode("gpu_temp");
|
||||
int core = AppConfig.GetMode("gpu_core");
|
||||
int memory = AppConfig.GetMode("gpu_memory");
|
||||
|
||||
if (gpu_boost < 0) gpu_boost = AsusACPI.MaxGPUBoost;
|
||||
if (gpu_temp < 0) gpu_temp = AsusACPI.MaxGPUTemp;
|
||||
@@ -214,7 +458,7 @@ namespace GHelper
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.WriteLine(ex.ToString());
|
||||
gpuVisible = panelGPU.Visible = false;
|
||||
gpuVisible = buttonGPU.Visible = false;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -233,8 +477,8 @@ namespace GHelper
|
||||
TrackBar track = (TrackBar)sender;
|
||||
track.Value = (int)Math.Round((float)track.Value / 5) * 5;
|
||||
|
||||
AppConfig.setConfigPerf("gpu_core", trackGPUCore.Value);
|
||||
AppConfig.setConfigPerf("gpu_memory", trackGPUMemory.Value);
|
||||
AppConfig.SetMode("gpu_core", trackGPUCore.Value);
|
||||
AppConfig.SetMode("gpu_memory", trackGPUMemory.Value);
|
||||
|
||||
VisualiseGPUSettings();
|
||||
|
||||
@@ -242,8 +486,8 @@ namespace GHelper
|
||||
|
||||
private void trackGPUPower_Scroll(object? sender, EventArgs e)
|
||||
{
|
||||
AppConfig.setConfigPerf("gpu_boost", trackGPUBoost.Value);
|
||||
AppConfig.setConfigPerf("gpu_temp", trackGPUTemp.Value);
|
||||
AppConfig.SetMode("gpu_boost", trackGPUBoost.Value);
|
||||
AppConfig.SetMode("gpu_temp", trackGPUTemp.Value);
|
||||
|
||||
VisualiseGPUSettings();
|
||||
}
|
||||
@@ -276,9 +520,6 @@ namespace GHelper
|
||||
break;
|
||||
}
|
||||
|
||||
if (Program.settingsForm.perfName.Length > 0)
|
||||
labelFans.Text = Properties.Strings.FanProfiles + ": " + Program.settingsForm.perfName;
|
||||
|
||||
chart.Titles[0].Text = title;
|
||||
|
||||
chart.ChartAreas[0].AxisX.Minimum = 10;
|
||||
@@ -309,8 +550,6 @@ namespace GHelper
|
||||
|
||||
public void FormPosition()
|
||||
{
|
||||
panelSliders.Visible = gpuVisible || powerVisible;
|
||||
|
||||
if (Height > Program.settingsForm.Height)
|
||||
{
|
||||
Top = Program.settingsForm.Top + Program.settingsForm.Height - Height;
|
||||
@@ -333,41 +572,33 @@ namespace GHelper
|
||||
|
||||
private void TrackPower_MouseUp(object? sender, MouseEventArgs e)
|
||||
{
|
||||
Program.settingsForm.AutoPower();
|
||||
modeControl.AutoPower();
|
||||
}
|
||||
|
||||
|
||||
public void InitBoost()
|
||||
{
|
||||
int boost = NativeMethods.GetCPUBoost();
|
||||
int boost = PowerNative.GetCPUBoost();
|
||||
if (boost >= 0)
|
||||
comboBoost.SelectedIndex = Math.Min(boost, comboBoost.Items.Count - 1);
|
||||
}
|
||||
|
||||
private void ComboBoost_Changed(object? sender, EventArgs e)
|
||||
{
|
||||
if (AppConfig.getConfigPerf("auto_boost") != comboBoost.SelectedIndex)
|
||||
if (AppConfig.GetMode("auto_boost") != comboBoost.SelectedIndex)
|
||||
{
|
||||
NativeMethods.SetCPUBoost(comboBoost.SelectedIndex);
|
||||
AppConfig.setConfigPerf("auto_boost", comboBoost.SelectedIndex);
|
||||
PowerNative.SetCPUBoost(comboBoost.SelectedIndex);
|
||||
}
|
||||
AppConfig.SetMode("auto_boost", comboBoost.SelectedIndex);
|
||||
}
|
||||
|
||||
private void CheckApplyPower_Click(object? sender, EventArgs e)
|
||||
{
|
||||
if (sender is null) return;
|
||||
CheckBox chk = (CheckBox)sender;
|
||||
AppConfig.setConfigPerf("auto_apply_power", chk.Checked ? 1 : 0);
|
||||
|
||||
if (chk.Checked)
|
||||
{
|
||||
Program.settingsForm.AutoPower();
|
||||
}
|
||||
else
|
||||
{
|
||||
Program.acpi.DeviceSet(AsusACPI.PerformanceMode, AppConfig.getConfig("performance_mode"), "PerfMode");
|
||||
Program.settingsForm.AutoFans();
|
||||
}
|
||||
AppConfig.SetMode("auto_apply_power", chk.Checked ? 1 : 0);
|
||||
modeControl.SetPerformanceMode();
|
||||
|
||||
}
|
||||
|
||||
@@ -376,17 +607,9 @@ namespace GHelper
|
||||
if (sender is null) return;
|
||||
CheckBox chk = (CheckBox)sender;
|
||||
|
||||
AppConfig.setConfigPerf("auto_apply", chk.Checked ? 1 : 0);
|
||||
AppConfig.SetMode("auto_apply", chk.Checked ? 1 : 0);
|
||||
modeControl.SetPerformanceMode();
|
||||
|
||||
if (chk.Checked)
|
||||
{
|
||||
Program.settingsForm.AutoFans();
|
||||
}
|
||||
else
|
||||
{
|
||||
Program.acpi.DeviceSet(AsusACPI.PerformanceMode, AppConfig.getConfig("performance_mode"), "PerfMode");
|
||||
Program.settingsForm.AutoPower();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -411,13 +634,15 @@ namespace GHelper
|
||||
public void InitPower(bool changed = false)
|
||||
{
|
||||
|
||||
bool modeA0 = Program.acpi.DeviceGet(AsusACPI.PPT_TotalA0) >= 0;
|
||||
bool modeA0 = (Program.acpi.DeviceGet(AsusACPI.PPT_TotalA0) >= 0 || RyzenControl.IsAMD());
|
||||
bool modeB0 = Program.acpi.IsAllAmdPPT();
|
||||
bool modeC1 = Program.acpi.DeviceGet(AsusACPI.PPT_APUC1) >= 0;
|
||||
|
||||
powerVisible = panelPower.Visible = modeA0;
|
||||
panelA0.Visible = modeA0;
|
||||
panelB0.Visible = modeB0;
|
||||
|
||||
panelApplyPower.Visible = panelTitleCPU.Visible = modeA0 || modeB0 || modeC1;
|
||||
|
||||
|
||||
// All AMD version has B0 but doesn't have C0 (Nvidia GPU) settings
|
||||
if (modeB0)
|
||||
@@ -437,7 +662,7 @@ namespace GHelper
|
||||
int limit_cpu;
|
||||
int limit_fast;
|
||||
|
||||
bool apply = AppConfig.getConfigPerf("auto_apply_power") == 1;
|
||||
bool apply = AppConfig.IsMode("auto_apply_power");
|
||||
|
||||
if (changed)
|
||||
{
|
||||
@@ -447,9 +672,9 @@ namespace GHelper
|
||||
}
|
||||
else
|
||||
{
|
||||
limit_total = AppConfig.getConfigPerf("limit_total");
|
||||
limit_cpu = AppConfig.getConfigPerf("limit_cpu");
|
||||
limit_fast = AppConfig.getConfigPerf("limit_fast");
|
||||
limit_total = AppConfig.GetMode("limit_total");
|
||||
limit_cpu = AppConfig.GetMode("limit_cpu");
|
||||
limit_fast = AppConfig.GetMode("limit_fast");
|
||||
}
|
||||
|
||||
if (limit_total < 0) limit_total = AsusACPI.DefaultTotal;
|
||||
@@ -475,9 +700,9 @@ namespace GHelper
|
||||
labelB0.Text = trackB0.Value.ToString() + "W";
|
||||
labelC1.Text = trackC1.Value.ToString() + "W";
|
||||
|
||||
AppConfig.setConfigPerf("limit_total", limit_total);
|
||||
AppConfig.setConfigPerf("limit_cpu", limit_cpu);
|
||||
AppConfig.setConfigPerf("limit_fast", limit_fast);
|
||||
AppConfig.SetMode("limit_total", limit_total);
|
||||
AppConfig.SetMode("limit_cpu", limit_cpu);
|
||||
AppConfig.SetMode("limit_fast", limit_fast);
|
||||
|
||||
|
||||
}
|
||||
@@ -497,7 +722,7 @@ namespace GHelper
|
||||
// Middle / system fan check
|
||||
if (!AsusACPI.IsEmptyCurve(Program.acpi.GetFanCurve(AsusFan.Mid)))
|
||||
{
|
||||
AppConfig.setConfig("mid_fan", 1);
|
||||
AppConfig.Set("mid_fan", 1);
|
||||
chartCount++;
|
||||
chartMid.Visible = true;
|
||||
SetChart(chartMid, AsusFan.Mid);
|
||||
@@ -505,13 +730,13 @@ namespace GHelper
|
||||
}
|
||||
else
|
||||
{
|
||||
AppConfig.setConfig("mid_fan", 0);
|
||||
AppConfig.Set("mid_fan", 0);
|
||||
}
|
||||
|
||||
// XG Mobile Fan check
|
||||
if (Program.acpi.IsXGConnected())
|
||||
{
|
||||
AppConfig.setConfig("xgm_fan", 1);
|
||||
AppConfig.Set("xgm_fan", 1);
|
||||
chartCount++;
|
||||
chartXGM.Visible = true;
|
||||
SetChart(chartXGM, AsusFan.XGM);
|
||||
@@ -519,7 +744,7 @@ namespace GHelper
|
||||
}
|
||||
else
|
||||
{
|
||||
AppConfig.setConfig("xgm_fan", 0);
|
||||
AppConfig.Set("xgm_fan", 0);
|
||||
}
|
||||
|
||||
try
|
||||
@@ -539,9 +764,7 @@ namespace GHelper
|
||||
LoadProfile(seriesCPU, AsusFan.CPU);
|
||||
LoadProfile(seriesGPU, AsusFan.GPU);
|
||||
|
||||
int auto_apply = AppConfig.getConfigPerf("auto_apply");
|
||||
|
||||
checkApplyFans.Checked = (auto_apply == 1);
|
||||
checkApplyFans.Checked = AppConfig.IsMode("auto_apply");
|
||||
|
||||
}
|
||||
|
||||
@@ -555,15 +778,14 @@ namespace GHelper
|
||||
|
||||
series.Points.Clear();
|
||||
|
||||
int mode = AppConfig.getConfig("performance_mode");
|
||||
byte[] curve = AppConfig.getFanConfig(device);
|
||||
byte[] curve = AppConfig.GetFanConfig(device);
|
||||
|
||||
if (reset || AsusACPI.IsInvalidCurve(curve))
|
||||
{
|
||||
curve = Program.acpi.GetFanCurve(device, mode);
|
||||
curve = Program.acpi.GetFanCurve(device, Modes.GetCurrentBase());
|
||||
|
||||
if (AsusACPI.IsInvalidCurve(curve))
|
||||
curve = AppConfig.getDefaultCurve(device);
|
||||
curve = AppConfig.GetDefaultCurve(device);
|
||||
|
||||
curve = AsusACPI.FixFanCurve(curve);
|
||||
|
||||
@@ -594,7 +816,7 @@ namespace GHelper
|
||||
i++;
|
||||
}
|
||||
|
||||
AppConfig.setFanConfig(device, curve);
|
||||
AppConfig.SetFanConfig(device, curve);
|
||||
//Program.wmi.SetFanCurve(device, curve);
|
||||
|
||||
}
|
||||
@@ -606,51 +828,66 @@ namespace GHelper
|
||||
LoadProfile(seriesCPU, AsusFan.CPU, true);
|
||||
LoadProfile(seriesGPU, AsusFan.GPU, true);
|
||||
|
||||
if (AppConfig.isConfig("mid_fan"))
|
||||
if (AppConfig.Is("mid_fan"))
|
||||
LoadProfile(seriesMid, AsusFan.Mid, true);
|
||||
|
||||
if (AppConfig.isConfig("xgm_fan"))
|
||||
if (AppConfig.Is("xgm_fan"))
|
||||
LoadProfile(seriesXGM, AsusFan.XGM, true);
|
||||
|
||||
checkApplyFans.Checked = false;
|
||||
checkApplyPower.Checked = false;
|
||||
|
||||
AppConfig.setConfigPerf("auto_apply", 0);
|
||||
AppConfig.setConfigPerf("auto_apply_power", 0);
|
||||
AppConfig.SetMode("auto_apply", 0);
|
||||
AppConfig.SetMode("auto_apply_power", 0);
|
||||
|
||||
Program.acpi.DeviceSet(AsusACPI.PerformanceMode, AppConfig.getConfig("performance_mode"), "PerfMode");
|
||||
trackUV.Value = RyzenControl.MaxCPUUV;
|
||||
trackUViGPU.Value = RyzenControl.MaxIGPUUV;
|
||||
trackTemp.Value = RyzenControl.MaxTemp;
|
||||
|
||||
AdvancedScroll();
|
||||
AppConfig.SetMode("cpu_temp", -1);
|
||||
|
||||
modeControl.ResetPerformanceMode();
|
||||
|
||||
if (Program.acpi.IsXGConnected()) AsusUSB.ResetXGM();
|
||||
|
||||
trackGPUCore.Value = 0;
|
||||
trackGPUMemory.Value = 0;
|
||||
trackGPUBoost.Value = AsusACPI.MaxGPUBoost;
|
||||
trackGPUTemp.Value = AsusACPI.MaxGPUTemp;
|
||||
|
||||
AppConfig.setConfigPerf("gpu_boost", trackGPUBoost.Value);
|
||||
AppConfig.setConfigPerf("gpu_temp", trackGPUTemp.Value);
|
||||
AppConfig.setConfigPerf("gpu_core", trackGPUCore.Value);
|
||||
AppConfig.setConfigPerf("gpu_memory", trackGPUMemory.Value);
|
||||
VisualiseGPUSettings();
|
||||
if (gpuVisible)
|
||||
{
|
||||
trackGPUCore.Value = 0;
|
||||
trackGPUMemory.Value = 0;
|
||||
trackGPUBoost.Value = AsusACPI.MaxGPUBoost;
|
||||
trackGPUTemp.Value = AsusACPI.MaxGPUTemp;
|
||||
|
||||
AppConfig.SetMode("gpu_boost", trackGPUBoost.Value);
|
||||
AppConfig.SetMode("gpu_temp", trackGPUTemp.Value);
|
||||
AppConfig.SetMode("gpu_core", trackGPUCore.Value);
|
||||
AppConfig.SetMode("gpu_memory", trackGPUMemory.Value);
|
||||
|
||||
VisualiseGPUSettings();
|
||||
modeControl.SetGPUClocks(true);
|
||||
modeControl.SetGPUPower();
|
||||
}
|
||||
|
||||
Program.settingsForm.SetGPUClocks(true);
|
||||
Program.settingsForm.SetGPUPower();
|
||||
}
|
||||
|
||||
private void ChartCPU_MouseUp(object? sender, MouseEventArgs e)
|
||||
{
|
||||
curPoint = null;
|
||||
curIndex = -1;
|
||||
|
||||
labelTip.Visible = false;
|
||||
|
||||
SaveProfile(seriesCPU, AsusFan.CPU);
|
||||
SaveProfile(seriesGPU, AsusFan.GPU);
|
||||
|
||||
if (AppConfig.isConfig("mid_fan"))
|
||||
if (AppConfig.Is("mid_fan"))
|
||||
SaveProfile(seriesMid, AsusFan.Mid);
|
||||
|
||||
if (AppConfig.isConfig("xgm_fan"))
|
||||
if (AppConfig.Is("xgm_fan"))
|
||||
SaveProfile(seriesXGM, AsusFan.XGM);
|
||||
|
||||
Program.settingsForm.AutoFans();
|
||||
modeControl.AutoFans();
|
||||
|
||||
|
||||
}
|
||||
@@ -668,9 +905,12 @@ namespace GHelper
|
||||
bool tip = false;
|
||||
|
||||
HitTestResult hit = chart.HitTest(e.X, e.Y);
|
||||
Series series = chart.Series[0];
|
||||
|
||||
if (hit.Series is not null && hit.PointIndex >= 0)
|
||||
{
|
||||
curPoint = hit.Series.Points[hit.PointIndex];
|
||||
curIndex = hit.PointIndex;
|
||||
curPoint = hit.Series.Points[curIndex];
|
||||
tip = true;
|
||||
}
|
||||
|
||||
@@ -691,17 +931,24 @@ namespace GHelper
|
||||
if (dy < 0) dy = 0;
|
||||
if (dy > fansMax) dy = fansMax;
|
||||
|
||||
dymin = (dx - 65) * 1.2;
|
||||
dymin = (dx - 70) * 1.2;
|
||||
|
||||
if (dy < dymin) dy = dymin;
|
||||
|
||||
if (e.Button.HasFlag(MouseButtons.Left))
|
||||
{
|
||||
curPoint.XValue = dx;
|
||||
curPoint.YValues[0] = dy;
|
||||
double deltaY = dy - curPoint.YValues[0];
|
||||
double deltaX = dx - curPoint.XValue;
|
||||
|
||||
if (hit.Series is not null)
|
||||
AdjustAllLevels(hit.PointIndex, dx, dy, hit.Series);
|
||||
curPoint.XValue = dx;
|
||||
|
||||
if (Control.ModifierKeys == Keys.Shift)
|
||||
AdjustAll(0, deltaY, series);
|
||||
else
|
||||
{
|
||||
curPoint.YValues[0] = dy;
|
||||
AdjustAllLevels(curIndex, dx, dy, series);
|
||||
}
|
||||
|
||||
tip = true;
|
||||
}
|
||||
@@ -724,12 +971,21 @@ namespace GHelper
|
||||
|
||||
}
|
||||
|
||||
private void AdjustAll(double deltaX, double deltaY, Series series)
|
||||
{
|
||||
for (int i = 0; i < series.Points.Count; i++)
|
||||
{
|
||||
series.Points[i].XValue = Math.Max(20, Math.Min(100, series.Points[i].XValue + deltaX));
|
||||
series.Points[i].YValues[0] = Math.Max(0, Math.Min(100, series.Points[i].YValues[0] + deltaY));
|
||||
}
|
||||
}
|
||||
|
||||
private void AdjustAllLevels(int index, double curXVal, double curYVal, Series series)
|
||||
{
|
||||
|
||||
// Get the neighboring DataPoints of the hit point
|
||||
DataPoint upperPoint = null;
|
||||
DataPoint lowerPoint = null;
|
||||
DataPoint? upperPoint = null;
|
||||
DataPoint? lowerPoint = null;
|
||||
|
||||
if (index > 0)
|
||||
{
|
||||
|
||||
@@ -117,4 +117,7 @@
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="labelRisky.Text" xml:space="preserve">
|
||||
<value>Undervolting is experimental and risky feature. If applied values are too low for your hardware, it can become unstable or shut down. Try small negative values first, click Apply and test what works for you.</value>
|
||||
</data>
|
||||
</root>
|
||||
@@ -16,7 +16,7 @@
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<ProduceReferenceAssembly>False</ProduceReferenceAssembly>
|
||||
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
|
||||
<AssemblyVersion>0.75</AssemblyVersion>
|
||||
<AssemblyVersion>0.95</AssemblyVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||
@@ -63,6 +63,7 @@
|
||||
<PackageReference Include="hidlibrary" Version="3.3.40" />
|
||||
<PackageReference Include="HidSharpCore" Version="1.2.1.1" />
|
||||
<PackageReference Include="NAudio" Version="2.1.0" />
|
||||
<PackageReference Include="NvAPIWrapper.Net" Version="0.8.1.101" />
|
||||
<PackageReference Include="System.Management" Version="7.0.1" />
|
||||
<PackageReference Include="TaskScheduler" Version="2.10.1" />
|
||||
<PackageReference Include="WinForms.DataVisualization" Version="1.8.0" />
|
||||
@@ -133,6 +134,12 @@
|
||||
<Generator>SettingsSingleFileGenerator</Generator>
|
||||
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
|
||||
</None>
|
||||
<None Update="WinRing0x64.dll">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="WinRing0x64.sys">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -1,18 +1,47 @@
|
||||
using System.Diagnostics;
|
||||
using System.Runtime.InteropServices;
|
||||
using static GHelper.Gpu.AMD.Adl2.NativeMethods;
|
||||
|
||||
namespace AmdAdl2;
|
||||
namespace GHelper.Gpu.AMD;
|
||||
|
||||
#region Export Struct
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
|
||||
public struct ADLSGApplicationInfo
|
||||
{
|
||||
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
|
||||
public string strFileName;
|
||||
|
||||
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
|
||||
public string strFilePath;
|
||||
|
||||
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
|
||||
public string strVersion;
|
||||
|
||||
public long timeStamp;
|
||||
public uint iProfileExists;
|
||||
public uint iGPUAffinity;
|
||||
public ADLBdf GPUBdf;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct ADLSingleSensorData {
|
||||
public struct ADLBdf
|
||||
{
|
||||
public int iBus;
|
||||
public int iDevice;
|
||||
public int iFunction;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct ADLSingleSensorData
|
||||
{
|
||||
public int Supported;
|
||||
public int Value;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct ADLPMLogDataOutput {
|
||||
public struct ADLPMLogDataOutput
|
||||
{
|
||||
int Size;
|
||||
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = Adl2.ADL_PMLOG_MAX_SENSORS)]
|
||||
@@ -30,7 +59,8 @@ public struct ADLGcnInfo
|
||||
}
|
||||
|
||||
[Flags]
|
||||
public enum ADLAsicFamilyType {
|
||||
public enum ADLAsicFamilyType
|
||||
{
|
||||
Undefined = 0,
|
||||
Discrete = 1 << 0,
|
||||
Integrated = 1 << 1,
|
||||
@@ -42,7 +72,8 @@ public enum ADLAsicFamilyType {
|
||||
Embedded = 1 << 7,
|
||||
}
|
||||
|
||||
public enum ADLSensorType {
|
||||
public enum ADLSensorType
|
||||
{
|
||||
SENSOR_MAXTYPES = 0,
|
||||
PMLOG_CLK_GFXCLK = 1, // Current graphic clock value in MHz
|
||||
PMLOG_CLK_MEMCLK = 2, // Current memory clock value in MHz
|
||||
@@ -122,13 +153,15 @@ public enum ADLSensorType {
|
||||
|
||||
//Throttle Status
|
||||
[Flags]
|
||||
public enum ADL_THROTTLE_NOTIFICATION {
|
||||
public enum ADL_THROTTLE_NOTIFICATION
|
||||
{
|
||||
ADL_PMLOG_THROTTLE_POWER = 1 << 0,
|
||||
ADL_PMLOG_THROTTLE_THERMAL = 1 << 1,
|
||||
ADL_PMLOG_THROTTLE_CURRENT = 1 << 2,
|
||||
};
|
||||
|
||||
public enum ADL_PMLOG_SENSORS {
|
||||
public enum ADL_PMLOG_SENSORS
|
||||
{
|
||||
ADL_SENSOR_MAXTYPES = 0,
|
||||
ADL_PMLOG_CLK_GFXCLK = 1,
|
||||
ADL_PMLOG_CLK_MEMCLK = 2,
|
||||
@@ -210,7 +243,8 @@ public enum ADL_PMLOG_SENSORS {
|
||||
|
||||
/// <summary> ADLAdapterInfo Structure</summary>
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct ADLAdapterInfo {
|
||||
public struct ADLAdapterInfo
|
||||
{
|
||||
/// <summary>The size of the structure</summary>
|
||||
int Size;
|
||||
|
||||
@@ -265,7 +299,8 @@ public struct ADLAdapterInfo {
|
||||
|
||||
/// <summary> ADLAdapterInfo Array</summary>
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct ADLAdapterInfoArray {
|
||||
public struct ADLAdapterInfoArray
|
||||
{
|
||||
/// <summary> ADLAdapterInfo Array </summary>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = Adl2.ADL_MAX_ADAPTERS)]
|
||||
public ADLAdapterInfo[] ADLAdapterInfo;
|
||||
@@ -277,7 +312,8 @@ public struct ADLAdapterInfoArray {
|
||||
|
||||
/// <summary> ADLDisplayID Structure</summary>
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct ADLDisplayID {
|
||||
public struct ADLDisplayID
|
||||
{
|
||||
/// <summary> Display Logical Index </summary>
|
||||
public int DisplayLogicalIndex;
|
||||
|
||||
@@ -293,7 +329,8 @@ public struct ADLDisplayID {
|
||||
|
||||
/// <summary> ADLDisplayInfo Structure</summary>
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct ADLDisplayInfo {
|
||||
public struct ADLDisplayInfo
|
||||
{
|
||||
/// <summary> Display Index </summary>
|
||||
public ADLDisplayID DisplayID;
|
||||
|
||||
@@ -328,7 +365,8 @@ public struct ADLDisplayInfo {
|
||||
|
||||
#endregion Export Struct
|
||||
|
||||
public class Adl2 {
|
||||
public class Adl2
|
||||
{
|
||||
public const string Atiadlxx_FileName = "atiadlxx.dll";
|
||||
|
||||
#region Internal Constant
|
||||
@@ -371,24 +409,30 @@ public class Adl2 {
|
||||
// ///// <summary> ADL Create Function to create ADL Data</summary>
|
||||
/// <param name="enumConnectedAdapters">If it is 1, then ADL will only return the physical exist adapters </param>
|
||||
///// <returns> retrun ADL Error Code</returns>
|
||||
public static int ADL2_Main_Control_Create(int enumConnectedAdapters, out IntPtr adlContextHandle) {
|
||||
public static int ADL2_Main_Control_Create(int enumConnectedAdapters, out nint adlContextHandle)
|
||||
{
|
||||
return NativeMethods.ADL2_Main_Control_Create(ADL_Main_Memory_Alloc_Impl_Reference, enumConnectedAdapters, out adlContextHandle);
|
||||
}
|
||||
|
||||
public static void FreeMemory(IntPtr buffer) {
|
||||
public static void FreeMemory(nint buffer)
|
||||
{
|
||||
Memory_Free_Impl(buffer);
|
||||
}
|
||||
|
||||
private static bool? isDllLoaded;
|
||||
|
||||
public static bool Load() {
|
||||
public static bool Load()
|
||||
{
|
||||
if (isDllLoaded != null)
|
||||
return isDllLoaded.Value;
|
||||
|
||||
try {
|
||||
try
|
||||
{
|
||||
Marshal.PrelinkAll(typeof(Adl2));
|
||||
isDllLoaded = true;
|
||||
} catch (Exception e) when (e is DllNotFoundException or EntryPointNotFoundException) {
|
||||
}
|
||||
catch (Exception e) when (e is DllNotFoundException or EntryPointNotFoundException)
|
||||
{
|
||||
Debug.WriteLine(e);
|
||||
isDllLoaded = false;
|
||||
}
|
||||
@@ -396,53 +440,57 @@ public class Adl2 {
|
||||
return isDllLoaded.Value;
|
||||
}
|
||||
|
||||
private static NativeMethods.ADL_Main_Memory_Alloc ADL_Main_Memory_Alloc_Impl_Reference = Memory_Alloc_Impl;
|
||||
private static ADL_Main_Memory_Alloc ADL_Main_Memory_Alloc_Impl_Reference = Memory_Alloc_Impl;
|
||||
|
||||
/// <summary> Build in memory allocation function</summary>
|
||||
/// <param name="size">input size</param>
|
||||
/// <returns>return the memory buffer</returns>
|
||||
private static IntPtr Memory_Alloc_Impl(int size) {
|
||||
private static nint Memory_Alloc_Impl(int size)
|
||||
{
|
||||
return Marshal.AllocCoTaskMem(size);
|
||||
}
|
||||
|
||||
/// <summary> Build in memory free function</summary>
|
||||
/// <param name="buffer">input buffer</param>
|
||||
private static void Memory_Free_Impl(IntPtr buffer) {
|
||||
if (IntPtr.Zero != buffer) {
|
||||
private static void Memory_Free_Impl(nint buffer)
|
||||
{
|
||||
if (nint.Zero != buffer)
|
||||
{
|
||||
Marshal.FreeCoTaskMem(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
public static class NativeMethods {
|
||||
public static class NativeMethods
|
||||
{
|
||||
/// <summary> ADL Memory allocation function allows ADL to callback for memory allocation</summary>
|
||||
/// <param name="size">input size</param>
|
||||
/// <returns> retrun ADL Error Code</returns>
|
||||
public delegate IntPtr ADL_Main_Memory_Alloc(int size);
|
||||
public delegate nint ADL_Main_Memory_Alloc(int size);
|
||||
|
||||
// ///// <summary> ADL Create Function to create ADL Data</summary>
|
||||
/// <param name="callback">Call back functin pointer which is ised to allocate memeory </param>
|
||||
/// <param name="enumConnectedAdapters">If it is 1, then ADL will only retuen the physical exist adapters </param>
|
||||
///// <returns> retrun ADL Error Code</returns>
|
||||
[DllImport(Atiadlxx_FileName)]
|
||||
public static extern int ADL2_Main_Control_Create(ADL_Main_Memory_Alloc callback, int enumConnectedAdapters, out IntPtr adlContextHandle);
|
||||
public static extern int ADL2_Main_Control_Create(ADL_Main_Memory_Alloc callback, int enumConnectedAdapters, out nint adlContextHandle);
|
||||
|
||||
/// <summary> ADL Destroy Function to free up ADL Data</summary>
|
||||
/// <returns> retrun ADL Error Code</returns>
|
||||
[DllImport(Atiadlxx_FileName)]
|
||||
public static extern int ADL2_Main_Control_Destroy(IntPtr adlContextHandle);
|
||||
public static extern int ADL2_Main_Control_Destroy(nint adlContextHandle);
|
||||
|
||||
/// <summary> ADL Function to get the number of adapters</summary>
|
||||
/// <param name="numAdapters">return number of adapters</param>
|
||||
/// <returns> retrun ADL Error Code</returns>
|
||||
[DllImport(Atiadlxx_FileName)]
|
||||
public static extern int ADL2_Adapter_NumberOfAdapters_Get(IntPtr adlContextHandle, out int numAdapters);
|
||||
public static extern int ADL2_Adapter_NumberOfAdapters_Get(nint adlContextHandle, out int numAdapters);
|
||||
|
||||
/// <summary> ADL Function to get the GPU adapter information</summary>
|
||||
/// <param name="info">return GPU adapter information</param>
|
||||
/// <param name="inputSize">the size of the GPU adapter struct</param>
|
||||
/// <returns> retrun ADL Error Code</returns>
|
||||
[DllImport(Atiadlxx_FileName)]
|
||||
public static extern int ADL2_Adapter_AdapterInfo_Get(IntPtr adlContextHandle, IntPtr info, int inputSize);
|
||||
public static extern int ADL2_Adapter_AdapterInfo_Get(nint adlContextHandle, nint info, int inputSize);
|
||||
|
||||
/// <summary> Function to determine if the adapter is active or not.</summary>
|
||||
/// <remarks>The function is used to check if the adapter associated with iAdapterIndex is active</remarks>
|
||||
@@ -450,7 +498,7 @@ public class Adl2 {
|
||||
/// <param name="status"> Status of the adapter. True: Active; False: Dsiabled</param>
|
||||
/// <returns>Non zero is successfull</returns>
|
||||
[DllImport(Atiadlxx_FileName)]
|
||||
public static extern int ADL2_Adapter_Active_Get(IntPtr adlContextHandle, int adapterIndex, out int status);
|
||||
public static extern int ADL2_Adapter_Active_Get(nint adlContextHandle, int adapterIndex, out int status);
|
||||
|
||||
/// <summary>Get display information based on adapter index</summary>
|
||||
/// <param name="adapterIndex">Adapter Index</param>
|
||||
@@ -460,16 +508,16 @@ public class Adl2 {
|
||||
/// <returns>return ADL Error Code</returns>
|
||||
[DllImport(Atiadlxx_FileName)]
|
||||
public static extern int ADL2_Display_DisplayInfo_Get(
|
||||
IntPtr adlContextHandle,
|
||||
nint adlContextHandle,
|
||||
int adapterIndex,
|
||||
out int numDisplays,
|
||||
out IntPtr displayInfoArray,
|
||||
out nint displayInfoArray,
|
||||
int forceDetect
|
||||
);
|
||||
|
||||
[DllImport(Atiadlxx_FileName)]
|
||||
public static extern int ADL2_Overdrive_Caps(
|
||||
IntPtr adlContextHandle,
|
||||
nint adlContextHandle,
|
||||
int adapterIndex,
|
||||
out int supported,
|
||||
out int enabled,
|
||||
@@ -477,9 +525,75 @@ public class Adl2 {
|
||||
);
|
||||
|
||||
[DllImport(Atiadlxx_FileName)]
|
||||
public static extern int ADL2_New_QueryPMLogData_Get(IntPtr adlContextHandle, int adapterIndex, out ADLPMLogDataOutput adlpmLogDataOutput);
|
||||
public static extern int ADL2_New_QueryPMLogData_Get(nint adlContextHandle, int adapterIndex, out ADLPMLogDataOutput adlpmLogDataOutput);
|
||||
|
||||
[DllImport(Atiadlxx_FileName)]
|
||||
public static extern int ADL2_Adapter_ASICFamilyType_Get(IntPtr adlContextHandle, int adapterIndex, out ADLAsicFamilyType asicFamilyType, out int asicFamilyTypeValids);
|
||||
public static extern int ADL2_Adapter_ASICFamilyType_Get(nint adlContextHandle, int adapterIndex, out ADLAsicFamilyType asicFamilyType, out int asicFamilyTypeValids);
|
||||
|
||||
[DllImport(Atiadlxx_FileName)]
|
||||
public static extern int ADL2_SwitchableGraphics_Applications_Get(
|
||||
nint context,
|
||||
int iListType,
|
||||
out int lpNumApps,
|
||||
out nint lppAppList);
|
||||
|
||||
[DllImport(Atiadlxx_FileName)]
|
||||
public static extern int ADL2_Adapter_VariBright_Caps(
|
||||
nint context,
|
||||
int iAdapterIndex,
|
||||
out int iSupported,
|
||||
out int iEnabled,
|
||||
out int iVersion);
|
||||
|
||||
[DllImport(Atiadlxx_FileName)]
|
||||
public static extern int ADL2_Adapter_VariBrightEnable_Set(
|
||||
nint context,
|
||||
int iAdapterIndex,
|
||||
int iEnabled);
|
||||
|
||||
// Clocks
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct ADLODNPerformanceLevel
|
||||
{
|
||||
public int iClock;
|
||||
public int iVddc;
|
||||
public int iEnabled;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct ADLODNPerformanceLevels
|
||||
{
|
||||
public int iSize;
|
||||
public int iMode;
|
||||
public int iNumberOfPerformanceLevels;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)]
|
||||
public ADLODNPerformanceLevel[] aLevels;
|
||||
}
|
||||
|
||||
|
||||
[DllImport(Atiadlxx_FileName)]
|
||||
public static extern int ADL2_OverdriveN_SystemClocks_Get(
|
||||
nint context,
|
||||
int adapterIndex,
|
||||
ref ADLODNPerformanceLevels performanceLevels);
|
||||
|
||||
[DllImport(Atiadlxx_FileName)]
|
||||
public static extern int ADL2_OverdriveN_SystemClocks_Set(
|
||||
nint context,
|
||||
int adapterIndex,
|
||||
ref ADLODNPerformanceLevels performanceLevels);
|
||||
|
||||
[DllImport(Atiadlxx_FileName)]
|
||||
public static extern int ADL2_OverdriveN_MemoryClocks_Get(
|
||||
nint context,
|
||||
int adapterIndex,
|
||||
ref ADLODNPerformanceLevels performanceLevels);
|
||||
|
||||
[DllImport(Atiadlxx_FileName)]
|
||||
public static extern int ADL2_OverdriveN_MemoryClocks_Set(
|
||||
nint context,
|
||||
int adapterIndex,
|
||||
ref ADLODNPerformanceLevels performanceLevels);
|
||||
}
|
||||
}
|
||||
234
app/Gpu/AMD/AmdGpuControl.cs
Normal file
234
app/Gpu/AMD/AmdGpuControl.cs
Normal file
@@ -0,0 +1,234 @@
|
||||
using GHelper.Helpers;
|
||||
using System.Runtime.InteropServices;
|
||||
using static GHelper.Gpu.AMD.Adl2.NativeMethods;
|
||||
|
||||
namespace GHelper.Gpu.AMD;
|
||||
|
||||
// Reference: https://github.com/GPUOpen-LibrariesAndSDKs/display-library/blob/master/Sample-Managed/Program.cs
|
||||
public class AmdGpuControl : IGpuControl
|
||||
{
|
||||
private bool _isReady;
|
||||
private nint _adlContextHandle;
|
||||
private readonly ADLAdapterInfo _internalDiscreteAdapter;
|
||||
|
||||
public bool IsNvidia => false;
|
||||
|
||||
public string FullName => _internalDiscreteAdapter!.AdapterName;
|
||||
|
||||
private ADLAdapterInfo? FindByType(ADLAsicFamilyType type = ADLAsicFamilyType.Discrete)
|
||||
{
|
||||
ADL2_Adapter_NumberOfAdapters_Get(_adlContextHandle, out int numberOfAdapters);
|
||||
if (numberOfAdapters <= 0)
|
||||
return null;
|
||||
|
||||
ADLAdapterInfoArray osAdapterInfoData = new();
|
||||
int osAdapterInfoDataSize = Marshal.SizeOf(osAdapterInfoData);
|
||||
nint AdapterBuffer = Marshal.AllocCoTaskMem(osAdapterInfoDataSize);
|
||||
Marshal.StructureToPtr(osAdapterInfoData, AdapterBuffer, false);
|
||||
if (ADL2_Adapter_AdapterInfo_Get(_adlContextHandle, AdapterBuffer, osAdapterInfoDataSize) != Adl2.ADL_SUCCESS)
|
||||
return null;
|
||||
|
||||
osAdapterInfoData = (ADLAdapterInfoArray)Marshal.PtrToStructure(AdapterBuffer, osAdapterInfoData.GetType())!;
|
||||
|
||||
const int amdVendorId = 1002;
|
||||
|
||||
// Determine which GPU is internal discrete AMD GPU
|
||||
ADLAdapterInfo internalDiscreteAdapter =
|
||||
osAdapterInfoData.ADLAdapterInfo
|
||||
.FirstOrDefault(adapter =>
|
||||
{
|
||||
if (adapter.Exist == 0 || adapter.Present == 0)
|
||||
return false;
|
||||
|
||||
if (adapter.VendorID != amdVendorId)
|
||||
return false;
|
||||
|
||||
if (ADL2_Adapter_ASICFamilyType_Get(_adlContextHandle, adapter.AdapterIndex, out ADLAsicFamilyType asicFamilyType, out int asicFamilyTypeValids) != Adl2.ADL_SUCCESS)
|
||||
return false;
|
||||
|
||||
asicFamilyType = (ADLAsicFamilyType)((int)asicFamilyType & asicFamilyTypeValids);
|
||||
|
||||
return (asicFamilyType & type) != 0;
|
||||
});
|
||||
|
||||
if (internalDiscreteAdapter.Exist == 0)
|
||||
return null;
|
||||
|
||||
return internalDiscreteAdapter;
|
||||
|
||||
}
|
||||
|
||||
public AmdGpuControl()
|
||||
{
|
||||
if (!Adl2.Load())
|
||||
return;
|
||||
|
||||
if (Adl2.ADL2_Main_Control_Create(1, out _adlContextHandle) != Adl2.ADL_SUCCESS)
|
||||
return;
|
||||
|
||||
ADLAdapterInfo? internalDiscreteAdapter = FindByType(ADLAsicFamilyType.Discrete);
|
||||
|
||||
if (internalDiscreteAdapter is not null)
|
||||
{
|
||||
_internalDiscreteAdapter = (ADLAdapterInfo)internalDiscreteAdapter;
|
||||
_isReady = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public bool IsValid => _isReady && _adlContextHandle != nint.Zero;
|
||||
|
||||
public int? GetCurrentTemperature()
|
||||
{
|
||||
if (!IsValid)
|
||||
return null;
|
||||
|
||||
if (ADL2_New_QueryPMLogData_Get(_adlContextHandle, _internalDiscreteAdapter.AdapterIndex, out ADLPMLogDataOutput adlpmLogDataOutput) != Adl2.ADL_SUCCESS)
|
||||
return null;
|
||||
|
||||
ADLSingleSensorData temperatureSensor = adlpmLogDataOutput.Sensors[(int)ADLSensorType.PMLOG_TEMPERATURE_EDGE];
|
||||
if (temperatureSensor.Supported == 0)
|
||||
return null;
|
||||
|
||||
return temperatureSensor.Value;
|
||||
}
|
||||
|
||||
|
||||
public int? GetGpuUse()
|
||||
{
|
||||
if (!IsValid) return null;
|
||||
|
||||
if (ADL2_New_QueryPMLogData_Get(_adlContextHandle, _internalDiscreteAdapter.AdapterIndex, out ADLPMLogDataOutput adlpmLogDataOutput) != Adl2.ADL_SUCCESS)
|
||||
return null;
|
||||
|
||||
ADLSingleSensorData gpuUsage = adlpmLogDataOutput.Sensors[(int)ADLSensorType.PMLOG_INFO_ACTIVITY_GFX];
|
||||
if (gpuUsage.Supported == 0)
|
||||
return null;
|
||||
|
||||
return gpuUsage.Value;
|
||||
|
||||
}
|
||||
|
||||
|
||||
public bool SetVariBright(int enabled)
|
||||
{
|
||||
if (_adlContextHandle == nint.Zero) return false;
|
||||
|
||||
ADLAdapterInfo? iGPU = FindByType(ADLAsicFamilyType.Integrated);
|
||||
if (iGPU is null) return false;
|
||||
|
||||
return ADL2_Adapter_VariBrightEnable_Set(_adlContextHandle, ((ADLAdapterInfo)iGPU).AdapterIndex, enabled) == Adl2.ADL_SUCCESS;
|
||||
|
||||
}
|
||||
|
||||
public bool GetVariBright(out int supported, out int enabled)
|
||||
{
|
||||
supported = enabled = -1;
|
||||
|
||||
if (_adlContextHandle == nint.Zero) return false;
|
||||
|
||||
ADLAdapterInfo? iGPU = FindByType(ADLAsicFamilyType.Integrated);
|
||||
if (iGPU is null) return false;
|
||||
|
||||
if (ADL2_Adapter_VariBright_Caps(_adlContextHandle, ((ADLAdapterInfo)iGPU).AdapterIndex, out int supportedOut, out int enabledOut, out int version) != Adl2.ADL_SUCCESS)
|
||||
return false;
|
||||
|
||||
supported = supportedOut;
|
||||
enabled = enabledOut;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public ADLODNPerformanceLevels? GetGPUClocks()
|
||||
{
|
||||
if (!IsValid) return null;
|
||||
|
||||
ADLODNPerformanceLevels performanceLevels = new();
|
||||
ADL2_OverdriveN_SystemClocks_Get(_adlContextHandle, _internalDiscreteAdapter.AdapterIndex, ref performanceLevels);
|
||||
|
||||
return performanceLevels;
|
||||
}
|
||||
|
||||
public void KillGPUApps()
|
||||
{
|
||||
|
||||
if (!IsValid) return;
|
||||
|
||||
nint appInfoPtr = nint.Zero;
|
||||
int appCount = 0;
|
||||
|
||||
try
|
||||
{
|
||||
// Get switchable graphics applications information
|
||||
var result = ADL2_SwitchableGraphics_Applications_Get(_adlContextHandle, 2, out appCount, out appInfoPtr);
|
||||
if (result != 0)
|
||||
{
|
||||
throw new Exception("Failed to get switchable graphics applications. Error code: " + result);
|
||||
}
|
||||
|
||||
// Convert the application data pointers to an array of structs
|
||||
var appInfoArray = new ADLSGApplicationInfo[appCount];
|
||||
nint currentPtr = appInfoPtr;
|
||||
|
||||
for (int i = 0; i < appCount; i++)
|
||||
{
|
||||
appInfoArray[i] = Marshal.PtrToStructure<ADLSGApplicationInfo>(currentPtr);
|
||||
currentPtr = nint.Add(currentPtr, Marshal.SizeOf<ADLSGApplicationInfo>());
|
||||
}
|
||||
|
||||
var appNames = new List<string>();
|
||||
|
||||
for (int i = 0; i < appCount; i++)
|
||||
{
|
||||
if (appInfoArray[i].iGPUAffinity == 1)
|
||||
{
|
||||
Logger.WriteLine(appInfoArray[i].strFileName + ":" + appInfoArray[i].iGPUAffinity + "(" + appInfoArray[i].timeStamp + ")");
|
||||
appNames.Add(Path.GetFileNameWithoutExtension(appInfoArray[i].strFileName));
|
||||
}
|
||||
}
|
||||
|
||||
List<string> immune = new() { "svchost", "system", "ntoskrnl", "csrss", "winlogon", "wininit", "smss" };
|
||||
|
||||
foreach (string kill in appNames)
|
||||
if (!immune.Contains(kill.ToLower()))
|
||||
ProcessHelper.KillByName(kill);
|
||||
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.WriteLine(ex.Message);
|
||||
}
|
||||
finally
|
||||
{
|
||||
// Clean up resources
|
||||
if (appInfoPtr != nint.Zero)
|
||||
{
|
||||
Marshal.FreeCoTaskMem(appInfoPtr);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void ReleaseUnmanagedResources()
|
||||
{
|
||||
if (_adlContextHandle != nint.Zero)
|
||||
{
|
||||
ADL2_Main_Control_Destroy(_adlContextHandle);
|
||||
_adlContextHandle = nint.Zero;
|
||||
_isReady = false;
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
ReleaseUnmanagedResources();
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
~AmdGpuControl()
|
||||
{
|
||||
ReleaseUnmanagedResources();
|
||||
}
|
||||
}
|
||||
@@ -1,113 +0,0 @@
|
||||
using System.Runtime.InteropServices;
|
||||
using AmdAdl2;
|
||||
|
||||
namespace GHelper.Gpu;
|
||||
|
||||
// Reference: https://github.com/GPUOpen-LibrariesAndSDKs/display-library/blob/master/Sample-Managed/Program.cs
|
||||
public class AmdGpuControl : IGpuControl {
|
||||
private bool _isReady;
|
||||
private IntPtr _adlContextHandle;
|
||||
private readonly ADLAdapterInfo _internalDiscreteAdapter;
|
||||
|
||||
public bool IsNvidia => false;
|
||||
|
||||
public string FullName => _internalDiscreteAdapter!.AdapterName;
|
||||
public AmdGpuControl() {
|
||||
if (!Adl2.Load())
|
||||
return;
|
||||
|
||||
if (Adl2.ADL2_Main_Control_Create(1, out _adlContextHandle) != Adl2.ADL_SUCCESS)
|
||||
return;
|
||||
|
||||
Adl2.NativeMethods.ADL2_Adapter_NumberOfAdapters_Get(_adlContextHandle, out int numberOfAdapters);
|
||||
if (numberOfAdapters <= 0)
|
||||
return;
|
||||
|
||||
ADLAdapterInfoArray osAdapterInfoData = new();
|
||||
int osAdapterInfoDataSize = Marshal.SizeOf(osAdapterInfoData);
|
||||
IntPtr AdapterBuffer = Marshal.AllocCoTaskMem(osAdapterInfoDataSize);
|
||||
Marshal.StructureToPtr(osAdapterInfoData, AdapterBuffer, false);
|
||||
if (Adl2.NativeMethods.ADL2_Adapter_AdapterInfo_Get(_adlContextHandle, AdapterBuffer, osAdapterInfoDataSize) != Adl2.ADL_SUCCESS)
|
||||
return;
|
||||
|
||||
osAdapterInfoData = (ADLAdapterInfoArray) Marshal.PtrToStructure(AdapterBuffer, osAdapterInfoData.GetType())!;
|
||||
|
||||
const int amdVendorId = 1002;
|
||||
|
||||
// Determine which GPU is internal discrete AMD GPU
|
||||
ADLAdapterInfo internalDiscreteAdapter =
|
||||
osAdapterInfoData.ADLAdapterInfo
|
||||
.FirstOrDefault(adapter => {
|
||||
if (adapter.Exist == 0 || adapter.Present == 0)
|
||||
return false;
|
||||
|
||||
if (adapter.VendorID != amdVendorId)
|
||||
return false;
|
||||
|
||||
if (Adl2.NativeMethods.ADL2_Adapter_ASICFamilyType_Get(_adlContextHandle, adapter.AdapterIndex, out ADLAsicFamilyType asicFamilyType, out int asicFamilyTypeValids) != Adl2.ADL_SUCCESS)
|
||||
return false;
|
||||
|
||||
asicFamilyType = (ADLAsicFamilyType) ((int) asicFamilyType & asicFamilyTypeValids);
|
||||
|
||||
// FIXME: is this correct for G14 2022?
|
||||
return (asicFamilyType & ADLAsicFamilyType.Discrete) != 0;
|
||||
});
|
||||
|
||||
if (internalDiscreteAdapter.Exist == 0)
|
||||
return;
|
||||
|
||||
_internalDiscreteAdapter = internalDiscreteAdapter;
|
||||
_isReady = true;
|
||||
}
|
||||
|
||||
public bool IsValid => _isReady && _adlContextHandle != IntPtr.Zero;
|
||||
|
||||
public int? GetCurrentTemperature() {
|
||||
if (!IsValid)
|
||||
return null;
|
||||
|
||||
if (Adl2.NativeMethods.ADL2_New_QueryPMLogData_Get(_adlContextHandle, _internalDiscreteAdapter.AdapterIndex, out ADLPMLogDataOutput adlpmLogDataOutput) != Adl2.ADL_SUCCESS)
|
||||
return null;
|
||||
|
||||
ADLSingleSensorData temperatureSensor = adlpmLogDataOutput.Sensors[(int) ADLSensorType.PMLOG_TEMPERATURE_EDGE];
|
||||
if (temperatureSensor.Supported == 0)
|
||||
return null;
|
||||
|
||||
return temperatureSensor.Value;
|
||||
}
|
||||
|
||||
|
||||
public int? GetGpuUse()
|
||||
{
|
||||
if (!IsValid)
|
||||
return null;
|
||||
|
||||
if (Adl2.NativeMethods.ADL2_New_QueryPMLogData_Get(_adlContextHandle, _internalDiscreteAdapter.AdapterIndex, out ADLPMLogDataOutput adlpmLogDataOutput) != Adl2.ADL_SUCCESS)
|
||||
return null;
|
||||
|
||||
ADLSingleSensorData gpuUsage = adlpmLogDataOutput.Sensors[(int)ADLSensorType.PMLOG_INFO_ACTIVITY_GFX];
|
||||
if (gpuUsage.Supported == 0)
|
||||
return null;
|
||||
|
||||
return gpuUsage.Value;
|
||||
|
||||
}
|
||||
|
||||
|
||||
private void ReleaseUnmanagedResources() {
|
||||
if (_adlContextHandle != IntPtr.Zero) {
|
||||
Adl2.NativeMethods.ADL2_Main_Control_Destroy(_adlContextHandle);
|
||||
_adlContextHandle = IntPtr.Zero;
|
||||
_isReady = false;
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose() {
|
||||
ReleaseUnmanagedResources();
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
~AmdGpuControl() {
|
||||
ReleaseUnmanagedResources();
|
||||
}
|
||||
}
|
||||
325
app/Gpu/GPUModeControl.cs
Normal file
325
app/Gpu/GPUModeControl.cs
Normal file
@@ -0,0 +1,325 @@
|
||||
using GHelper.Display;
|
||||
using GHelper.Gpu.NVidia;
|
||||
using GHelper.Helpers;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace GHelper.Gpu
|
||||
{
|
||||
public class GPUModeControl
|
||||
{
|
||||
SettingsForm settings;
|
||||
ScreenControl screenControl = new ScreenControl();
|
||||
|
||||
public GPUModeControl(SettingsForm settingsForm)
|
||||
{
|
||||
settings = settingsForm;
|
||||
}
|
||||
|
||||
public void InitGPUMode()
|
||||
{
|
||||
int eco = Program.acpi.DeviceGet(AsusACPI.GPUEco);
|
||||
int mux = Program.acpi.DeviceGet(AsusACPI.GPUMux);
|
||||
|
||||
Logger.WriteLine("Eco flag : " + eco);
|
||||
Logger.WriteLine("Mux flag : " + mux);
|
||||
|
||||
int GpuMode;
|
||||
|
||||
if (mux == 0)
|
||||
{
|
||||
GpuMode = AsusACPI.GPUModeUltimate;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (eco == 1)
|
||||
GpuMode = AsusACPI.GPUModeEco;
|
||||
else
|
||||
GpuMode = AsusACPI.GPUModeStandard;
|
||||
|
||||
// Ultimate mode not suported
|
||||
if (mux != 1) settings.HideUltimateMode();
|
||||
// GPU mode not supported
|
||||
if (eco < 0 && mux < 0) settings.HideGPUModes();
|
||||
}
|
||||
|
||||
AppConfig.Set("gpu_mode", GpuMode);
|
||||
|
||||
InitXGM();
|
||||
settings.VisualiseGPUMode(GpuMode);
|
||||
}
|
||||
|
||||
|
||||
public void SetGPUMode(int GPUMode)
|
||||
{
|
||||
|
||||
int CurrentGPU = AppConfig.Get("gpu_mode");
|
||||
AppConfig.Set("gpu_auto", 0);
|
||||
|
||||
if (CurrentGPU == GPUMode)
|
||||
{
|
||||
settings.VisualiseGPUMode();
|
||||
return;
|
||||
}
|
||||
|
||||
var restart = false;
|
||||
var changed = false;
|
||||
|
||||
if (CurrentGPU == AsusACPI.GPUModeUltimate)
|
||||
{
|
||||
DialogResult dialogResult = MessageBox.Show(Properties.Strings.AlertUltimateOff, Properties.Strings.AlertUltimateTitle, MessageBoxButtons.YesNo);
|
||||
if (dialogResult == DialogResult.Yes)
|
||||
{
|
||||
Program.acpi.DeviceSet(AsusACPI.GPUMux, 1, "GPUMux");
|
||||
restart = true;
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
else if (GPUMode == AsusACPI.GPUModeUltimate)
|
||||
{
|
||||
DialogResult dialogResult = MessageBox.Show(Properties.Strings.AlertUltimateOn, Properties.Strings.AlertUltimateTitle, MessageBoxButtons.YesNo);
|
||||
if (dialogResult == DialogResult.Yes)
|
||||
{
|
||||
Program.acpi.DeviceSet(AsusACPI.GPUMux, 0, "GPUMux");
|
||||
restart = true;
|
||||
changed = true;
|
||||
}
|
||||
|
||||
}
|
||||
else if (GPUMode == AsusACPI.GPUModeEco)
|
||||
{
|
||||
settings.VisualiseGPUMode(GPUMode);
|
||||
SetGPUEco(1, true);
|
||||
changed = true;
|
||||
}
|
||||
else if (GPUMode == AsusACPI.GPUModeStandard)
|
||||
{
|
||||
settings.VisualiseGPUMode(GPUMode);
|
||||
SetGPUEco(0);
|
||||
changed = true;
|
||||
}
|
||||
|
||||
if (changed)
|
||||
{
|
||||
AppConfig.Set("gpu_mode", GPUMode);
|
||||
}
|
||||
|
||||
if (restart)
|
||||
{
|
||||
settings.VisualiseGPUMode();
|
||||
Process.Start("shutdown", "/r /t 1");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void SetGPUEco(int eco, bool hardWay = false)
|
||||
{
|
||||
|
||||
settings.LockGPUModes();
|
||||
|
||||
Task.Run(async () =>
|
||||
{
|
||||
|
||||
int status = 1;
|
||||
|
||||
if (eco == 1)
|
||||
{
|
||||
if (NvidiaSmi.GetDisplayActiveStatus())
|
||||
{
|
||||
DialogResult dialogResult = MessageBox.Show(Properties.Strings.EnableOptimusText, Properties.Strings.EnableOptimusTitle, MessageBoxButtons.YesNo);
|
||||
if (dialogResult == DialogResult.No)
|
||||
{
|
||||
InitGPUMode();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
HardwareControl.KillGPUApps();
|
||||
}
|
||||
|
||||
Logger.WriteLine($"Running eco command {eco}");
|
||||
|
||||
status = Program.acpi.SetGPUEco(eco);
|
||||
|
||||
if (status == 0 && eco == 1 && hardWay) RestartGPU();
|
||||
|
||||
await Task.Delay(TimeSpan.FromMilliseconds(100));
|
||||
|
||||
settings.Invoke(delegate
|
||||
{
|
||||
InitGPUMode();
|
||||
screenControl.AutoScreen();
|
||||
});
|
||||
|
||||
if (eco == 0)
|
||||
{
|
||||
await Task.Delay(TimeSpan.FromMilliseconds(3000));
|
||||
HardwareControl.RecreateGpuControl();
|
||||
Program.modeControl.SetGPUClocks(false);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
|
||||
public static bool IsPlugged()
|
||||
{
|
||||
bool optimizedUSBC = AppConfig.Get("optimized_usbc") != 1;
|
||||
|
||||
return SystemInformation.PowerStatus.PowerLineStatus == PowerLineStatus.Online &&
|
||||
(optimizedUSBC || Program.acpi.DeviceGet(AsusACPI.ChargerMode) < AsusACPI.ChargerUSB);
|
||||
|
||||
}
|
||||
|
||||
public bool AutoGPUMode(bool optimized = false)
|
||||
{
|
||||
|
||||
bool GpuAuto = AppConfig.Is("gpu_auto");
|
||||
bool ForceGPU = AppConfig.ContainsModel("503");
|
||||
|
||||
int GpuMode = AppConfig.Get("gpu_mode");
|
||||
|
||||
if (!GpuAuto && !ForceGPU) return false;
|
||||
|
||||
int eco = Program.acpi.DeviceGet(AsusACPI.GPUEco);
|
||||
int mux = Program.acpi.DeviceGet(AsusACPI.GPUMux);
|
||||
|
||||
if (mux == 0)
|
||||
{
|
||||
if (optimized) SetGPUMode(AsusACPI.GPUModeStandard);
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
if (ReEnableGPU()) return true;
|
||||
|
||||
if (eco == 1)
|
||||
if ((GpuAuto && IsPlugged()) || (ForceGPU && GpuMode == AsusACPI.GPUModeStandard))
|
||||
{
|
||||
SetGPUEco(0);
|
||||
return true;
|
||||
}
|
||||
if (eco == 0)
|
||||
if ((GpuAuto && !IsPlugged()) || (ForceGPU && GpuMode == AsusACPI.GPUModeEco))
|
||||
{
|
||||
|
||||
if (HardwareControl.IsUsedGPU())
|
||||
{
|
||||
DialogResult dialogResult = MessageBox.Show(Properties.Strings.AlertDGPU, Properties.Strings.AlertDGPUTitle, MessageBoxButtons.YesNo);
|
||||
if (dialogResult == DialogResult.No) return false;
|
||||
}
|
||||
|
||||
SetGPUEco(1);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
|
||||
public void RestartGPU(bool confirm = true)
|
||||
{
|
||||
if (HardwareControl.GpuControl is null) return;
|
||||
if (!HardwareControl.GpuControl!.IsNvidia) return;
|
||||
|
||||
if (confirm)
|
||||
{
|
||||
DialogResult dialogResult = MessageBox.Show(Properties.Strings.RestartGPU, Properties.Strings.EcoMode, MessageBoxButtons.YesNo);
|
||||
if (dialogResult == DialogResult.No) return;
|
||||
}
|
||||
|
||||
ProcessHelper.RunAsAdmin("gpurestart");
|
||||
|
||||
if (!ProcessHelper.IsUserAdministrator()) return;
|
||||
|
||||
Logger.WriteLine("Trying to restart dGPU");
|
||||
|
||||
Task.Run(async () =>
|
||||
{
|
||||
settings.LockGPUModes("Restarting GPU ...");
|
||||
|
||||
var nvControl = (NvidiaGpuControl)HardwareControl.GpuControl;
|
||||
bool status = nvControl.RestartGPU();
|
||||
|
||||
settings.Invoke(delegate
|
||||
{
|
||||
//labelTipGPU.Text = status ? "GPU Restarted, you can try Eco mode again" : "Failed to restart GPU"; TODO
|
||||
InitGPUMode();
|
||||
});
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
public bool ReEnableGPU()
|
||||
{
|
||||
|
||||
if (AppConfig.Get("gpu_reenable") != 1) return false;
|
||||
if (Screen.AllScreens.Length <= 1) return false;
|
||||
|
||||
Logger.WriteLine("Re-enabling gpu for 503 model");
|
||||
|
||||
Thread.Sleep(1000);
|
||||
SetGPUEco(1);
|
||||
Thread.Sleep(1000);
|
||||
SetGPUEco(0);
|
||||
return true;
|
||||
}
|
||||
|
||||
public void InitXGM()
|
||||
{
|
||||
bool connected = Program.acpi.IsXGConnected();
|
||||
int activated = Program.acpi.DeviceGet(AsusACPI.GPUXG);
|
||||
settings.VisualizeXGM(connected, activated == 1);
|
||||
}
|
||||
|
||||
public void ToggleXGM()
|
||||
{
|
||||
|
||||
Task.Run(async () =>
|
||||
{
|
||||
settings.LockGPUModes();
|
||||
|
||||
if (Program.acpi.DeviceGet(AsusACPI.GPUXG) == 1)
|
||||
{
|
||||
HardwareControl.KillGPUApps();
|
||||
DialogResult dialogResult = MessageBox.Show("Did you close all applications running on XG Mobile?", "Disabling XG Mobile", MessageBoxButtons.YesNo);
|
||||
if (dialogResult == DialogResult.Yes)
|
||||
{
|
||||
Program.acpi.DeviceSet(AsusACPI.GPUXG, 0, "GPU XGM");
|
||||
await Task.Delay(TimeSpan.FromSeconds(15));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Program.acpi.DeviceSet(AsusACPI.GPUXG, 1, "GPU XGM");
|
||||
AsusUSB.ApplyXGMLight(AppConfig.Is("xmg_light"));
|
||||
|
||||
await Task.Delay(TimeSpan.FromSeconds(15));
|
||||
|
||||
if (AppConfig.IsMode("auto_apply"))
|
||||
AsusUSB.SetXGMFan(AppConfig.GetFanConfig(AsusFan.XGM));
|
||||
}
|
||||
|
||||
settings.Invoke(delegate
|
||||
{
|
||||
InitGPUMode();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
public void KillGPUApps()
|
||||
{
|
||||
if (HardwareControl.GpuControl is not null)
|
||||
{
|
||||
HardwareControl.GpuControl.KillGPUApps();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -6,4 +6,6 @@ public interface IGpuControl : IDisposable {
|
||||
public string FullName { get; }
|
||||
int? GetCurrentTemperature();
|
||||
int? GetGpuUse();
|
||||
void KillGPUApps();
|
||||
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using NvAPIWrapper.GPU;
|
||||
using GHelper.Helpers;
|
||||
using NvAPIWrapper.GPU;
|
||||
using NvAPIWrapper.Native;
|
||||
using NvAPIWrapper.Native.GPU;
|
||||
using NvAPIWrapper.Native.GPU.Structures;
|
||||
@@ -6,13 +7,13 @@ using NvAPIWrapper.Native.Interfaces.GPU;
|
||||
using System.Diagnostics;
|
||||
using static NvAPIWrapper.Native.GPU.Structures.PerformanceStates20InfoV1;
|
||||
|
||||
namespace GHelper.Gpu;
|
||||
namespace GHelper.Gpu.NVidia;
|
||||
|
||||
public class NvidiaGpuControl : IGpuControl
|
||||
{
|
||||
|
||||
public const int MaxCoreOffset = 250;
|
||||
public const int MaxMemoryOffset = 250;
|
||||
public static int MaxCoreOffset => AppConfig.Get("max_gpu_core", 250);
|
||||
public static int MaxMemoryOffset => AppConfig.Get("max_gpu_memory", 250);
|
||||
|
||||
public const int MinCoreOffset = -250;
|
||||
public const int MinMemoryOffset = -250;
|
||||
@@ -56,25 +57,21 @@ public class NvidiaGpuControl : IGpuControl
|
||||
{
|
||||
Process[] processes = internalGpu.GetActiveApplications();
|
||||
foreach (Process process in processes)
|
||||
{
|
||||
try
|
||||
{
|
||||
process?.Kill();
|
||||
Logger.WriteLine("Stopped: " + process.ProcessName);
|
||||
Logger.WriteLine("Kill:" + process.ProcessName);
|
||||
ProcessHelper.KillByProcess(process);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.WriteLine(ex.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.WriteLine(ex.Message);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//NVIDIA.RestartDisplayDriver();
|
||||
}
|
||||
|
||||
@@ -92,6 +89,12 @@ public class NvidiaGpuControl : IGpuControl
|
||||
core = states.Clocks[PerformanceStateId.P0_3DPerformance][0].FrequencyDeltaInkHz.DeltaValue / 1000;
|
||||
memory = states.Clocks[PerformanceStateId.P0_3DPerformance][1].FrequencyDeltaInkHz.DeltaValue / 1000;
|
||||
Logger.WriteLine($"GET GPU CLOCKS: {core}, {memory}");
|
||||
|
||||
foreach (var delta in states.Voltages[PerformanceStateId.P0_3DPerformance])
|
||||
{
|
||||
Logger.WriteLine("GPU VOLT:" + delta.IsEditable + " - " + delta.ValueDeltaInMicroVolt.DeltaValue);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
@@ -104,43 +107,6 @@ public class NvidiaGpuControl : IGpuControl
|
||||
|
||||
}
|
||||
|
||||
private static void RunCMD(string name, string args)
|
||||
{
|
||||
var cmd = new Process();
|
||||
cmd.StartInfo.UseShellExecute = false;
|
||||
cmd.StartInfo.CreateNoWindow = true;
|
||||
cmd.StartInfo.RedirectStandardOutput = true;
|
||||
cmd.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
|
||||
cmd.StartInfo.FileName = name;
|
||||
cmd.StartInfo.Arguments = args;
|
||||
cmd.Start();
|
||||
Logger.WriteLine(cmd.StandardOutput.ReadToEnd());
|
||||
cmd.WaitForExit();
|
||||
}
|
||||
|
||||
|
||||
public bool RestartGPUPnP()
|
||||
{
|
||||
|
||||
if (!IsValid) return false;
|
||||
|
||||
try
|
||||
{
|
||||
PhysicalGPU internalGpu = _internalGpu!;
|
||||
var pnpDeviceId = internalGpu.BusInformation.PCIIdentifiers.ToString();
|
||||
Logger.WriteLine("Device ID:" + pnpDeviceId);
|
||||
RunCMD("pnputil", $"/disable-device /deviceid \"{pnpDeviceId}\"");
|
||||
Thread.Sleep(3000);
|
||||
RunCMD("pnputil", $"/enable-device /deviceid \"{pnpDeviceId}\"");
|
||||
Thread.Sleep(2000);
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.WriteLine(ex.ToString());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public bool RestartGPU()
|
||||
{
|
||||
@@ -148,7 +114,7 @@ public class NvidiaGpuControl : IGpuControl
|
||||
{
|
||||
string script = @"$device = Get-PnpDevice | Where-Object { $_.FriendlyName -imatch 'NVIDIA' -and $_.Class -eq 'Display' }; Disable-PnpDevice $device.InstanceId -Confirm:$false; Start-Sleep -Seconds 3; Enable-PnpDevice $device.InstanceId -Confirm:$false";
|
||||
Logger.WriteLine(script);
|
||||
RunCMD("powershell", script);
|
||||
ProcessHelper.RunCMD("powershell", script);
|
||||
//Thread.Sleep(2000);
|
||||
return true;
|
||||
}
|
||||
@@ -161,13 +127,13 @@ public class NvidiaGpuControl : IGpuControl
|
||||
|
||||
public int SetClocksFromConfig()
|
||||
{
|
||||
int core = AppConfig.getConfig("gpu_core");
|
||||
int memory = AppConfig.getConfig("gpu_memory");
|
||||
int core = AppConfig.Get("gpu_core", 0);
|
||||
int memory = AppConfig.Get("gpu_memory", 0);
|
||||
int status = SetClocks(core, memory);
|
||||
return status;
|
||||
}
|
||||
|
||||
public int SetClocks(int core, int memory)
|
||||
public int SetClocks(int core, int memory, int voltage = 0)
|
||||
{
|
||||
|
||||
if (core < MinCoreOffset || core > MaxCoreOffset) return 0;
|
||||
@@ -177,6 +143,7 @@ public class NvidiaGpuControl : IGpuControl
|
||||
|
||||
var coreClock = new PerformanceStates20ClockEntryV1(PublicClockDomain.Graphics, new PerformanceStates20ParameterDelta(core * 1000));
|
||||
var memoryClock = new PerformanceStates20ClockEntryV1(PublicClockDomain.Memory, new PerformanceStates20ParameterDelta(memory * 1000));
|
||||
var voltageEntry = new PerformanceStates20BaseVoltageEntryV1(PerformanceVoltageDomain.Core, new PerformanceStates20ParameterDelta(voltage));
|
||||
|
||||
PerformanceStates20ClockEntryV1[] clocks = { coreClock, memoryClock };
|
||||
PerformanceStates20BaseVoltageEntryV1[] voltages = { };
|
||||
65
app/Gpu/NVidia/NvidiaSmi.cs
Normal file
65
app/Gpu/NVidia/NvidiaSmi.cs
Normal file
@@ -0,0 +1,65 @@
|
||||
using Ryzen;
|
||||
using System.Diagnostics;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
public static class NvidiaSmi
|
||||
{
|
||||
public static bool GetDisplayActiveStatus()
|
||||
{
|
||||
// Non AMD devices doesn't seem to be affected
|
||||
if (!RyzenControl.IsAMD()) return false;
|
||||
|
||||
string commandOutput = RunNvidiaSmiCommand();
|
||||
|
||||
Logger.WriteLine(commandOutput);
|
||||
|
||||
if (commandOutput.Length == 0) return false;
|
||||
if (!commandOutput.Contains("RTX 40")) return false;
|
||||
|
||||
// Extract the "Display Active" status using regular expressions
|
||||
string displayActivePattern = @"Display Active\s+:\s+(\w+)";
|
||||
|
||||
Match match = Regex.Match(commandOutput, displayActivePattern, RegexOptions.IgnoreCase);
|
||||
|
||||
if (match.Success)
|
||||
{
|
||||
string status = match.Groups[1].Value.ToLower().Trim(' ');
|
||||
return status == "enabled";
|
||||
}
|
||||
|
||||
return false; // Return false if the "Display Active" status is not found
|
||||
}
|
||||
|
||||
private static string RunNvidiaSmiCommand(string arguments = "-i 0 -q")
|
||||
{
|
||||
ProcessStartInfo startInfo = new ProcessStartInfo
|
||||
{
|
||||
FileName = "nvidia-smi",
|
||||
Arguments = arguments,
|
||||
RedirectStandardOutput = true,
|
||||
UseShellExecute = false,
|
||||
CreateNoWindow = true
|
||||
};
|
||||
|
||||
Process process = new Process
|
||||
{
|
||||
StartInfo = startInfo
|
||||
};
|
||||
|
||||
try
|
||||
{
|
||||
process.Start();
|
||||
string output = process.StandardOutput.ReadToEnd();
|
||||
process.WaitForExit();
|
||||
return output;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
//return File.ReadAllText(@"smi.txt");
|
||||
Debug.WriteLine(ex.Message);
|
||||
}
|
||||
|
||||
return "";
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,9 @@
|
||||
using GHelper;
|
||||
using GHelper.Gpu;
|
||||
using GHelper.Gpu.NVidia;
|
||||
using GHelper.Gpu.AMD;
|
||||
|
||||
using GHelper.Helpers;
|
||||
using System.Diagnostics;
|
||||
|
||||
public static class HardwareControl
|
||||
@@ -19,8 +23,8 @@ public static class HardwareControl
|
||||
public static int GetFanMax()
|
||||
{
|
||||
int max = 58;
|
||||
int configMax = AppConfig.getConfig("fan_max");
|
||||
if (configMax > 100) configMax = 0; // skipping inadvequate settings
|
||||
int configMax = AppConfig.Get("fan_max");
|
||||
if (configMax > 80) configMax = 0; // skipping inadvequate settings
|
||||
|
||||
if (AppConfig.ContainsModel("401")) max = 72;
|
||||
else if (AppConfig.ContainsModel("503")) max = 68;
|
||||
@@ -29,9 +33,9 @@ public static class HardwareControl
|
||||
|
||||
public static void SetFanMax(int fan)
|
||||
{
|
||||
AppConfig.setConfig("fan_max", fan);
|
||||
AppConfig.Set("fan_max", fan);
|
||||
}
|
||||
private static string FormatFan(int fan)
|
||||
public static string FormatFan(int fan)
|
||||
{
|
||||
// fix for old models
|
||||
if (fan < 0)
|
||||
@@ -41,9 +45,9 @@ public static class HardwareControl
|
||||
}
|
||||
|
||||
int fanMax = GetFanMax();
|
||||
if (fan > fanMax && fan < 110) SetFanMax(fan);
|
||||
if (fan > fanMax && fan < 80) SetFanMax(fan);
|
||||
|
||||
if (AppConfig.getConfig("fan_rpm") == 1)
|
||||
if (AppConfig.Is("fan_rpm"))
|
||||
return GHelper.Properties.Strings.FanSpeed + (fan * 100).ToString() + "RPM";
|
||||
else
|
||||
return GHelper.Properties.Strings.FanSpeed + Math.Min(Math.Round((float)fan / fanMax * 100), 100).ToString() + "%"; // relatively to 6000 rpm
|
||||
@@ -187,33 +191,12 @@ public static class HardwareControl
|
||||
public static void KillGPUApps()
|
||||
{
|
||||
|
||||
List<string> tokill = new() { "EADesktop", "RadeonSoftware", "epicgameslauncher" };
|
||||
List<string> tokill = new() { "EADesktop", "RadeonSoftware", "epicgameslauncher", "ASUSSmartDisplayControl" };
|
||||
foreach (string kill in tokill) ProcessHelper.KillByName(kill);
|
||||
|
||||
if (AppConfig.isConfig("kill_gpu_apps"))
|
||||
if (AppConfig.Is("kill_gpu_apps") && GpuControl is not null)
|
||||
{
|
||||
tokill.Add("nvdisplay.container");
|
||||
tokill.Add("nvcontainer");
|
||||
tokill.Add("nvcplui");
|
||||
}
|
||||
|
||||
foreach (string kill in tokill)
|
||||
foreach (var process in Process.GetProcessesByName(kill))
|
||||
{
|
||||
try
|
||||
{
|
||||
process.Kill();
|
||||
Logger.WriteLine($"Stopped: {process.ProcessName}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.WriteLine($"Failed to stop: {process.ProcessName} {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
if (AppConfig.isConfig("kill_gpu_apps") && GpuControl is not null && GpuControl.IsNvidia)
|
||||
{
|
||||
NvidiaGpuControl nvControl = (NvidiaGpuControl)GpuControl;
|
||||
nvControl.KillGPUApps();
|
||||
GpuControl.KillGPUApps();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ public static class Logger
|
||||
try
|
||||
{
|
||||
var file = File.ReadAllLines(logFile);
|
||||
int skip = Math.Max(0, file.Count() - 500);
|
||||
int skip = Math.Max(0, file.Count() - 1000);
|
||||
File.WriteAllLines(logFile, file.Skip(skip).ToArray());
|
||||
}
|
||||
catch { }
|
||||
@@ -1,7 +1,7 @@
|
||||
using System.Drawing.Imaging;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace OSD
|
||||
namespace GHelper.Helpers
|
||||
{
|
||||
|
||||
public class OSDNativeForm : NativeWindow, IDisposable
|
||||
@@ -19,11 +19,11 @@ namespace OSD
|
||||
|
||||
protected internal void Invalidate()
|
||||
{
|
||||
this.UpdateLayeredWindow();
|
||||
UpdateLayeredWindow();
|
||||
}
|
||||
private void UpdateLayeredWindow()
|
||||
{
|
||||
Bitmap bitmap1 = new Bitmap(this.Size.Width, this.Size.Height, PixelFormat.Format32bppArgb);
|
||||
Bitmap bitmap1 = new Bitmap(Size.Width, Size.Height, PixelFormat.Format32bppArgb);
|
||||
using (Graphics graphics1 = Graphics.FromImage(bitmap1))
|
||||
{
|
||||
Rectangle rectangle1;
|
||||
@@ -31,27 +31,27 @@ namespace OSD
|
||||
POINT point1;
|
||||
POINT point2;
|
||||
BLENDFUNCTION blendfunction1;
|
||||
rectangle1 = new Rectangle(0, 0, this.Size.Width, this.Size.Height);
|
||||
rectangle1 = new Rectangle(0, 0, Size.Width, Size.Height);
|
||||
PerformPaint(new PaintEventArgs(graphics1, rectangle1));
|
||||
IntPtr ptr1 = User32.GetDC(IntPtr.Zero);
|
||||
IntPtr ptr2 = Gdi32.CreateCompatibleDC(ptr1);
|
||||
IntPtr ptr3 = bitmap1.GetHbitmap(Color.FromArgb(0));
|
||||
IntPtr ptr4 = Gdi32.SelectObject(ptr2, ptr3);
|
||||
size1.cx = this.Size.Width;
|
||||
size1.cy = this.Size.Height;
|
||||
point1.x = this.Location.X;
|
||||
point1.x = this.Location.X;
|
||||
point1.y = this.Location.Y;
|
||||
nint ptr1 = User32.GetDC(nint.Zero);
|
||||
nint ptr2 = Gdi32.CreateCompatibleDC(ptr1);
|
||||
nint ptr3 = bitmap1.GetHbitmap(Color.FromArgb(0));
|
||||
nint ptr4 = Gdi32.SelectObject(ptr2, ptr3);
|
||||
size1.cx = Size.Width;
|
||||
size1.cy = Size.Height;
|
||||
point1.x = Location.X;
|
||||
point1.x = Location.X;
|
||||
point1.y = Location.Y;
|
||||
point2.x = 0;
|
||||
point2.y = 0;
|
||||
blendfunction1 = new BLENDFUNCTION();
|
||||
blendfunction1.BlendOp = 0;
|
||||
blendfunction1.BlendFlags = 0;
|
||||
blendfunction1.SourceConstantAlpha = this._alpha;
|
||||
blendfunction1.SourceConstantAlpha = _alpha;
|
||||
blendfunction1.AlphaFormat = 1;
|
||||
User32.UpdateLayeredWindow(base.Handle, ptr1, ref point1, ref size1, ptr2, ref point2, 0, ref blendfunction1, 2); //2=ULW_ALPHA
|
||||
User32.UpdateLayeredWindow(Handle, ptr1, ref point1, ref size1, ptr2, ref point2, 0, ref blendfunction1, 2); //2=ULW_ALPHA
|
||||
Gdi32.SelectObject(ptr2, ptr4);
|
||||
User32.ReleaseDC(IntPtr.Zero, ptr1);
|
||||
User32.ReleaseDC(nint.Zero, ptr1);
|
||||
Gdi32.DeleteObject(ptr3);
|
||||
Gdi32.DeleteDC(ptr2);
|
||||
}
|
||||
@@ -59,25 +59,25 @@ namespace OSD
|
||||
|
||||
public virtual void Show()
|
||||
{
|
||||
if (base.Handle == IntPtr.Zero) //if handle don't equal to zero - window was created and just hided
|
||||
this.CreateWindowOnly();
|
||||
User32.ShowWindow(base.Handle, User32.SW_SHOWNOACTIVATE);
|
||||
if (Handle == nint.Zero) //if handle don't equal to zero - window was created and just hided
|
||||
CreateWindowOnly();
|
||||
User32.ShowWindow(Handle, User32.SW_SHOWNOACTIVATE);
|
||||
}
|
||||
|
||||
|
||||
public virtual void Hide()
|
||||
{
|
||||
if (base.Handle == IntPtr.Zero)
|
||||
if (Handle == nint.Zero)
|
||||
return;
|
||||
User32.ShowWindow(base.Handle, User32.SW_HIDE);
|
||||
this.DestroyHandle();
|
||||
User32.ShowWindow(Handle, User32.SW_HIDE);
|
||||
DestroyHandle();
|
||||
}
|
||||
|
||||
|
||||
public virtual void Close()
|
||||
{
|
||||
this.Hide();
|
||||
this.Dispose();
|
||||
Hide();
|
||||
Dispose();
|
||||
}
|
||||
|
||||
private void CreateWindowOnly()
|
||||
@@ -85,55 +85,55 @@ namespace OSD
|
||||
|
||||
CreateParams params1 = new CreateParams();
|
||||
params1.Caption = "FloatingNativeWindow";
|
||||
int nX = this._location.X;
|
||||
int nY = this._location.Y;
|
||||
Screen screen1 = Screen.FromHandle(base.Handle);
|
||||
if ((nX + this._size.Width) > screen1.Bounds.Width)
|
||||
int nX = _location.X;
|
||||
int nY = _location.Y;
|
||||
Screen screen1 = Screen.FromHandle(Handle);
|
||||
if (nX + _size.Width > screen1.Bounds.Width)
|
||||
{
|
||||
nX = screen1.Bounds.Width - this._size.Width;
|
||||
nX = screen1.Bounds.Width - _size.Width;
|
||||
}
|
||||
if ((nY + this._size.Height) > screen1.Bounds.Height)
|
||||
if (nY + _size.Height > screen1.Bounds.Height)
|
||||
{
|
||||
nY = screen1.Bounds.Height - this._size.Height;
|
||||
nY = screen1.Bounds.Height - _size.Height;
|
||||
}
|
||||
this._location = new Point(nX, nY);
|
||||
Size size1 = this._size;
|
||||
Point point1 = this._location;
|
||||
_location = new Point(nX, nY);
|
||||
Size size1 = _size;
|
||||
Point point1 = _location;
|
||||
params1.X = nX;
|
||||
params1.Y = nY;
|
||||
params1.Height = size1.Height;
|
||||
params1.Width = size1.Width;
|
||||
params1.Parent = IntPtr.Zero;
|
||||
params1.Parent = nint.Zero;
|
||||
uint ui = User32.WS_POPUP;
|
||||
params1.Style = (int)ui;
|
||||
params1.ExStyle = User32.WS_EX_TOPMOST | User32.WS_EX_TOOLWINDOW | User32.WS_EX_LAYERED | User32.WS_EX_NOACTIVATE | User32.WS_EX_TRANSPARENT;
|
||||
this.CreateHandle(params1);
|
||||
this.UpdateLayeredWindow();
|
||||
CreateHandle(params1);
|
||||
UpdateLayeredWindow();
|
||||
}
|
||||
|
||||
|
||||
|
||||
protected virtual void SetBoundsCore(int x, int y, int width, int height)
|
||||
{
|
||||
if (((this.X != x) || (this.Y != y)) || ((this.Width != width) || (this.Height != height)))
|
||||
if (X != x || Y != y || Width != width || Height != height)
|
||||
{
|
||||
if (base.Handle != IntPtr.Zero)
|
||||
if (Handle != nint.Zero)
|
||||
{
|
||||
int num1 = 20;
|
||||
if ((this.X == x) && (this.Y == y))
|
||||
if (X == x && Y == y)
|
||||
{
|
||||
num1 |= 2;
|
||||
}
|
||||
if ((this.Width == width) && (this.Height == height))
|
||||
if (Width == width && Height == height)
|
||||
{
|
||||
num1 |= 1;
|
||||
}
|
||||
User32.SetWindowPos(base.Handle, IntPtr.Zero, x, y, width, height, (uint)num1);
|
||||
User32.SetWindowPos(Handle, nint.Zero, x, y, width, height, (uint)num1);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.Location = new Point(x, y);
|
||||
this.Size = new Size(width, height);
|
||||
Location = new Point(x, y);
|
||||
Size = new Size(width, height);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -147,20 +147,20 @@ namespace OSD
|
||||
/// </summary>
|
||||
public virtual Point Location
|
||||
{
|
||||
get { return this._location; }
|
||||
get { return _location; }
|
||||
set
|
||||
{
|
||||
if (base.Handle != IntPtr.Zero)
|
||||
if (Handle != nint.Zero)
|
||||
{
|
||||
this.SetBoundsCore(value.X, value.Y, this._size.Width, this._size.Height);
|
||||
SetBoundsCore(value.X, value.Y, _size.Width, _size.Height);
|
||||
RECT rect = new RECT();
|
||||
User32.GetWindowRect(base.Handle, ref rect);
|
||||
this._location = new Point(rect.left, rect.top);
|
||||
this.UpdateLayeredWindow();
|
||||
User32.GetWindowRect(Handle, ref rect);
|
||||
_location = new Point(rect.left, rect.top);
|
||||
UpdateLayeredWindow();
|
||||
}
|
||||
else
|
||||
{
|
||||
this._location = value;
|
||||
_location = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -169,20 +169,20 @@ namespace OSD
|
||||
/// </summary>
|
||||
public virtual Size Size
|
||||
{
|
||||
get { return this._size; }
|
||||
get { return _size; }
|
||||
set
|
||||
{
|
||||
if (base.Handle != IntPtr.Zero)
|
||||
if (Handle != nint.Zero)
|
||||
{
|
||||
this.SetBoundsCore(this._location.X, this._location.Y, value.Width, value.Height);
|
||||
SetBoundsCore(_location.X, _location.Y, value.Width, value.Height);
|
||||
RECT rect = new RECT();
|
||||
User32.GetWindowRect(base.Handle, ref rect);
|
||||
this._size = new Size(rect.right - rect.left, rect.bottom - rect.top);
|
||||
this.UpdateLayeredWindow();
|
||||
User32.GetWindowRect(Handle, ref rect);
|
||||
_size = new Size(rect.right - rect.left, rect.bottom - rect.top);
|
||||
UpdateLayeredWindow();
|
||||
}
|
||||
else
|
||||
{
|
||||
this._size = value;
|
||||
_size = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -191,10 +191,10 @@ namespace OSD
|
||||
/// </summary>
|
||||
public int Height
|
||||
{
|
||||
get { return this._size.Height; }
|
||||
get { return _size.Height; }
|
||||
set
|
||||
{
|
||||
this._size = new Size(this._size.Width, value);
|
||||
_size = new Size(_size.Width, value);
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
@@ -202,10 +202,10 @@ namespace OSD
|
||||
/// </summary>
|
||||
public int Width
|
||||
{
|
||||
get { return this._size.Width; }
|
||||
get { return _size.Width; }
|
||||
set
|
||||
{
|
||||
this._size = new Size(value, this._size.Height);
|
||||
_size = new Size(value, _size.Height);
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
@@ -213,10 +213,10 @@ namespace OSD
|
||||
/// </summary>
|
||||
public int X
|
||||
{
|
||||
get { return this._location.X; }
|
||||
get { return _location.X; }
|
||||
set
|
||||
{
|
||||
this.Location = new Point(value, this.Location.Y);
|
||||
Location = new Point(value, Location.Y);
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
@@ -224,10 +224,10 @@ namespace OSD
|
||||
/// </summary>
|
||||
public int Y
|
||||
{
|
||||
get { return this._location.Y; }
|
||||
get { return _location.Y; }
|
||||
set
|
||||
{
|
||||
this.Location = new Point(this.Location.X, value);
|
||||
Location = new Point(Location.X, value);
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
@@ -237,7 +237,7 @@ namespace OSD
|
||||
{
|
||||
get
|
||||
{
|
||||
return new Rectangle(new Point(0, 0), this._size);
|
||||
return new Rectangle(new Point(0, 0), _size);
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
@@ -245,12 +245,12 @@ namespace OSD
|
||||
/// </summary>
|
||||
public byte Alpha
|
||||
{
|
||||
get { return this._alpha; }
|
||||
get { return _alpha; }
|
||||
set
|
||||
{
|
||||
if (this._alpha == value) return;
|
||||
this._alpha = value;
|
||||
this.UpdateLayeredWindow();
|
||||
if (_alpha == value) return;
|
||||
_alpha = value;
|
||||
UpdateLayeredWindow();
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
@@ -258,15 +258,15 @@ namespace OSD
|
||||
#region IDisposable Members
|
||||
public void Dispose()
|
||||
{
|
||||
this.Dispose(true);
|
||||
Dispose(true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
private void Dispose(bool disposing)
|
||||
{
|
||||
if (!this._disposed)
|
||||
if (!_disposed)
|
||||
{
|
||||
this.DestroyHandle();
|
||||
this._disposed = true;
|
||||
DestroyHandle();
|
||||
_disposed = true;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
@@ -299,16 +299,16 @@ namespace OSD
|
||||
{
|
||||
public uint cbSize;
|
||||
public uint dwFlags;
|
||||
public IntPtr hWnd;
|
||||
public nint hWnd;
|
||||
public uint dwHoverTime;
|
||||
}
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal struct MSG
|
||||
{
|
||||
public IntPtr hwnd;
|
||||
public nint hwnd;
|
||||
public int message;
|
||||
public IntPtr wParam;
|
||||
public IntPtr lParam;
|
||||
public nint wParam;
|
||||
public nint lParam;
|
||||
public int time;
|
||||
public int pt_x;
|
||||
public int pt_y;
|
||||
@@ -345,69 +345,69 @@ namespace OSD
|
||||
{
|
||||
}
|
||||
[DllImport("User32.dll", CharSet = CharSet.Auto)]
|
||||
internal static extern bool AnimateWindow(IntPtr hWnd, uint dwTime, uint dwFlags);
|
||||
internal static extern bool AnimateWindow(nint hWnd, uint dwTime, uint dwFlags);
|
||||
[DllImport("User32.dll", CharSet = CharSet.Auto)]
|
||||
internal static extern bool ClientToScreen(IntPtr hWnd, ref POINT pt);
|
||||
internal static extern bool ClientToScreen(nint hWnd, ref POINT pt);
|
||||
[DllImport("User32.dll", CharSet = CharSet.Auto)]
|
||||
internal static extern bool DispatchMessage(ref MSG msg);
|
||||
[DllImport("User32.dll", CharSet = CharSet.Auto)]
|
||||
internal static extern bool DrawFocusRect(IntPtr hWnd, ref RECT rect);
|
||||
internal static extern bool DrawFocusRect(nint hWnd, ref RECT rect);
|
||||
[DllImport("User32.dll", CharSet = CharSet.Auto)]
|
||||
internal static extern IntPtr GetDC(IntPtr hWnd);
|
||||
internal static extern nint GetDC(nint hWnd);
|
||||
[DllImport("User32.dll", CharSet = CharSet.Auto)]
|
||||
internal static extern IntPtr GetFocus();
|
||||
internal static extern nint GetFocus();
|
||||
[DllImport("User32.dll", CharSet = CharSet.Auto)]
|
||||
internal static extern ushort GetKeyState(int virtKey);
|
||||
[DllImport("User32.dll", CharSet = CharSet.Auto)]
|
||||
internal static extern bool GetMessage(ref MSG msg, int hWnd, uint wFilterMin, uint wFilterMax);
|
||||
[DllImport("User32.dll", CharSet = CharSet.Auto)]
|
||||
internal static extern IntPtr GetParent(IntPtr hWnd);
|
||||
internal static extern nint GetParent(nint hWnd);
|
||||
[DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
|
||||
public static extern bool GetClientRect(IntPtr hWnd, [In, Out] ref RECT rect);
|
||||
public static extern bool GetClientRect(nint hWnd, [In, Out] ref RECT rect);
|
||||
[DllImport("User32.dll", CharSet = CharSet.Auto)]
|
||||
internal static extern int GetWindowLong(IntPtr hWnd, int nIndex);
|
||||
internal static extern int GetWindowLong(nint hWnd, int nIndex);
|
||||
[DllImport("User32.dll", CharSet = CharSet.Auto)]
|
||||
internal static extern IntPtr GetWindow(IntPtr hWnd, int cmd);
|
||||
internal static extern nint GetWindow(nint hWnd, int cmd);
|
||||
[DllImport("User32.dll", CharSet = CharSet.Auto)]
|
||||
internal static extern bool GetWindowRect(IntPtr hWnd, ref RECT rect);
|
||||
internal static extern bool GetWindowRect(nint hWnd, ref RECT rect);
|
||||
[DllImport("User32.dll", CharSet = CharSet.Auto)]
|
||||
internal static extern bool HideCaret(IntPtr hWnd);
|
||||
internal static extern bool HideCaret(nint hWnd);
|
||||
[DllImport("User32.dll", CharSet = CharSet.Auto)]
|
||||
internal static extern bool InvalidateRect(IntPtr hWnd, ref RECT rect, bool erase);
|
||||
internal static extern bool InvalidateRect(nint hWnd, ref RECT rect, bool erase);
|
||||
[DllImport("User32.dll", CharSet = CharSet.Auto)]
|
||||
internal static extern IntPtr LoadCursor(IntPtr hInstance, uint cursor);
|
||||
internal static extern nint LoadCursor(nint hInstance, uint cursor);
|
||||
[DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
|
||||
public static extern int MapWindowPoints(IntPtr hWndFrom, IntPtr hWndTo, [In, Out] ref RECT rect, int cPoints);
|
||||
public static extern int MapWindowPoints(nint hWndFrom, nint hWndTo, [In, Out] ref RECT rect, int cPoints);
|
||||
[DllImport("User32.dll", CharSet = CharSet.Auto)]
|
||||
internal static extern bool MoveWindow(IntPtr hWnd, int x, int y, int width, int height, bool repaint);
|
||||
internal static extern bool MoveWindow(nint hWnd, int x, int y, int width, int height, bool repaint);
|
||||
[DllImport("User32.dll", CharSet = CharSet.Auto)]
|
||||
internal static extern bool PeekMessage(ref MSG msg, int hWnd, uint wFilterMin, uint wFilterMax, uint wFlag);
|
||||
[DllImport("User32.dll", CharSet = CharSet.Auto)]
|
||||
internal static extern bool PostMessage(IntPtr hWnd, int Msg, uint wParam, uint lParam);
|
||||
internal static extern bool PostMessage(nint hWnd, int Msg, uint wParam, uint lParam);
|
||||
[DllImport("User32.dll", CharSet = CharSet.Auto)]
|
||||
internal static extern bool ReleaseCapture();
|
||||
[DllImport("User32.dll", CharSet = CharSet.Auto)]
|
||||
internal static extern int ReleaseDC(IntPtr hWnd, IntPtr hDC);
|
||||
internal static extern int ReleaseDC(nint hWnd, nint hDC);
|
||||
[DllImport("User32.dll", CharSet = CharSet.Auto)]
|
||||
internal static extern bool ScreenToClient(IntPtr hWnd, ref POINT pt);
|
||||
internal static extern bool ScreenToClient(nint hWnd, ref POINT pt);
|
||||
[DllImport("User32.dll", CharSet = CharSet.Auto)]
|
||||
internal static extern uint SendMessage(IntPtr hWnd, int Msg, uint wParam, uint lParam);
|
||||
internal static extern uint SendMessage(nint hWnd, int Msg, uint wParam, uint lParam);
|
||||
[DllImport("User32.dll", CharSet = CharSet.Auto)]
|
||||
internal static extern IntPtr SetCursor(IntPtr hCursor);
|
||||
internal static extern nint SetCursor(nint hCursor);
|
||||
[DllImport("User32.dll", CharSet = CharSet.Auto)]
|
||||
internal static extern IntPtr SetFocus(IntPtr hWnd);
|
||||
internal static extern nint SetFocus(nint hWnd);
|
||||
[DllImport("User32.dll", CharSet = CharSet.Auto)]
|
||||
internal static extern int SetWindowLong(IntPtr hWnd, int nIndex, int newLong);
|
||||
internal static extern int SetWindowLong(nint hWnd, int nIndex, int newLong);
|
||||
[DllImport("User32.dll", CharSet = CharSet.Auto)]
|
||||
internal static extern int SetWindowPos(IntPtr hWnd, IntPtr hWndAfter, int X, int Y, int Width, int Height, uint flags);
|
||||
internal static extern int SetWindowPos(nint hWnd, nint hWndAfter, int X, int Y, int Width, int Height, uint flags);
|
||||
[DllImport("User32.dll", CharSet = CharSet.Auto)]
|
||||
internal static extern bool SetWindowRgn(IntPtr hWnd, IntPtr hRgn, bool redraw);
|
||||
internal static extern bool SetWindowRgn(nint hWnd, nint hRgn, bool redraw);
|
||||
[DllImport("User32.dll", CharSet = CharSet.Auto)]
|
||||
internal static extern bool ShowCaret(IntPtr hWnd);
|
||||
internal static extern bool ShowCaret(nint hWnd);
|
||||
[DllImport("User32.dll", CharSet = CharSet.Auto)]
|
||||
internal static extern bool SetCapture(IntPtr hWnd);
|
||||
internal static extern bool SetCapture(nint hWnd);
|
||||
[DllImport("User32.dll", CharSet = CharSet.Auto)]
|
||||
internal static extern int ShowWindow(IntPtr hWnd, short cmdShow);
|
||||
internal static extern int ShowWindow(nint hWnd, short cmdShow);
|
||||
[DllImport("User32.dll", CharSet = CharSet.Auto)]
|
||||
internal static extern bool SystemParametersInfo(uint uiAction, uint uiParam, ref int bRetValue, uint fWinINI);
|
||||
[DllImport("User32.dll", CharSet = CharSet.Auto)]
|
||||
@@ -415,9 +415,9 @@ namespace OSD
|
||||
[DllImport("User32.dll", CharSet = CharSet.Auto)]
|
||||
internal static extern bool TranslateMessage(ref MSG msg);
|
||||
[DllImport("User32.dll", CharSet = CharSet.Auto)]
|
||||
internal static extern bool UpdateLayeredWindow(IntPtr hwnd, IntPtr hdcDst, ref POINT pptDst, ref SIZE psize, IntPtr hdcSrc, ref POINT pprSrc, int crKey, ref BLENDFUNCTION pblend, int dwFlags);
|
||||
internal static extern bool UpdateLayeredWindow(nint hwnd, nint hdcDst, ref POINT pptDst, ref SIZE psize, nint hdcSrc, ref POINT pprSrc, int crKey, ref BLENDFUNCTION pblend, int dwFlags);
|
||||
[DllImport("User32.dll", CharSet = CharSet.Auto)]
|
||||
internal static extern bool UpdateWindow(IntPtr hwnd);
|
||||
internal static extern bool UpdateWindow(nint hwnd);
|
||||
[DllImport("User32.dll", CharSet = CharSet.Auto)]
|
||||
internal static extern bool WaitMessage();
|
||||
[DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
|
||||
@@ -431,25 +431,25 @@ namespace OSD
|
||||
{
|
||||
}
|
||||
[DllImport("gdi32.dll", CharSet = CharSet.Auto)]
|
||||
internal static extern int CombineRgn(IntPtr dest, IntPtr src1, IntPtr src2, int flags);
|
||||
internal static extern int CombineRgn(nint dest, nint src1, nint src2, int flags);
|
||||
[DllImport("gdi32.dll", CharSet = CharSet.Auto)]
|
||||
internal static extern IntPtr CreateBrushIndirect(ref LOGBRUSH brush);
|
||||
internal static extern nint CreateBrushIndirect(ref LOGBRUSH brush);
|
||||
[DllImport("gdi32.dll", CharSet = CharSet.Auto)]
|
||||
internal static extern IntPtr CreateCompatibleDC(IntPtr hDC);
|
||||
internal static extern nint CreateCompatibleDC(nint hDC);
|
||||
[DllImport("gdi32.dll", CharSet = CharSet.Auto)]
|
||||
internal static extern IntPtr CreateRectRgnIndirect(ref RECT rect);
|
||||
internal static extern nint CreateRectRgnIndirect(ref RECT rect);
|
||||
[DllImport("gdi32.dll", CharSet = CharSet.Auto)]
|
||||
internal static extern bool DeleteDC(IntPtr hDC);
|
||||
internal static extern bool DeleteDC(nint hDC);
|
||||
[DllImport("gdi32.dll", CharSet = CharSet.Auto)]
|
||||
internal static extern IntPtr DeleteObject(IntPtr hObject);
|
||||
internal static extern nint DeleteObject(nint hObject);
|
||||
[DllImport("gdi32.dll", CharSet = CharSet.Auto)]
|
||||
internal static extern int GetClipBox(IntPtr hDC, ref RECT rectBox);
|
||||
internal static extern int GetClipBox(nint hDC, ref RECT rectBox);
|
||||
[DllImport("gdi32.dll", CharSet = CharSet.Auto)]
|
||||
internal static extern bool PatBlt(IntPtr hDC, int x, int y, int width, int height, uint flags);
|
||||
internal static extern bool PatBlt(nint hDC, int x, int y, int width, int height, uint flags);
|
||||
[DllImport("gdi32.dll", CharSet = CharSet.Auto)]
|
||||
internal static extern int SelectClipRgn(IntPtr hDC, IntPtr hRgn);
|
||||
internal static extern int SelectClipRgn(nint hDC, nint hRgn);
|
||||
[DllImport("gdi32.dll", CharSet = CharSet.Auto)]
|
||||
internal static extern IntPtr SelectObject(IntPtr hDC, IntPtr hObject);
|
||||
internal static extern nint SelectObject(nint hDC, nint hObject);
|
||||
}
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct LOGBRUSH
|
||||
@@ -1,13 +1,27 @@
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Text;
|
||||
using Microsoft.Win32;
|
||||
using System.Diagnostics;
|
||||
using Microsoft.Win32;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace GHelper
|
||||
namespace GHelper.Helpers
|
||||
{
|
||||
public static class OptimizationService
|
||||
{
|
||||
public static void SetChargeLimit (int newValue)
|
||||
|
||||
static List<string> services = new() {
|
||||
"AsusAppService",
|
||||
"ASUSLinkNear",
|
||||
"ASUSLinkRemote",
|
||||
"ASUSSoftwareManager",
|
||||
"ASUSSwitch",
|
||||
"ASUSSystemAnalysis",
|
||||
"ASUSSystemDiagnosis",
|
||||
"ArmouryCrateControlInterface",
|
||||
"AsusCertService",
|
||||
"ASUSOptimization"
|
||||
};
|
||||
|
||||
public static void SetChargeLimit(int newValue)
|
||||
{
|
||||
// Set the path to the .ini file
|
||||
string path = @"C:\ProgramData\ASUS\ASUS System Control Interface\ASUSOptimization\Customization.ini";
|
||||
@@ -38,7 +52,17 @@ namespace GHelper
|
||||
|
||||
public static bool IsRunning()
|
||||
{
|
||||
return (Process.GetProcessesByName("AsusOptimization").Count() > 0);
|
||||
return Process.GetProcessesByName("AsusOptimization").Count() > 0;
|
||||
}
|
||||
|
||||
public static int GetRunningCount()
|
||||
{
|
||||
int count = 0;
|
||||
foreach (string service in services)
|
||||
{
|
||||
if (Process.GetProcessesByName(service).Count() > 0) count++;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
@@ -60,6 +84,23 @@ namespace GHelper
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static void StopAsusServices()
|
||||
{
|
||||
foreach (string service in services)
|
||||
{
|
||||
ProcessHelper.StopDisableService(service);
|
||||
}
|
||||
}
|
||||
|
||||
public static void StartAsusServices()
|
||||
{
|
||||
foreach (string service in services)
|
||||
{
|
||||
ProcessHelper.StartEnableService(service);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
146
app/Helpers/ProcessHelper.cs
Normal file
146
app/Helpers/ProcessHelper.cs
Normal file
@@ -0,0 +1,146 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Security.Principal;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace GHelper.Helpers
|
||||
{
|
||||
public static class ProcessHelper
|
||||
{
|
||||
private static long lastAdmin;
|
||||
|
||||
public static void CheckAlreadyRunning()
|
||||
{
|
||||
Process currentProcess = Process.GetCurrentProcess();
|
||||
Process[] processes = Process.GetProcessesByName(currentProcess.ProcessName);
|
||||
|
||||
if (processes.Length > 1)
|
||||
{
|
||||
foreach (Process process in processes)
|
||||
if (process.Id != currentProcess.Id)
|
||||
try
|
||||
{
|
||||
process.Kill();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.WriteLine(ex.ToString());
|
||||
MessageBox.Show(Properties.Strings.AppAlreadyRunningText, Properties.Strings.AppAlreadyRunning, MessageBoxButtons.OK);
|
||||
Application.Exit();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static bool IsUserAdministrator()
|
||||
{
|
||||
WindowsIdentity identity = WindowsIdentity.GetCurrent();
|
||||
WindowsPrincipal principal = new WindowsPrincipal(identity);
|
||||
return principal.IsInRole(WindowsBuiltInRole.Administrator);
|
||||
}
|
||||
|
||||
public static void RunAsAdmin(string? param = null)
|
||||
{
|
||||
|
||||
if (Math.Abs(DateTimeOffset.Now.ToUnixTimeMilliseconds() - lastAdmin) < 2000) return;
|
||||
lastAdmin = DateTimeOffset.Now.ToUnixTimeMilliseconds();
|
||||
|
||||
// Check if the current user is an administrator
|
||||
if (!IsUserAdministrator())
|
||||
{
|
||||
ProcessStartInfo startInfo = new ProcessStartInfo();
|
||||
startInfo.UseShellExecute = true;
|
||||
startInfo.WorkingDirectory = Environment.CurrentDirectory;
|
||||
startInfo.FileName = Application.ExecutablePath;
|
||||
startInfo.Arguments = param;
|
||||
startInfo.Verb = "runas";
|
||||
try
|
||||
{
|
||||
Process.Start(startInfo);
|
||||
Application.Exit();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.WriteLine(ex.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static void KillByName(string name)
|
||||
{
|
||||
foreach (var process in Process.GetProcessesByName(name))
|
||||
{
|
||||
try
|
||||
{
|
||||
process.Kill();
|
||||
Logger.WriteLine($"Stopped: {process.ProcessName}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.WriteLine($"Failed to stop: {process.ProcessName} {ex.Message}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void KillByProcess(Process process)
|
||||
{
|
||||
try
|
||||
{
|
||||
process.Kill();
|
||||
Logger.WriteLine($"Stopped: {process.ProcessName}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.WriteLine($"Failed to stop: {process.ProcessName} {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
public static void StopDisableService(string serviceName)
|
||||
{
|
||||
try
|
||||
{
|
||||
string script = $"Set-Service -Name \"{serviceName}\" -Status stopped -StartupType disabled";
|
||||
Logger.WriteLine(script);
|
||||
RunCMD("powershell", script);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.WriteLine(ex.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
public static void StartEnableService(string serviceName)
|
||||
{
|
||||
try
|
||||
{
|
||||
string script = $"Set-Service -Name \"{serviceName}\" -Status running -StartupType Automatic";
|
||||
Logger.WriteLine(script);
|
||||
RunCMD("powershell", script);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.WriteLine(ex.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
public static void RunCMD(string name, string args)
|
||||
{
|
||||
var cmd = new Process();
|
||||
cmd.StartInfo.UseShellExecute = false;
|
||||
cmd.StartInfo.CreateNoWindow = true;
|
||||
cmd.StartInfo.RedirectStandardOutput = true;
|
||||
cmd.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
|
||||
cmd.StartInfo.FileName = name;
|
||||
cmd.StartInfo.Arguments = args;
|
||||
cmd.Start();
|
||||
Logger.WriteLine(cmd.StandardOutput.ReadToEnd());
|
||||
cmd.WaitForExit();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
namespace GHelper
|
||||
namespace GHelper.Helpers
|
||||
{
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
@@ -1,4 +1,4 @@
|
||||
using GHelper;
|
||||
using GHelper.Helpers;
|
||||
using Microsoft.Win32.TaskScheduler;
|
||||
using System.Diagnostics;
|
||||
using System.Security.Principal;
|
||||
@@ -16,7 +16,7 @@ public class Startup
|
||||
|
||||
public static void ReScheduleAdmin()
|
||||
{
|
||||
if (Program.IsUserAdministrator() && IsScheduled())
|
||||
if (ProcessHelper.IsUserAdministrator() && IsScheduled())
|
||||
{
|
||||
UnSchedule();
|
||||
Schedule();
|
||||
@@ -34,11 +34,12 @@ public class Startup
|
||||
|
||||
using (TaskDefinition td = TaskService.Instance.NewTask())
|
||||
{
|
||||
|
||||
td.RegistrationInfo.Description = "G-Helper Auto Start";
|
||||
td.Triggers.Add(new LogonTrigger { UserId = userId });
|
||||
td.Triggers.Add(new LogonTrigger { UserId = userId, Delay = TimeSpan.FromSeconds(1) });
|
||||
td.Actions.Add(strExeFilePath);
|
||||
|
||||
if (Program.IsUserAdministrator())
|
||||
if (ProcessHelper.IsUserAdministrator())
|
||||
td.Principal.RunLevel = TaskRunLevel.Highest;
|
||||
|
||||
td.Settings.StopIfGoingOnBatteries = false;
|
||||
@@ -54,10 +55,10 @@ public class Startup
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
if (Program.IsUserAdministrator())
|
||||
if (ProcessHelper.IsUserAdministrator())
|
||||
MessageBox.Show("Can't create a start up task. Try running Task Scheduler by hand and manually deleting GHelper task if it exists there.", "Scheduler Error", MessageBoxButtons.OK);
|
||||
else
|
||||
Program.RunAsAdmin();
|
||||
else
|
||||
ProcessHelper.RunAsAdmin();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,10 +74,10 @@ public class Startup
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
if (Program.IsUserAdministrator())
|
||||
if (ProcessHelper.IsUserAdministrator())
|
||||
MessageBox.Show("Can't remove task. Try running Task Scheduler by hand and manually deleting GHelper task if it exists there.", "Scheduler Error", MessageBoxButtons.OK);
|
||||
else
|
||||
Program.RunAsAdmin();
|
||||
ProcessHelper.RunAsAdmin();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,6 @@
|
||||
using System.Diagnostics;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Drawing2D;
|
||||
using OSD;
|
||||
using System.Drawing.Drawing2D;
|
||||
|
||||
|
||||
namespace GHelper
|
||||
namespace GHelper.Helpers
|
||||
{
|
||||
|
||||
static class Drawing
|
||||
@@ -51,10 +47,13 @@ namespace GHelper
|
||||
BacklightDown,
|
||||
Touchpad,
|
||||
Microphone,
|
||||
MicrophoneMute
|
||||
MicrophoneMute,
|
||||
FnLock,
|
||||
Battery,
|
||||
Charger
|
||||
}
|
||||
|
||||
public class ToastForm : OSDNativeForm
|
||||
public class ToastForm : OSDNativeForm
|
||||
{
|
||||
|
||||
protected static string toastText = "Balanced";
|
||||
@@ -71,8 +70,8 @@ namespace GHelper
|
||||
|
||||
protected override void PerformPaint(PaintEventArgs e)
|
||||
{
|
||||
Brush brush = new SolidBrush(Color.FromArgb(150,Color.Black));
|
||||
Drawing.FillRoundedRectangle(e.Graphics, brush, this.Bound, 10);
|
||||
Brush brush = new SolidBrush(Color.FromArgb(150, Color.Black));
|
||||
e.Graphics.FillRoundedRectangle(brush, Bound, 10);
|
||||
|
||||
StringFormat format = new StringFormat();
|
||||
format.LineAlignment = StringAlignment.Center;
|
||||
@@ -103,6 +102,15 @@ namespace GHelper
|
||||
case ToastIcon.Touchpad:
|
||||
icon = Properties.Resources.icons8_touchpad_96;
|
||||
break;
|
||||
case ToastIcon.FnLock:
|
||||
icon = Properties.Resources.icons8_function;
|
||||
break;
|
||||
case ToastIcon.Battery:
|
||||
icon = Properties.Resources.icons8_charged_battery_96;
|
||||
break;
|
||||
case ToastIcon.Charger:
|
||||
icon = Properties.Resources.icons8_charging_battery_96;
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
@@ -117,34 +125,37 @@ namespace GHelper
|
||||
e.Graphics.DrawString(toastText,
|
||||
new Font("Segoe UI", 36f, FontStyle.Bold, GraphicsUnit.Pixel),
|
||||
new SolidBrush(Color.White),
|
||||
new PointF(this.Bound.Width / 2 + shiftX, this.Bound.Height / 2),
|
||||
new PointF(Bound.Width / 2 + shiftX, Bound.Height / 2),
|
||||
format);
|
||||
|
||||
}
|
||||
|
||||
public void RunToast(string text, ToastIcon? icon = null)
|
||||
{
|
||||
//Hide();
|
||||
timer.Stop();
|
||||
Program.settingsForm.Invoke(delegate
|
||||
{
|
||||
//Hide();
|
||||
timer.Stop();
|
||||
|
||||
toastText = text;
|
||||
toastIcon = icon;
|
||||
toastText = text;
|
||||
toastIcon = icon;
|
||||
|
||||
Screen screen1 = Screen.FromHandle(base.Handle);
|
||||
Screen screen1 = Screen.FromHandle(Handle);
|
||||
|
||||
Width = 300;
|
||||
Height = 100;
|
||||
X = (screen1.Bounds.Width - this.Width)/2;
|
||||
Y = screen1.Bounds.Height - 300 - this.Height;
|
||||
Width = Math.Max(300, 100 + toastText.Length * 22);
|
||||
Height = 100;
|
||||
X = (screen1.Bounds.Width - Width) / 2;
|
||||
Y = screen1.Bounds.Height - 300 - Height;
|
||||
|
||||
Show();
|
||||
timer.Start();
|
||||
});
|
||||
|
||||
Show();
|
||||
timer.Start();
|
||||
}
|
||||
|
||||
private void timer_Tick(object? sender, EventArgs e)
|
||||
{
|
||||
Debug.WriteLine("Toast end");
|
||||
|
||||
//Debug.WriteLine("Toast end");
|
||||
Hide();
|
||||
timer.Stop();
|
||||
}
|
||||
@@ -1,63 +1,25 @@
|
||||
using HidLibrary;
|
||||
using GHelper.Display;
|
||||
using GHelper.Helpers;
|
||||
using GHelper.Mode;
|
||||
using Microsoft.Win32;
|
||||
using NAudio.CoreAudioApi;
|
||||
using System.Diagnostics;
|
||||
using System.Management;
|
||||
|
||||
namespace GHelper
|
||||
namespace GHelper.Input
|
||||
{
|
||||
public class KeyboardListener
|
||||
{
|
||||
|
||||
CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
|
||||
|
||||
public KeyboardListener(Action<int> KeyHandler)
|
||||
{
|
||||
HidDevice? input = AsusUSB.GetDevice();
|
||||
if (input == null) return;
|
||||
|
||||
Logger.WriteLine($"Input: {input.DevicePath}");
|
||||
|
||||
var task = Task.Run(() =>
|
||||
{
|
||||
try
|
||||
{
|
||||
while (!cancellationTokenSource.Token.IsCancellationRequested)
|
||||
{
|
||||
var data = input.Read().Data;
|
||||
if (data.Length > 1 && data[0] == AsusUSB.INPUT_HID_ID && data[1] > 0)
|
||||
{
|
||||
Logger.WriteLine($"Key: {data[1]}");
|
||||
KeyHandler(data[1]);
|
||||
}
|
||||
}
|
||||
Logger.WriteLine("Listener stopped");
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.WriteLine(ex.ToString());
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
cancellationTokenSource?.Cancel();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public class InputDispatcher
|
||||
{
|
||||
System.Timers.Timer timer = new System.Timers.Timer(1000);
|
||||
public bool backlight = true;
|
||||
public static bool backlightActivity = true;
|
||||
|
||||
public static Keys keyProfile = Keys.F5;
|
||||
public static Keys keyApp = Keys.F12;
|
||||
|
||||
static ModeControl modeControl = Program.modeControl;
|
||||
static ScreenControl screenControl = new ScreenControl();
|
||||
|
||||
KeyboardListener listener;
|
||||
KeyboardHook hook = new KeyboardHook();
|
||||
|
||||
@@ -80,27 +42,28 @@ namespace GHelper
|
||||
|
||||
private void Timer_Elapsed(object? sender, System.Timers.ElapsedEventArgs e)
|
||||
{
|
||||
TimeSpan iddle = NativeMethods.GetIdleTime();
|
||||
if (GetBacklight() == 0) return;
|
||||
|
||||
TimeSpan iddle = NativeMethods.GetIdleTime();
|
||||
int kb_timeout;
|
||||
|
||||
if (SystemInformation.PowerStatus.PowerLineStatus == PowerLineStatus.Online)
|
||||
kb_timeout = AppConfig.getConfig("keyboard_ac_timeout", 0);
|
||||
kb_timeout = AppConfig.Get("keyboard_ac_timeout", 0);
|
||||
else
|
||||
kb_timeout = AppConfig.getConfig("keyboard_timeout", 60);
|
||||
kb_timeout = AppConfig.Get("keyboard_timeout", 60);
|
||||
|
||||
if (kb_timeout == 0) return;
|
||||
|
||||
if (backlight && iddle.TotalSeconds > kb_timeout)
|
||||
if (backlightActivity && iddle.TotalSeconds > kb_timeout)
|
||||
{
|
||||
backlight = false;
|
||||
AsusUSB.ApplyBrightness(0);
|
||||
backlightActivity = false;
|
||||
AsusUSB.ApplyBrightness(0, "Timeout");
|
||||
}
|
||||
|
||||
if (!backlight && iddle.TotalSeconds < kb_timeout)
|
||||
if (!backlightActivity && iddle.TotalSeconds < kb_timeout)
|
||||
{
|
||||
backlight = true;
|
||||
AsusUSB.ApplyBrightness(AppConfig.getConfig("keyboard_brightness"));
|
||||
backlightActivity = true;
|
||||
SetBacklightAuto();
|
||||
}
|
||||
|
||||
//Debug.WriteLine(iddle.TotalSeconds);
|
||||
@@ -114,14 +77,16 @@ namespace GHelper
|
||||
|
||||
if (!OptimizationService.IsRunning())
|
||||
listener = new KeyboardListener(HandleEvent);
|
||||
else
|
||||
Logger.WriteLine("Optimization service is running");
|
||||
|
||||
InitBacklightTimer();
|
||||
}
|
||||
|
||||
public void InitBacklightTimer()
|
||||
{
|
||||
timer.Enabled = (AppConfig.getConfig("keyboard_timeout") > 0 && SystemInformation.PowerStatus.PowerLineStatus != PowerLineStatus.Online) ||
|
||||
(AppConfig.getConfig("keyboard_ac_timeout") > 0 && SystemInformation.PowerStatus.PowerLineStatus == PowerLineStatus.Online);
|
||||
timer.Enabled = AppConfig.Get("keyboard_timeout") > 0 && SystemInformation.PowerStatus.PowerLineStatus != PowerLineStatus.Online ||
|
||||
AppConfig.Get("keyboard_ac_timeout") > 0 && SystemInformation.PowerStatus.PowerLineStatus == PowerLineStatus.Online;
|
||||
}
|
||||
|
||||
|
||||
@@ -131,29 +96,29 @@ namespace GHelper
|
||||
hook.UnregisterAll();
|
||||
|
||||
// CTRL + SHIFT + F5 to cycle profiles
|
||||
if (AppConfig.getConfig("keybind_profile") != -1) keyProfile = (Keys)AppConfig.getConfig("keybind_profile");
|
||||
if (AppConfig.getConfig("keybind_app") != -1) keyApp = (Keys)AppConfig.getConfig("keybind_app");
|
||||
if (AppConfig.Get("keybind_profile") != -1) keyProfile = (Keys)AppConfig.Get("keybind_profile");
|
||||
if (AppConfig.Get("keybind_app") != -1) keyApp = (Keys)AppConfig.Get("keybind_app");
|
||||
|
||||
string actionM1 = AppConfig.getConfigString("m1");
|
||||
string actionM2 = AppConfig.getConfigString("m2");
|
||||
string actionM1 = AppConfig.GetString("m1");
|
||||
string actionM2 = AppConfig.GetString("m2");
|
||||
|
||||
if (keyProfile != Keys.None) hook.RegisterHotKey(ModifierKeys.Shift | ModifierKeys.Control, keyProfile);
|
||||
if (keyApp != Keys.None) hook.RegisterHotKey(ModifierKeys.Shift | ModifierKeys.Control, keyApp);
|
||||
|
||||
if (!AppConfig.ContainsModel("Z13"))
|
||||
if (actionM1 is not null && actionM1.Length > 0) hook.RegisterHotKey(ModifierKeys.None, Keys.VolumeDown);
|
||||
if (actionM2 is not null && actionM2.Length > 0) hook.RegisterHotKey(ModifierKeys.None, Keys.VolumeUp);
|
||||
if (actionM2 is not null && actionM2.Length > 0) hook.RegisterHotKey(ModifierKeys.None, Keys.VolumeUp);
|
||||
|
||||
// FN-Lock group
|
||||
|
||||
if (AppConfig.isConfig("fn_lock") && !AppConfig.ContainsModel("VivoBook"))
|
||||
if (AppConfig.Is("fn_lock") && !AppConfig.ContainsModel("VivoBook"))
|
||||
for (Keys i = Keys.F1; i <= Keys.F11; i++) hook.RegisterHotKey(ModifierKeys.None, i);
|
||||
|
||||
}
|
||||
|
||||
static void CustomKey(string configKey = "m3")
|
||||
{
|
||||
string command = AppConfig.getConfigString(configKey + "_custom");
|
||||
string command = AppConfig.GetString(configKey + "_custom");
|
||||
int intKey;
|
||||
|
||||
try
|
||||
@@ -194,22 +159,38 @@ namespace GHelper
|
||||
KeyProcess("m3");
|
||||
return;
|
||||
case Keys.F11:
|
||||
OptimizationEvent(199);
|
||||
HandleEvent(199);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (AppConfig.ContainsModel("GA401I") && !AppConfig.ContainsModel("GA401IHR"))
|
||||
{
|
||||
switch (e.Key)
|
||||
{
|
||||
case Keys.F2:
|
||||
KeyboardHook.KeyPress(Keys.MediaPreviousTrack);
|
||||
return;
|
||||
case Keys.F3:
|
||||
KeyboardHook.KeyPress(Keys.MediaPlayPause);
|
||||
return;
|
||||
case Keys.F4:
|
||||
KeyboardHook.KeyPress(Keys.MediaNextTrack);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
switch (e.Key)
|
||||
{
|
||||
case Keys.F1:
|
||||
KeyboardHook.KeyPress(Keys.VolumeMute);
|
||||
break;
|
||||
case Keys.F2:
|
||||
OptimizationEvent(197);
|
||||
HandleEvent(197);
|
||||
break;
|
||||
case Keys.F3:
|
||||
OptimizationEvent(196);
|
||||
HandleEvent(196);
|
||||
break;
|
||||
case Keys.F4:
|
||||
KeyProcess("fnf4");
|
||||
@@ -222,22 +203,22 @@ namespace GHelper
|
||||
break;
|
||||
case Keys.F7:
|
||||
if (AppConfig.ContainsModel("TUF"))
|
||||
Program.settingsForm.BeginInvoke(Program.settingsForm.RunToast, ScreenBrightness.Adjust(-10) + "%", ToastIcon.BrightnessDown);
|
||||
OptimizationEvent(16);
|
||||
Program.toast.RunToast(ScreenBrightness.Adjust(-10) + "%", ToastIcon.BrightnessDown);
|
||||
HandleOptimizationEvent(16);
|
||||
break;
|
||||
case Keys.F8:
|
||||
if (AppConfig.ContainsModel("TUF"))
|
||||
Program.settingsForm.BeginInvoke(Program.settingsForm.RunToast, ScreenBrightness.Adjust(+10) + "%", ToastIcon.BrightnessUp);
|
||||
OptimizationEvent(32);
|
||||
if (AppConfig.ContainsModel("TUF"))
|
||||
Program.toast.RunToast(ScreenBrightness.Adjust(+10) + "%", ToastIcon.BrightnessUp);
|
||||
HandleOptimizationEvent(32);
|
||||
break;
|
||||
case Keys.F9:
|
||||
KeyboardHook.KeyWinPress(Keys.P);
|
||||
break;
|
||||
case Keys.F10:
|
||||
OptimizationEvent(107);
|
||||
HandleOptimizationEvent(107);
|
||||
break;
|
||||
case Keys.F11:
|
||||
OptimizationEvent(108);
|
||||
HandleOptimizationEvent(108);
|
||||
break;
|
||||
case Keys.F12:
|
||||
KeyboardHook.KeyWinPress(Keys.A);
|
||||
@@ -255,7 +236,7 @@ namespace GHelper
|
||||
|
||||
if (e.Modifier == (ModifierKeys.Control | ModifierKeys.Shift))
|
||||
{
|
||||
if (e.Key == keyProfile) Program.settingsForm.CyclePerformanceMode();
|
||||
if (e.Key == keyProfile) modeControl.CyclePerformanceMode();
|
||||
if (e.Key == keyApp) Program.SettingsToggle();
|
||||
}
|
||||
|
||||
@@ -265,7 +246,7 @@ namespace GHelper
|
||||
|
||||
public static void KeyProcess(string name = "m3")
|
||||
{
|
||||
string action = AppConfig.getConfigString(name);
|
||||
string action = AppConfig.GetString(name);
|
||||
|
||||
if (action is null || action.Length <= 1)
|
||||
{
|
||||
@@ -277,6 +258,8 @@ namespace GHelper
|
||||
action = "performance";
|
||||
if (name == "m3" && !OptimizationService.IsRunning())
|
||||
action = "micmute";
|
||||
if (name == "fnc")
|
||||
action = "fnlock";
|
||||
}
|
||||
|
||||
switch (action)
|
||||
@@ -291,16 +274,17 @@ namespace GHelper
|
||||
KeyboardHook.KeyPress(Keys.Snapshot);
|
||||
break;
|
||||
case "screen":
|
||||
Logger.WriteLine("Screen off toggle");
|
||||
NativeMethods.TurnOffScreen(Program.settingsForm.Handle);
|
||||
break;
|
||||
case "miniled":
|
||||
Program.settingsForm.BeginInvoke(Program.settingsForm.ToogleMiniled);
|
||||
screenControl.ToogleMiniled();
|
||||
break;
|
||||
case "aura":
|
||||
Program.settingsForm.BeginInvoke(Program.settingsForm.CycleAuraMode);
|
||||
break;
|
||||
case "performance":
|
||||
Program.settingsForm.BeginInvoke(Program.settingsForm.CyclePerformanceMode);
|
||||
modeControl.CyclePerformanceMode();
|
||||
break;
|
||||
case "ghelper":
|
||||
Program.settingsForm.BeginInvoke(delegate
|
||||
@@ -308,8 +292,8 @@ namespace GHelper
|
||||
Program.SettingsToggle();
|
||||
});
|
||||
break;
|
||||
case "custom":
|
||||
CustomKey(name);
|
||||
case "fnlock":
|
||||
ToggleFnLock();
|
||||
break;
|
||||
case "micmute":
|
||||
using (var enumerator = new MMDeviceEnumerator())
|
||||
@@ -317,9 +301,18 @@ namespace GHelper
|
||||
var commDevice = enumerator.GetDefaultAudioEndpoint(DataFlow.Capture, Role.Communications);
|
||||
bool muteStatus = !commDevice.AudioEndpointVolume.Mute;
|
||||
commDevice.AudioEndpointVolume.Mute = muteStatus;
|
||||
Program.settingsForm.BeginInvoke(Program.settingsForm.RunToast, muteStatus ? "Muted" : "Unmuted", muteStatus ? ToastIcon.MicrophoneMute : ToastIcon.Microphone);
|
||||
Program.toast.RunToast(muteStatus ? "Muted" : "Unmuted", muteStatus ? ToastIcon.MicrophoneMute : ToastIcon.Microphone);
|
||||
}
|
||||
break;
|
||||
case "brightness_up":
|
||||
HandleOptimizationEvent(32);
|
||||
break;
|
||||
case "brightness_down":
|
||||
HandleOptimizationEvent(16);
|
||||
break;
|
||||
case "custom":
|
||||
CustomKey(name);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
@@ -330,25 +323,33 @@ namespace GHelper
|
||||
{
|
||||
using (var key = Registry.CurrentUser.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\PrecisionTouchPad\Status", false))
|
||||
{
|
||||
return (key?.GetValue("Enabled")?.ToString() == "1");
|
||||
return key?.GetValue("Enabled")?.ToString() == "1";
|
||||
}
|
||||
}
|
||||
|
||||
static void ToggleFnLock()
|
||||
{
|
||||
int fnLock = AppConfig.isConfig("fn_lock") ? 0 : 1;
|
||||
AppConfig.setConfig("fn_lock", fnLock);
|
||||
Program.acpi.DeviceSet(AsusACPI.FnLock, (fnLock == 1) ? 0 : 1, "FnLock");
|
||||
int fnLock = AppConfig.Is("fn_lock") ? 0 : 1;
|
||||
AppConfig.Set("fn_lock", fnLock);
|
||||
|
||||
if (AppConfig.ContainsModel("VivoBook"))
|
||||
Program.acpi.DeviceSet(AsusACPI.FnLock, fnLock == 1 ? 0 : 1, "FnLock");
|
||||
else
|
||||
Program.settingsForm.BeginInvoke(Program.inputDispatcher.RegisterKeys);
|
||||
|
||||
Program.toast.RunToast("Fn-Lock " + (fnLock == 1 ? "On" : "Off"), ToastIcon.FnLock);
|
||||
}
|
||||
|
||||
static void TabletMode()
|
||||
public static void TabletMode()
|
||||
{
|
||||
if (AppConfig.Is("disable_tablet")) return;
|
||||
|
||||
bool touchpadState = GetTouchpadState();
|
||||
bool tabletState = Program.acpi.DeviceGet(AsusACPI.TabletState) > 0;
|
||||
|
||||
Logger.WriteLine("Tablet: " + tabletState + " Touchpad: " + touchpadState);
|
||||
|
||||
if ((tabletState && touchpadState) || (!tabletState && !touchpadState)) AsusUSB.TouchpadToggle();
|
||||
if (tabletState && touchpadState || !tabletState && !touchpadState) AsusUSB.TouchpadToggle();
|
||||
|
||||
}
|
||||
|
||||
@@ -363,70 +364,114 @@ namespace GHelper
|
||||
KeyProcess("m4");
|
||||
return;
|
||||
case 174: // FN+F5
|
||||
Program.settingsForm.BeginInvoke(Program.settingsForm.CyclePerformanceMode);
|
||||
modeControl.CyclePerformanceMode();
|
||||
return;
|
||||
case 179: // FN+F4
|
||||
case 178: // FN+F4
|
||||
KeyProcess("fnf4");
|
||||
return;
|
||||
case 189: // Tablet mode
|
||||
TabletMode();
|
||||
case 158: // Fn + C
|
||||
KeyProcess("fnc");
|
||||
return;
|
||||
case 78: // Fn + ESC
|
||||
ToggleFnLock();
|
||||
return;
|
||||
case 189: // Tablet mode
|
||||
TabletMode();
|
||||
return;
|
||||
case 197: // FN+F2
|
||||
SetBacklight(-1);
|
||||
return;
|
||||
case 196: // FN+F3
|
||||
SetBacklight(1);
|
||||
return;
|
||||
case 199: // ON Z13 - FN+F11 - cycles backlight
|
||||
SetBacklight(4);
|
||||
return;
|
||||
case 53: // FN+F6 on GA-502DU model
|
||||
NativeMethods.TurnOffScreen(Program.settingsForm.Handle);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!OptimizationService.IsRunning()) OptimizationEvent(EventID);
|
||||
if (!OptimizationService.IsRunning())
|
||||
HandleOptimizationEvent(EventID);
|
||||
|
||||
}
|
||||
|
||||
static void OptimizationEvent(int EventID)
|
||||
{
|
||||
|
||||
// Asus Optimization service Events
|
||||
|
||||
int backlight = AppConfig.getConfig("keyboard_brightness");
|
||||
string[] backlightNames = new string[] { "Off", "Low", "Mid", "Max" };
|
||||
|
||||
// Asus Optimization service Events
|
||||
static void HandleOptimizationEvent(int EventID)
|
||||
{
|
||||
switch (EventID)
|
||||
{
|
||||
case 197: // FN+F2
|
||||
backlight = Math.Max(0, backlight - 1);
|
||||
AppConfig.setConfig("keyboard_brightness", backlight);
|
||||
AsusUSB.ApplyBrightness(backlight);
|
||||
Program.settingsForm.BeginInvoke(Program.settingsForm.RunToast, backlightNames[backlight], ToastIcon.BacklightDown);
|
||||
break;
|
||||
case 196: // FN+F3
|
||||
backlight = Math.Min(3, backlight + 1);
|
||||
AppConfig.setConfig("keyboard_brightness", backlight);
|
||||
AsusUSB.ApplyBrightness(backlight);
|
||||
Program.settingsForm.BeginInvoke(Program.settingsForm.RunToast, backlightNames[backlight], ToastIcon.BacklightUp);
|
||||
break;
|
||||
case 199: // ON Z13 - FN+F11 - cycles backlight
|
||||
if (++backlight > 3) backlight = 0;
|
||||
AppConfig.setConfig("keyboard_brightness", backlight);
|
||||
AsusUSB.ApplyBrightness(backlight);
|
||||
Program.settingsForm.BeginInvoke(Program.settingsForm.RunToast, backlightNames[backlight], ToastIcon.BacklightUp);
|
||||
break;
|
||||
case 16: // FN+F7
|
||||
Program.acpi.DeviceSet(AsusACPI.UniversalControl, 0x10, "Brightness");
|
||||
//ScreenBrightness.Adjust(-10);
|
||||
Program.acpi.DeviceSet(AsusACPI.UniversalControl, AsusACPI.Brightness_Down, "Brightness");
|
||||
break;
|
||||
case 32: // FN+F8
|
||||
Program.acpi.DeviceSet(AsusACPI.UniversalControl, 0x20, "Brightness");
|
||||
//ScreenBrightness.Adjust(+10);
|
||||
Program.acpi.DeviceSet(AsusACPI.UniversalControl, AsusACPI.Brightness_Up, "Brightness");
|
||||
break;
|
||||
case 107: // FN+F10
|
||||
bool touchpadState = GetTouchpadState();
|
||||
AsusUSB.TouchpadToggle();
|
||||
Program.settingsForm.BeginInvoke(Program.settingsForm.RunToast, touchpadState ? "Off" : "On", ToastIcon.Touchpad);
|
||||
Program.toast.RunToast(touchpadState ? "Off" : "On", ToastIcon.Touchpad);
|
||||
break;
|
||||
case 108: // FN+F11
|
||||
Program.acpi.DeviceSet(AsusACPI.UniversalControl, 0x6c, "Sleep");
|
||||
//NativeMethods.SetSuspendState(false, true, true);
|
||||
Program.acpi.DeviceSet(AsusACPI.UniversalControl, AsusACPI.KB_Sleep, "Sleep");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static int GetBacklight()
|
||||
{
|
||||
int backlight_power = AppConfig.Get("keyboard_brightness", 1);
|
||||
int backlight_battery = AppConfig.Get("keyboard_brightness_ac", 1);
|
||||
bool onBattery = SystemInformation.PowerStatus.PowerLineStatus != PowerLineStatus.Online;
|
||||
|
||||
int backlight;
|
||||
|
||||
//backlight = onBattery ? Math.Min(backlight_battery, backlight_power) : Math.Max(backlight_battery, backlight_power);
|
||||
backlight = onBattery ? backlight_battery : backlight_power;
|
||||
|
||||
return Math.Max(Math.Min(3, backlight), 0);
|
||||
}
|
||||
|
||||
public static void SetBacklightAuto(bool init = false)
|
||||
{
|
||||
if (init) AsusUSB.Init();
|
||||
|
||||
//if (!OptimizationService.IsRunning())
|
||||
AsusUSB.ApplyBrightness(GetBacklight(), "Auto");
|
||||
}
|
||||
|
||||
public static void SetBacklight(int delta)
|
||||
{
|
||||
int backlight_power = AppConfig.Get("keyboard_brightness", 1);
|
||||
int backlight_battery = AppConfig.Get("keyboard_brightness_ac", 1);
|
||||
bool onBattery = SystemInformation.PowerStatus.PowerLineStatus != PowerLineStatus.Online;
|
||||
|
||||
int backlight = onBattery ? backlight_battery : backlight_power;
|
||||
|
||||
if (delta >= 4)
|
||||
backlight = ++backlight % 4;
|
||||
else
|
||||
backlight = Math.Max(Math.Min(3, backlight + delta), 0);
|
||||
|
||||
if (onBattery)
|
||||
AppConfig.Set("keyboard_brightness_ac", backlight);
|
||||
else
|
||||
AppConfig.Set("keyboard_brightness", backlight);
|
||||
|
||||
if (!OptimizationService.IsRunning())
|
||||
{
|
||||
AsusUSB.ApplyBrightness(backlight, "HotKey");
|
||||
string[] backlightNames = new string[] { "Off", "Low", "Mid", "Max" };
|
||||
Program.toast.RunToast(backlightNames[backlight], delta > 0 ? ToastIcon.BacklightUp : ToastIcon.BacklightDown);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void LaunchProcess(string command = "")
|
||||
{
|
||||
|
||||
69
app/Input/KeyboardListener.cs
Normal file
69
app/Input/KeyboardListener.cs
Normal file
@@ -0,0 +1,69 @@
|
||||
using HidLibrary;
|
||||
|
||||
namespace GHelper.Input
|
||||
{
|
||||
public class KeyboardListener
|
||||
{
|
||||
|
||||
CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
|
||||
|
||||
public KeyboardListener(Action<int> KeyHandler)
|
||||
{
|
||||
HidDevice? input = AsusUSB.GetDevice();
|
||||
|
||||
// Fallback
|
||||
if (input == null)
|
||||
{
|
||||
AsusUSB.Init();
|
||||
Thread.Sleep(1000);
|
||||
input = AsusUSB.GetDevice();
|
||||
}
|
||||
|
||||
if (input == null)
|
||||
{
|
||||
Logger.WriteLine($"Input device not found");
|
||||
return;
|
||||
}
|
||||
|
||||
Logger.WriteLine($"Input: {input.DevicePath}");
|
||||
|
||||
var task = Task.Run(() =>
|
||||
{
|
||||
try
|
||||
{
|
||||
while (!cancellationTokenSource.Token.IsCancellationRequested)
|
||||
{
|
||||
|
||||
// Emergency break
|
||||
if (input == null || !input.IsConnected)
|
||||
{
|
||||
Logger.WriteLine("Listener terminated");
|
||||
break;
|
||||
}
|
||||
|
||||
var data = input.Read().Data;
|
||||
if (data.Length > 1 && data[0] == AsusUSB.INPUT_HID_ID && data[1] > 0 && data[1] != 236)
|
||||
{
|
||||
Logger.WriteLine($"Key: {data[1]}");
|
||||
KeyHandler(data[1]);
|
||||
}
|
||||
}
|
||||
|
||||
Logger.WriteLine("Listener stopped");
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.WriteLine(ex.ToString());
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
cancellationTokenSource?.Cancel();
|
||||
}
|
||||
}
|
||||
}
|
||||
423
app/Mode/ModeControl.cs
Normal file
423
app/Mode/ModeControl.cs
Normal file
@@ -0,0 +1,423 @@
|
||||
using GHelper.Battery;
|
||||
using GHelper.Gpu.NVidia;
|
||||
using GHelper.Helpers;
|
||||
using Ryzen;
|
||||
|
||||
namespace GHelper.Mode
|
||||
{
|
||||
public class ModeControl
|
||||
{
|
||||
|
||||
static SettingsForm settings = Program.settingsForm;
|
||||
|
||||
private static bool customFans = false;
|
||||
private static int customPower = 0;
|
||||
|
||||
private int _cpuUV = 0;
|
||||
private int _igpuUV = 0;
|
||||
|
||||
static System.Timers.Timer reapplyTimer = default!;
|
||||
|
||||
public ModeControl()
|
||||
{
|
||||
reapplyTimer = new System.Timers.Timer(AppConfig.GetMode("reapply_time", 30) * 1000);
|
||||
reapplyTimer.Elapsed += ReapplyTimer_Elapsed;
|
||||
reapplyTimer.Enabled = false;
|
||||
}
|
||||
|
||||
private void ReapplyTimer_Elapsed(object? sender, System.Timers.ElapsedEventArgs e)
|
||||
{
|
||||
SetCPUTemp(AppConfig.GetMode("cpu_temp"), false);
|
||||
}
|
||||
|
||||
public void AutoPerformance(bool powerChanged = false)
|
||||
{
|
||||
var Plugged = SystemInformation.PowerStatus.PowerLineStatus;
|
||||
|
||||
int mode = AppConfig.Get("performance_" + (int)Plugged);
|
||||
|
||||
if (mode != -1)
|
||||
SetPerformanceMode(mode, powerChanged);
|
||||
else
|
||||
SetPerformanceMode(Modes.GetCurrent());
|
||||
}
|
||||
|
||||
|
||||
public void ResetPerformanceMode()
|
||||
{
|
||||
ResetRyzen();
|
||||
Program.acpi.DeviceSet(AsusACPI.PerformanceMode, Modes.GetCurrentBase(), "Mode");
|
||||
}
|
||||
|
||||
public void SetPerformanceMode(int mode = -1, bool notify = false)
|
||||
{
|
||||
|
||||
int oldMode = Modes.GetCurrent();
|
||||
if (mode < 0) mode = oldMode;
|
||||
|
||||
if (!Modes.Exists(mode)) mode = 0;
|
||||
|
||||
customFans = false;
|
||||
customPower = 0;
|
||||
|
||||
settings.ShowMode(mode);
|
||||
SetModeLabel();
|
||||
|
||||
Modes.SetCurrent(mode);
|
||||
|
||||
Program.acpi.DeviceSet(AsusACPI.PerformanceMode, IsManualModeRequired() ? AsusACPI.PerformanceManual : Modes.GetBase(mode), "Mode");
|
||||
|
||||
if (AppConfig.Is("xgm_fan") && Program.acpi.IsXGConnected()) AsusUSB.ResetXGM();
|
||||
|
||||
if (notify)
|
||||
Program.toast.RunToast(Modes.GetCurrentName(), SystemInformation.PowerStatus.PowerLineStatus == PowerLineStatus.Online ? ToastIcon.Charger : ToastIcon.Battery);
|
||||
|
||||
SetGPUClocks();
|
||||
AutoFans();
|
||||
AutoPower(1000);
|
||||
|
||||
if (AppConfig.Get("auto_apply_power_plan") != 0)
|
||||
{
|
||||
if (AppConfig.GetModeString("scheme") is not null)
|
||||
PowerNative.SetPowerScheme(AppConfig.GetModeString("scheme"));
|
||||
else
|
||||
PowerNative.SetPowerScheme(Modes.GetBase(mode));
|
||||
}
|
||||
|
||||
if (AppConfig.GetMode("auto_boost") != -1)
|
||||
{
|
||||
PowerNative.SetCPUBoost(AppConfig.GetMode("auto_boost"));
|
||||
}
|
||||
|
||||
//BatteryControl.SetBatteryChargeLimit();
|
||||
|
||||
/*
|
||||
if (NativeMethods.PowerGetEffectiveOverlayScheme(out Guid activeScheme) == 0)
|
||||
{
|
||||
Debug.WriteLine("Effective :" + activeScheme);
|
||||
}
|
||||
*/
|
||||
|
||||
settings.FansInit();
|
||||
}
|
||||
|
||||
|
||||
public void CyclePerformanceMode()
|
||||
{
|
||||
SetPerformanceMode(Modes.GetNext(Control.ModifierKeys == Keys.Shift), true);
|
||||
}
|
||||
|
||||
public void AutoFans(bool force = false)
|
||||
{
|
||||
customFans = false;
|
||||
|
||||
if (AppConfig.IsMode("auto_apply") || force)
|
||||
{
|
||||
|
||||
bool xgmFan = false;
|
||||
if (AppConfig.Is("xgm_fan") && Program.acpi.IsXGConnected())
|
||||
{
|
||||
AsusUSB.SetXGMFan(AppConfig.GetFanConfig(AsusFan.XGM));
|
||||
xgmFan = true;
|
||||
}
|
||||
|
||||
int cpuResult = Program.acpi.SetFanCurve(AsusFan.CPU, AppConfig.GetFanConfig(AsusFan.CPU));
|
||||
int gpuResult = Program.acpi.SetFanCurve(AsusFan.GPU, AppConfig.GetFanConfig(AsusFan.GPU));
|
||||
|
||||
if (AppConfig.Is("mid_fan"))
|
||||
Program.acpi.SetFanCurve(AsusFan.Mid, AppConfig.GetFanConfig(AsusFan.Mid));
|
||||
|
||||
|
||||
// something went wrong, resetting to default profile
|
||||
if (cpuResult != 1 || gpuResult != 1)
|
||||
{
|
||||
int mode = Modes.GetCurrentBase();
|
||||
Logger.WriteLine("ASUS BIOS rejected fan curve, resetting mode to " + mode);
|
||||
Program.acpi.DeviceSet(AsusACPI.PerformanceMode, mode, "Reset Mode");
|
||||
settings.LabelFansResult("ASUS BIOS rejected fan curve");
|
||||
}
|
||||
else
|
||||
{
|
||||
settings.LabelFansResult("");
|
||||
customFans = true;
|
||||
}
|
||||
|
||||
// force set PPTs for missbehaving bios on FX507/517 series
|
||||
if ((AppConfig.ContainsModel("FX507") || AppConfig.ContainsModel("FX517") || xgmFan) && !AppConfig.IsMode("auto_apply_power"))
|
||||
{
|
||||
Task.Run(async () =>
|
||||
{
|
||||
await Task.Delay(TimeSpan.FromSeconds(1));
|
||||
Program.acpi.DeviceSet(AsusACPI.PPT_TotalA0, 80, "PowerLimit Fix A0");
|
||||
Program.acpi.DeviceSet(AsusACPI.PPT_APUA3, 80, "PowerLimit Fix A3");
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
SetModeLabel();
|
||||
|
||||
}
|
||||
|
||||
private static bool IsManualModeRequired()
|
||||
{
|
||||
if (!AppConfig.IsMode("auto_apply_power"))
|
||||
return false;
|
||||
|
||||
return
|
||||
AppConfig.Is("manual_mode") ||
|
||||
AppConfig.ContainsModel("GU603") ||
|
||||
AppConfig.ContainsModel("GU604") ||
|
||||
AppConfig.ContainsModel("G733");
|
||||
}
|
||||
|
||||
private static bool IsFanRequired()
|
||||
{
|
||||
return AppConfig.ContainsModel("GA402XI") || AppConfig.ContainsModel("G513");
|
||||
}
|
||||
|
||||
public void AutoPower(int delay = 0)
|
||||
{
|
||||
|
||||
customPower = 0;
|
||||
|
||||
bool applyPower = AppConfig.IsMode("auto_apply_power");
|
||||
bool applyFans = AppConfig.IsMode("auto_apply");
|
||||
//bool applyGPU = true;
|
||||
|
||||
if (applyPower)
|
||||
{
|
||||
// force fan curve for misbehaving bios PPTs on some models
|
||||
if (!applyFans && IsFanRequired())
|
||||
{
|
||||
delay = 500;
|
||||
AutoFans(true);
|
||||
}
|
||||
|
||||
// Fix for models that don't support PPT settings in all modes, setting a "manual" mode for them
|
||||
if (IsManualModeRequired() && !applyFans)
|
||||
{
|
||||
AutoFans(true);
|
||||
}
|
||||
}
|
||||
|
||||
if (delay > 0)
|
||||
{
|
||||
var timer = new System.Timers.Timer(delay);
|
||||
timer.Elapsed += delegate
|
||||
{
|
||||
timer.Stop();
|
||||
timer.Dispose();
|
||||
|
||||
if (applyPower) SetPower();
|
||||
SetGPUPower();
|
||||
AutoRyzen();
|
||||
};
|
||||
timer.Start();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (applyPower) SetPower(true);
|
||||
SetGPUPower();
|
||||
AutoRyzen();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void SetModeLabel()
|
||||
{
|
||||
settings.SetModeLabel(Properties.Strings.PerformanceMode + ": " + Modes.GetCurrentName() + (customFans ? "+" : "") + ((customPower > 0) ? " " + customPower + "W" : ""));
|
||||
}
|
||||
|
||||
public void SetPower(bool launchAsAdmin = false)
|
||||
{
|
||||
|
||||
int limit_total = AppConfig.GetMode("limit_total");
|
||||
int limit_cpu = AppConfig.GetMode("limit_cpu");
|
||||
int limit_fast = AppConfig.GetMode("limit_fast");
|
||||
|
||||
if (limit_total > AsusACPI.MaxTotal) return;
|
||||
if (limit_total < AsusACPI.MinTotal) return;
|
||||
|
||||
if (limit_cpu > AsusACPI.MaxCPU) return;
|
||||
if (limit_cpu < AsusACPI.MinCPU) return;
|
||||
|
||||
if (limit_fast > AsusACPI.MaxTotal) return;
|
||||
if (limit_fast < AsusACPI.MinTotal) return;
|
||||
|
||||
// SPL + SPPT togeher in one slider
|
||||
if (Program.acpi.DeviceGet(AsusACPI.PPT_TotalA0) >= 0)
|
||||
{
|
||||
Program.acpi.DeviceSet(AsusACPI.PPT_TotalA0, limit_total, "PowerLimit A0");
|
||||
Program.acpi.DeviceSet(AsusACPI.PPT_APUA3, limit_total, "PowerLimit A3");
|
||||
customPower = limit_total;
|
||||
}
|
||||
else if (RyzenControl.IsAMD())
|
||||
{
|
||||
|
||||
if (ProcessHelper.IsUserAdministrator())
|
||||
{
|
||||
var stapmResult = SendCommand.set_stapm_limit((uint)limit_total * 1000);
|
||||
Logger.WriteLine($"STAPM: {limit_total} {stapmResult}");
|
||||
|
||||
var stapmResult2 = SendCommand.set_stapm2_limit((uint)limit_total * 1000);
|
||||
Logger.WriteLine($"STAPM2: {limit_total} {stapmResult2}");
|
||||
|
||||
var slowResult = SendCommand.set_slow_limit((uint)limit_total * 1000);
|
||||
Logger.WriteLine($"SLOW: {limit_total} {slowResult}");
|
||||
|
||||
var fastResult = SendCommand.set_fast_limit((uint)limit_total * 1000);
|
||||
Logger.WriteLine($"FAST: {limit_total} {fastResult}");
|
||||
|
||||
customPower = limit_total;
|
||||
}
|
||||
else if (launchAsAdmin)
|
||||
{
|
||||
ProcessHelper.RunAsAdmin("cpu");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (Program.acpi.IsAllAmdPPT()) // CPU limit all amd models
|
||||
{
|
||||
Program.acpi.DeviceSet(AsusACPI.PPT_CPUB0, limit_cpu, "PowerLimit B0");
|
||||
customPower = limit_cpu;
|
||||
}
|
||||
else if (Program.acpi.DeviceGet(AsusACPI.PPT_APUC1) >= 0) // FPPT boost for non all-amd models
|
||||
{
|
||||
Program.acpi.DeviceSet(AsusACPI.PPT_APUC1, limit_fast, "PowerLimit C1");
|
||||
customPower = limit_fast;
|
||||
}
|
||||
|
||||
|
||||
SetModeLabel();
|
||||
|
||||
}
|
||||
|
||||
public void SetGPUClocks(bool launchAsAdmin = true)
|
||||
{
|
||||
|
||||
int gpu_core = AppConfig.GetMode("gpu_core");
|
||||
int gpu_memory = AppConfig.GetMode("gpu_memory");
|
||||
|
||||
if (gpu_core == -1 && gpu_memory == -1) return;
|
||||
|
||||
//if ((gpu_core > -5 && gpu_core < 5) && (gpu_memory > -5 && gpu_memory < 5)) launchAsAdmin = false;
|
||||
|
||||
if (Program.acpi.DeviceGet(AsusACPI.GPUEco) == 1) return;
|
||||
if (HardwareControl.GpuControl is null) return;
|
||||
if (!HardwareControl.GpuControl!.IsNvidia) return;
|
||||
|
||||
using NvidiaGpuControl nvControl = (NvidiaGpuControl)HardwareControl.GpuControl;
|
||||
try
|
||||
{
|
||||
int getStatus = nvControl.GetClocks(out int current_core, out int current_memory);
|
||||
if (getStatus != -1)
|
||||
{
|
||||
if (Math.Abs(gpu_core - current_core) < 5 && Math.Abs(gpu_memory - current_memory) < 5) return;
|
||||
}
|
||||
|
||||
int setStatus = nvControl.SetClocks(gpu_core, gpu_memory);
|
||||
if (launchAsAdmin && setStatus == -1) ProcessHelper.RunAsAdmin("gpu");
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.WriteLine(ex.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
public void SetGPUPower()
|
||||
{
|
||||
|
||||
int gpu_boost = AppConfig.GetMode("gpu_boost");
|
||||
int gpu_temp = AppConfig.GetMode("gpu_temp");
|
||||
|
||||
|
||||
if (gpu_boost < AsusACPI.MinGPUBoost || gpu_boost > AsusACPI.MaxGPUBoost) return;
|
||||
if (gpu_temp < AsusACPI.MinGPUTemp || gpu_temp > AsusACPI.MaxGPUTemp) return;
|
||||
|
||||
if (Program.acpi.DeviceGet(AsusACPI.PPT_GPUC0) >= 0)
|
||||
Program.acpi.DeviceSet(AsusACPI.PPT_GPUC0, gpu_boost, "PowerLimit C0");
|
||||
|
||||
if (Program.acpi.DeviceGet(AsusACPI.PPT_GPUC2) >= 0)
|
||||
Program.acpi.DeviceSet(AsusACPI.PPT_GPUC2, gpu_temp, "PowerLimit C2");
|
||||
|
||||
}
|
||||
|
||||
public void SetCPUTemp(int? cpuTemp, bool log = true)
|
||||
{
|
||||
if (cpuTemp >= RyzenControl.MinTemp && cpuTemp < RyzenControl.MaxTemp)
|
||||
{
|
||||
var resultCPU = SendCommand.set_tctl_temp((uint)cpuTemp);
|
||||
if (log) Logger.WriteLine($"CPU Temp: {cpuTemp} {resultCPU}");
|
||||
|
||||
var restultAPU = SendCommand.set_apu_skin_temp_limit((uint)cpuTemp);
|
||||
if (log) Logger.WriteLine($"APU Temp: {cpuTemp} {restultAPU}");
|
||||
|
||||
reapplyTimer.Enabled = AppConfig.IsMode("auto_uv");
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
reapplyTimer.Enabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
public void SetUV(int cpuUV)
|
||||
{
|
||||
if (cpuUV >= RyzenControl.MinCPUUV && cpuUV <= RyzenControl.MaxCPUUV)
|
||||
{
|
||||
var uvResult = SendCommand.set_coall(cpuUV);
|
||||
Logger.WriteLine($"UV: {cpuUV} {uvResult}");
|
||||
if (uvResult == Smu.Status.OK) _cpuUV = cpuUV;
|
||||
}
|
||||
}
|
||||
|
||||
public void SetUViGPU(int igpuUV)
|
||||
{
|
||||
if (igpuUV >= RyzenControl.MinIGPUUV && igpuUV <= RyzenControl.MaxIGPUUV)
|
||||
{
|
||||
var iGPUResult = SendCommand.set_cogfx(igpuUV);
|
||||
Logger.WriteLine($"iGPU UV: {igpuUV} {iGPUResult}");
|
||||
if (iGPUResult == Smu.Status.OK) _igpuUV = igpuUV;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void SetRyzen(bool launchAsAdmin = false)
|
||||
{
|
||||
if (!ProcessHelper.IsUserAdministrator())
|
||||
{
|
||||
if (launchAsAdmin) ProcessHelper.RunAsAdmin("uv");
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
SetUV(AppConfig.GetMode("cpu_uv", 0));
|
||||
SetUViGPU(AppConfig.GetMode("igpu_uv", 0));
|
||||
SetCPUTemp(AppConfig.GetMode("cpu_temp"));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.WriteLine("UV Error: " + ex.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
public void ResetRyzen()
|
||||
{
|
||||
if (_cpuUV != 0) SetUV(0);
|
||||
if (_igpuUV != 0) SetUViGPU(0);
|
||||
}
|
||||
|
||||
public void AutoRyzen()
|
||||
{
|
||||
if (!RyzenControl.IsAMD()) return;
|
||||
|
||||
if (AppConfig.IsMode("auto_uv")) SetRyzen();
|
||||
else ResetRyzen();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
154
app/Mode/Modes.cs
Normal file
154
app/Mode/Modes.cs
Normal file
@@ -0,0 +1,154 @@
|
||||
namespace GHelper.Mode
|
||||
{
|
||||
internal class Modes
|
||||
{
|
||||
|
||||
const int maxModes = 20;
|
||||
|
||||
public static Dictionary<int, string> GetDictonary()
|
||||
{
|
||||
Dictionary<int, string> modes = new Dictionary<int, string>
|
||||
{
|
||||
{2, Properties.Strings.Silent},
|
||||
{0, Properties.Strings.Balanced},
|
||||
{1, Properties.Strings.Turbo}
|
||||
};
|
||||
|
||||
for (int i = 3; i < maxModes; i++)
|
||||
{
|
||||
if (Exists(i)) modes.Add(i, GetName(i));
|
||||
}
|
||||
|
||||
return modes;
|
||||
}
|
||||
|
||||
public static List<int> GetList()
|
||||
{
|
||||
List<int> modes = new() { 2, 0, 1 };
|
||||
for (int i = 3; i < maxModes; i++)
|
||||
{
|
||||
if (Exists(i)) modes.Add(i);
|
||||
}
|
||||
|
||||
return modes;
|
||||
}
|
||||
|
||||
public static void Remove(int mode)
|
||||
{
|
||||
List<string> cleanup = new() {
|
||||
"mode_base",
|
||||
"mode_name",
|
||||
"limit_total",
|
||||
"limit_fast",
|
||||
"limit_cpu",
|
||||
"limit_total",
|
||||
"fan_profile_cpu",
|
||||
"fan_profile_gpu",
|
||||
"fan_profile_mid",
|
||||
"gpu_boost",
|
||||
"gpu_temp",
|
||||
"gpu_core",
|
||||
"gpu_memory",
|
||||
"auto_boost",
|
||||
"auto_apply",
|
||||
"auto_apply_power"
|
||||
};
|
||||
|
||||
foreach (string clean in cleanup)
|
||||
{
|
||||
AppConfig.Remove(clean + "_" + mode);
|
||||
}
|
||||
}
|
||||
|
||||
public static int Add()
|
||||
{
|
||||
for (int i = 3; i < maxModes; i++)
|
||||
{
|
||||
if (!Exists(i))
|
||||
{
|
||||
int modeBase = GetCurrentBase();
|
||||
string nameName = "Custom " + (i - 2);
|
||||
AppConfig.Set("mode_base_" + i, modeBase);
|
||||
AppConfig.Set("mode_name_" + i, nameName);
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
public static int GetCurrent()
|
||||
{
|
||||
return AppConfig.Get("performance_mode");
|
||||
}
|
||||
|
||||
public static bool IsCurrentCustom()
|
||||
{
|
||||
return GetCurrent() > 2;
|
||||
}
|
||||
|
||||
public static void SetCurrent(int mode)
|
||||
{
|
||||
AppConfig.Set("performance_" + (int)SystemInformation.PowerStatus.PowerLineStatus, mode);
|
||||
AppConfig.Set("performance_mode", mode);
|
||||
}
|
||||
|
||||
public static int GetCurrentBase()
|
||||
{
|
||||
return GetBase(GetCurrent());
|
||||
}
|
||||
|
||||
public static string GetCurrentName()
|
||||
{
|
||||
return GetName(GetCurrent());
|
||||
}
|
||||
|
||||
public static bool Exists(int mode)
|
||||
{
|
||||
return GetBase(mode) >= 0;
|
||||
}
|
||||
|
||||
public static int GetBase(int mode)
|
||||
{
|
||||
if (mode >= 0 && mode <= 2)
|
||||
return mode;
|
||||
else
|
||||
return AppConfig.Get("mode_base_" + mode);
|
||||
}
|
||||
|
||||
public static string GetName(int mode)
|
||||
{
|
||||
switch (mode)
|
||||
{
|
||||
case 0:
|
||||
return Properties.Strings.Balanced;
|
||||
case 1:
|
||||
return Properties.Strings.Turbo;
|
||||
case 2:
|
||||
return Properties.Strings.Silent;
|
||||
default:
|
||||
return AppConfig.GetString("mode_name_" + mode);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static int GetNext(bool back = false)
|
||||
{
|
||||
var modes = GetList();
|
||||
int index = modes.IndexOf(GetCurrent());
|
||||
|
||||
if (back)
|
||||
{
|
||||
index--;
|
||||
if (index < 0) index = modes.Count - 1;
|
||||
return modes[index];
|
||||
}
|
||||
else
|
||||
{
|
||||
index++;
|
||||
if (index > modes.Count - 1) index = 0;
|
||||
return modes[index];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
167
app/Mode/PowerNative.cs
Normal file
167
app/Mode/PowerNative.cs
Normal file
@@ -0,0 +1,167 @@
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace GHelper.Mode
|
||||
{
|
||||
internal class PowerNative
|
||||
{
|
||||
[DllImport("PowrProf.dll", CharSet = CharSet.Unicode)]
|
||||
static extern UInt32 PowerWriteDCValueIndex(IntPtr RootPowerKey,
|
||||
[MarshalAs(UnmanagedType.LPStruct)] Guid SchemeGuid,
|
||||
[MarshalAs(UnmanagedType.LPStruct)] Guid SubGroupOfPowerSettingsGuid,
|
||||
[MarshalAs(UnmanagedType.LPStruct)] Guid PowerSettingGuid,
|
||||
int AcValueIndex);
|
||||
|
||||
[DllImport("PowrProf.dll", CharSet = CharSet.Unicode)]
|
||||
static extern UInt32 PowerWriteACValueIndex(IntPtr RootPowerKey,
|
||||
[MarshalAs(UnmanagedType.LPStruct)] Guid SchemeGuid,
|
||||
[MarshalAs(UnmanagedType.LPStruct)] Guid SubGroupOfPowerSettingsGuid,
|
||||
[MarshalAs(UnmanagedType.LPStruct)] Guid PowerSettingGuid,
|
||||
int AcValueIndex);
|
||||
|
||||
[DllImport("PowrProf.dll", CharSet = CharSet.Unicode)]
|
||||
static extern UInt32 PowerReadACValueIndex(IntPtr RootPowerKey,
|
||||
[MarshalAs(UnmanagedType.LPStruct)] Guid SchemeGuid,
|
||||
[MarshalAs(UnmanagedType.LPStruct)] Guid SubGroupOfPowerSettingsGuid,
|
||||
[MarshalAs(UnmanagedType.LPStruct)] Guid PowerSettingGuid,
|
||||
out IntPtr AcValueIndex
|
||||
);
|
||||
|
||||
[DllImport("PowrProf.dll", CharSet = CharSet.Unicode)]
|
||||
static extern UInt32 PowerReadDCValueIndex(IntPtr RootPowerKey,
|
||||
[MarshalAs(UnmanagedType.LPStruct)] Guid SchemeGuid,
|
||||
[MarshalAs(UnmanagedType.LPStruct)] Guid SubGroupOfPowerSettingsGuid,
|
||||
[MarshalAs(UnmanagedType.LPStruct)] Guid PowerSettingGuid,
|
||||
out IntPtr AcValueIndex
|
||||
);
|
||||
|
||||
|
||||
[DllImport("powrprof.dll")]
|
||||
static extern uint PowerReadACValue(
|
||||
IntPtr RootPowerKey,
|
||||
Guid SchemeGuid,
|
||||
Guid SubGroupOfPowerSettingGuid,
|
||||
Guid PowerSettingGuid,
|
||||
ref int Type,
|
||||
ref IntPtr Buffer,
|
||||
ref uint BufferSize
|
||||
);
|
||||
|
||||
|
||||
[DllImport("PowrProf.dll", CharSet = CharSet.Unicode)]
|
||||
static extern UInt32 PowerSetActiveScheme(IntPtr RootPowerKey,
|
||||
[MarshalAs(UnmanagedType.LPStruct)] Guid SchemeGuid);
|
||||
|
||||
[DllImport("PowrProf.dll", CharSet = CharSet.Unicode)]
|
||||
static extern UInt32 PowerGetActiveScheme(IntPtr UserPowerKey, out IntPtr ActivePolicyGuid);
|
||||
|
||||
static readonly Guid GUID_CPU = new Guid("54533251-82be-4824-96c1-47b60b740d00");
|
||||
static readonly Guid GUID_BOOST = new Guid("be337238-0d82-4146-a960-4f3749d470c7");
|
||||
|
||||
private static Guid GUID_SLEEP_SUBGROUP = new Guid("238c9fa8-0aad-41ed-83f4-97be242c8f20");
|
||||
private static Guid GUID_HIBERNATEIDLE = new Guid("9d7815a6-7ee4-497e-8888-515a05f02364");
|
||||
|
||||
[DllImportAttribute("powrprof.dll", EntryPoint = "PowerGetActualOverlayScheme")]
|
||||
public static extern uint PowerGetActualOverlayScheme(out Guid ActualOverlayGuid);
|
||||
|
||||
[DllImportAttribute("powrprof.dll", EntryPoint = "PowerGetEffectiveOverlayScheme")]
|
||||
public static extern uint PowerGetEffectiveOverlayScheme(out Guid EffectiveOverlayGuid);
|
||||
|
||||
[DllImportAttribute("powrprof.dll", EntryPoint = "PowerSetActiveOverlayScheme")]
|
||||
public static extern uint PowerSetActiveOverlayScheme(Guid OverlaySchemeGuid);
|
||||
|
||||
|
||||
static Guid GetActiveScheme()
|
||||
{
|
||||
IntPtr pActiveSchemeGuid;
|
||||
var hr = PowerGetActiveScheme(IntPtr.Zero, out pActiveSchemeGuid);
|
||||
Guid activeSchemeGuid = (Guid)Marshal.PtrToStructure(pActiveSchemeGuid, typeof(Guid));
|
||||
return activeSchemeGuid;
|
||||
}
|
||||
|
||||
public static int GetCPUBoost()
|
||||
{
|
||||
IntPtr AcValueIndex;
|
||||
Guid activeSchemeGuid = GetActiveScheme();
|
||||
|
||||
UInt32 value = PowerReadACValueIndex(IntPtr.Zero,
|
||||
activeSchemeGuid,
|
||||
GUID_CPU,
|
||||
GUID_BOOST, out AcValueIndex);
|
||||
|
||||
return AcValueIndex.ToInt32();
|
||||
|
||||
}
|
||||
|
||||
public static void SetCPUBoost(int boost = 0)
|
||||
{
|
||||
Guid activeSchemeGuid = GetActiveScheme();
|
||||
|
||||
if (boost == GetCPUBoost()) return;
|
||||
|
||||
var hrAC = PowerWriteACValueIndex(
|
||||
IntPtr.Zero,
|
||||
activeSchemeGuid,
|
||||
GUID_CPU,
|
||||
GUID_BOOST,
|
||||
boost);
|
||||
|
||||
PowerSetActiveScheme(IntPtr.Zero, activeSchemeGuid);
|
||||
|
||||
var hrDC = PowerWriteDCValueIndex(
|
||||
IntPtr.Zero,
|
||||
activeSchemeGuid,
|
||||
GUID_CPU,
|
||||
GUID_BOOST,
|
||||
boost);
|
||||
|
||||
PowerSetActiveScheme(IntPtr.Zero, activeSchemeGuid);
|
||||
|
||||
Logger.WriteLine("Boost " + boost);
|
||||
}
|
||||
|
||||
public static void SetPowerScheme(string scheme)
|
||||
{
|
||||
List<string> overlays = new() {
|
||||
"00000000-0000-0000-0000-000000000000",
|
||||
"ded574b5-45a0-4f42-8737-46345c09c238",
|
||||
"961cc777-2547-4f9d-8174-7d86181b8a7a",
|
||||
"3af9B8d9-7c97-431d-ad78-34a8bfea439f"
|
||||
};
|
||||
|
||||
Guid guidScheme = new Guid(scheme);
|
||||
|
||||
if (overlays.Contains(scheme))
|
||||
{
|
||||
uint status = PowerGetEffectiveOverlayScheme(out Guid activeScheme);
|
||||
if (status != 0 || activeScheme != guidScheme)
|
||||
{
|
||||
PowerSetActiveOverlayScheme(guidScheme);
|
||||
Logger.WriteLine("Power mode: " + scheme);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
PowerSetActiveScheme(IntPtr.Zero, guidScheme);
|
||||
Logger.WriteLine("Power plan: " + scheme);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public static void SetPowerScheme(int mode)
|
||||
{
|
||||
switch (mode)
|
||||
{
|
||||
case 0: // balanced
|
||||
SetPowerScheme("00000000-0000-0000-0000-000000000000");
|
||||
break;
|
||||
case 1: // turbo
|
||||
SetPowerScheme("ded574b5-45a0-4f42-8737-46345c09c238");
|
||||
break;
|
||||
case 2: //silent
|
||||
SetPowerScheme("961cc777-2547-4f9d-8174-7d86181b8a7a");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,310 +1,5 @@
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.Runtime.InteropServices;
|
||||
using static Tools.ScreenInterrogatory;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Tools
|
||||
{
|
||||
|
||||
|
||||
public static class ScreenInterrogatory
|
||||
{
|
||||
public const int ERROR_SUCCESS = 0;
|
||||
|
||||
#region enums
|
||||
|
||||
public enum QUERY_DEVICE_CONFIG_FLAGS : uint
|
||||
{
|
||||
QDC_ALL_PATHS = 0x00000001,
|
||||
QDC_ONLY_ACTIVE_PATHS = 0x00000002,
|
||||
QDC_DATABASE_CURRENT = 0x00000004
|
||||
}
|
||||
|
||||
public enum DISPLAYCONFIG_VIDEO_OUTPUT_TECHNOLOGY : uint
|
||||
{
|
||||
DISPLAYCONFIG_OUTPUT_TECHNOLOGY_OTHER = 0xFFFFFFFF,
|
||||
DISPLAYCONFIG_OUTPUT_TECHNOLOGY_HD15 = 0,
|
||||
DISPLAYCONFIG_OUTPUT_TECHNOLOGY_SVIDEO = 1,
|
||||
DISPLAYCONFIG_OUTPUT_TECHNOLOGY_COMPOSITE_VIDEO = 2,
|
||||
DISPLAYCONFIG_OUTPUT_TECHNOLOGY_COMPONENT_VIDEO = 3,
|
||||
DISPLAYCONFIG_OUTPUT_TECHNOLOGY_DVI = 4,
|
||||
DISPLAYCONFIG_OUTPUT_TECHNOLOGY_HDMI = 5,
|
||||
DISPLAYCONFIG_OUTPUT_TECHNOLOGY_LVDS = 6,
|
||||
DISPLAYCONFIG_OUTPUT_TECHNOLOGY_D_JPN = 8,
|
||||
DISPLAYCONFIG_OUTPUT_TECHNOLOGY_SDI = 9,
|
||||
DISPLAYCONFIG_OUTPUT_TECHNOLOGY_DISPLAYPORT_EXTERNAL = 10,
|
||||
DISPLAYCONFIG_OUTPUT_TECHNOLOGY_DISPLAYPORT_EMBEDDED = 11,
|
||||
DISPLAYCONFIG_OUTPUT_TECHNOLOGY_UDI_EXTERNAL = 12,
|
||||
DISPLAYCONFIG_OUTPUT_TECHNOLOGY_UDI_EMBEDDED = 13,
|
||||
DISPLAYCONFIG_OUTPUT_TECHNOLOGY_SDTVDONGLE = 14,
|
||||
DISPLAYCONFIG_OUTPUT_TECHNOLOGY_MIRACAST = 15,
|
||||
DISPLAYCONFIG_OUTPUT_TECHNOLOGY_INTERNAL = 0x80000000,
|
||||
DISPLAYCONFIG_OUTPUT_TECHNOLOGY_FORCE_UINT32 = 0xFFFFFFFF
|
||||
}
|
||||
|
||||
public enum DISPLAYCONFIG_SCANLINE_ORDERING : uint
|
||||
{
|
||||
DISPLAYCONFIG_SCANLINE_ORDERING_UNSPECIFIED = 0,
|
||||
DISPLAYCONFIG_SCANLINE_ORDERING_PROGRESSIVE = 1,
|
||||
DISPLAYCONFIG_SCANLINE_ORDERING_INTERLACED = 2,
|
||||
DISPLAYCONFIG_SCANLINE_ORDERING_INTERLACED_UPPERFIELDFIRST = DISPLAYCONFIG_SCANLINE_ORDERING_INTERLACED,
|
||||
DISPLAYCONFIG_SCANLINE_ORDERING_INTERLACED_LOWERFIELDFIRST = 3,
|
||||
DISPLAYCONFIG_SCANLINE_ORDERING_FORCE_UINT32 = 0xFFFFFFFF
|
||||
}
|
||||
|
||||
public enum DISPLAYCONFIG_ROTATION : uint
|
||||
{
|
||||
DISPLAYCONFIG_ROTATION_IDENTITY = 1,
|
||||
DISPLAYCONFIG_ROTATION_ROTATE90 = 2,
|
||||
DISPLAYCONFIG_ROTATION_ROTATE180 = 3,
|
||||
DISPLAYCONFIG_ROTATION_ROTATE270 = 4,
|
||||
DISPLAYCONFIG_ROTATION_FORCE_UINT32 = 0xFFFFFFFF
|
||||
}
|
||||
|
||||
public enum DISPLAYCONFIG_SCALING : uint
|
||||
{
|
||||
DISPLAYCONFIG_SCALING_IDENTITY = 1,
|
||||
DISPLAYCONFIG_SCALING_CENTERED = 2,
|
||||
DISPLAYCONFIG_SCALING_STRETCHED = 3,
|
||||
DISPLAYCONFIG_SCALING_ASPECTRATIOCENTEREDMAX = 4,
|
||||
DISPLAYCONFIG_SCALING_CUSTOM = 5,
|
||||
DISPLAYCONFIG_SCALING_PREFERRED = 128,
|
||||
DISPLAYCONFIG_SCALING_FORCE_UINT32 = 0xFFFFFFFF
|
||||
}
|
||||
|
||||
public enum DISPLAYCONFIG_PIXELFORMAT : uint
|
||||
{
|
||||
DISPLAYCONFIG_PIXELFORMAT_8BPP = 1,
|
||||
DISPLAYCONFIG_PIXELFORMAT_16BPP = 2,
|
||||
DISPLAYCONFIG_PIXELFORMAT_24BPP = 3,
|
||||
DISPLAYCONFIG_PIXELFORMAT_32BPP = 4,
|
||||
DISPLAYCONFIG_PIXELFORMAT_NONGDI = 5,
|
||||
DISPLAYCONFIG_PIXELFORMAT_FORCE_UINT32 = 0xffffffff
|
||||
}
|
||||
|
||||
public enum DISPLAYCONFIG_MODE_INFO_TYPE : uint
|
||||
{
|
||||
DISPLAYCONFIG_MODE_INFO_TYPE_SOURCE = 1,
|
||||
DISPLAYCONFIG_MODE_INFO_TYPE_TARGET = 2,
|
||||
DISPLAYCONFIG_MODE_INFO_TYPE_FORCE_UINT32 = 0xFFFFFFFF
|
||||
}
|
||||
|
||||
public enum DISPLAYCONFIG_DEVICE_INFO_TYPE : uint
|
||||
{
|
||||
DISPLAYCONFIG_DEVICE_INFO_GET_SOURCE_NAME = 1,
|
||||
DISPLAYCONFIG_DEVICE_INFO_GET_TARGET_NAME = 2,
|
||||
DISPLAYCONFIG_DEVICE_INFO_GET_TARGET_PREFERRED_MODE = 3,
|
||||
DISPLAYCONFIG_DEVICE_INFO_GET_ADAPTER_NAME = 4,
|
||||
DISPLAYCONFIG_DEVICE_INFO_SET_TARGET_PERSISTENCE = 5,
|
||||
DISPLAYCONFIG_DEVICE_INFO_GET_TARGET_BASE_TYPE = 6,
|
||||
DISPLAYCONFIG_DEVICE_INFO_FORCE_UINT32 = 0xFFFFFFFF
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region structs
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct LUID
|
||||
{
|
||||
public uint LowPart;
|
||||
public int HighPart;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct DISPLAYCONFIG_PATH_SOURCE_INFO
|
||||
{
|
||||
public LUID adapterId;
|
||||
public uint id;
|
||||
public uint modeInfoIdx;
|
||||
public uint statusFlags;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct DISPLAYCONFIG_PATH_TARGET_INFO
|
||||
{
|
||||
public LUID adapterId;
|
||||
public uint id;
|
||||
public uint modeInfoIdx;
|
||||
private DISPLAYCONFIG_VIDEO_OUTPUT_TECHNOLOGY outputTechnology;
|
||||
private DISPLAYCONFIG_ROTATION rotation;
|
||||
private DISPLAYCONFIG_SCALING scaling;
|
||||
private DISPLAYCONFIG_RATIONAL refreshRate;
|
||||
private DISPLAYCONFIG_SCANLINE_ORDERING scanLineOrdering;
|
||||
public bool targetAvailable;
|
||||
public uint statusFlags;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct DISPLAYCONFIG_RATIONAL
|
||||
{
|
||||
public uint Numerator;
|
||||
public uint Denominator;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct DISPLAYCONFIG_PATH_INFO
|
||||
{
|
||||
public DISPLAYCONFIG_PATH_SOURCE_INFO sourceInfo;
|
||||
public DISPLAYCONFIG_PATH_TARGET_INFO targetInfo;
|
||||
public uint flags;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct DISPLAYCONFIG_2DREGION
|
||||
{
|
||||
public uint cx;
|
||||
public uint cy;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct DISPLAYCONFIG_VIDEO_SIGNAL_INFO
|
||||
{
|
||||
public ulong pixelRate;
|
||||
public DISPLAYCONFIG_RATIONAL hSyncFreq;
|
||||
public DISPLAYCONFIG_RATIONAL vSyncFreq;
|
||||
public DISPLAYCONFIG_2DREGION activeSize;
|
||||
public DISPLAYCONFIG_2DREGION totalSize;
|
||||
public uint videoStandard;
|
||||
public DISPLAYCONFIG_SCANLINE_ORDERING scanLineOrdering;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct DISPLAYCONFIG_TARGET_MODE
|
||||
{
|
||||
public DISPLAYCONFIG_VIDEO_SIGNAL_INFO targetVideoSignalInfo;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct POINTL
|
||||
{
|
||||
private int x;
|
||||
private int y;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct DISPLAYCONFIG_SOURCE_MODE
|
||||
{
|
||||
public uint width;
|
||||
public uint height;
|
||||
public DISPLAYCONFIG_PIXELFORMAT pixelFormat;
|
||||
public POINTL position;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Explicit)]
|
||||
public struct DISPLAYCONFIG_MODE_INFO_UNION
|
||||
{
|
||||
[FieldOffset(0)]
|
||||
public DISPLAYCONFIG_TARGET_MODE targetMode;
|
||||
|
||||
[FieldOffset(0)]
|
||||
public DISPLAYCONFIG_SOURCE_MODE sourceMode;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct DISPLAYCONFIG_MODE_INFO
|
||||
{
|
||||
public DISPLAYCONFIG_MODE_INFO_TYPE infoType;
|
||||
public uint id;
|
||||
public LUID adapterId;
|
||||
public DISPLAYCONFIG_MODE_INFO_UNION modeInfo;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct DISPLAYCONFIG_TARGET_DEVICE_NAME_FLAGS
|
||||
{
|
||||
public uint value;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct DISPLAYCONFIG_DEVICE_INFO_HEADER
|
||||
{
|
||||
public DISPLAYCONFIG_DEVICE_INFO_TYPE type;
|
||||
public uint size;
|
||||
public LUID adapterId;
|
||||
public uint id;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
|
||||
public struct DISPLAYCONFIG_TARGET_DEVICE_NAME
|
||||
{
|
||||
public DISPLAYCONFIG_DEVICE_INFO_HEADER header;
|
||||
public DISPLAYCONFIG_TARGET_DEVICE_NAME_FLAGS flags;
|
||||
public DISPLAYCONFIG_VIDEO_OUTPUT_TECHNOLOGY outputTechnology;
|
||||
public ushort edidManufactureId;
|
||||
public ushort edidProductCodeId;
|
||||
public uint connectorInstance;
|
||||
|
||||
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]
|
||||
public string monitorFriendlyDeviceName;
|
||||
|
||||
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
|
||||
public string monitorDevicePath;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region DLL-Imports
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
public static extern int GetDisplayConfigBufferSizes(
|
||||
QUERY_DEVICE_CONFIG_FLAGS flags, out uint numPathArrayElements, out uint numModeInfoArrayElements);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
public static extern int QueryDisplayConfig(
|
||||
QUERY_DEVICE_CONFIG_FLAGS flags,
|
||||
ref uint numPathArrayElements, [Out] DISPLAYCONFIG_PATH_INFO[] PathInfoArray,
|
||||
ref uint numModeInfoArrayElements, [Out] DISPLAYCONFIG_MODE_INFO[] ModeInfoArray,
|
||||
IntPtr currentTopologyId
|
||||
);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
public static extern int DisplayConfigGetDeviceInfo(ref DISPLAYCONFIG_TARGET_DEVICE_NAME deviceName);
|
||||
|
||||
#endregion
|
||||
|
||||
private static DISPLAYCONFIG_TARGET_DEVICE_NAME DeviceName(LUID adapterId, uint targetId)
|
||||
{
|
||||
var deviceName = new DISPLAYCONFIG_TARGET_DEVICE_NAME
|
||||
{
|
||||
header =
|
||||
{
|
||||
size = (uint)Marshal.SizeOf(typeof (DISPLAYCONFIG_TARGET_DEVICE_NAME)),
|
||||
adapterId = adapterId,
|
||||
id = targetId,
|
||||
type = DISPLAYCONFIG_DEVICE_INFO_TYPE.DISPLAYCONFIG_DEVICE_INFO_GET_TARGET_NAME
|
||||
}
|
||||
};
|
||||
var error = DisplayConfigGetDeviceInfo(ref deviceName);
|
||||
if (error != ERROR_SUCCESS)
|
||||
throw new Win32Exception(error);
|
||||
|
||||
return deviceName;
|
||||
}
|
||||
|
||||
public static IEnumerable<DISPLAYCONFIG_TARGET_DEVICE_NAME> GetAllDevices()
|
||||
{
|
||||
uint pathCount, modeCount;
|
||||
var error = GetDisplayConfigBufferSizes(QUERY_DEVICE_CONFIG_FLAGS.QDC_ONLY_ACTIVE_PATHS, out pathCount, out modeCount);
|
||||
if (error != ERROR_SUCCESS)
|
||||
throw new Win32Exception(error);
|
||||
|
||||
var displayPaths = new DISPLAYCONFIG_PATH_INFO[pathCount];
|
||||
var displayModes = new DISPLAYCONFIG_MODE_INFO[modeCount];
|
||||
error = QueryDisplayConfig(QUERY_DEVICE_CONFIG_FLAGS.QDC_ONLY_ACTIVE_PATHS,
|
||||
ref pathCount, displayPaths, ref modeCount, displayModes, IntPtr.Zero);
|
||||
if (error != ERROR_SUCCESS)
|
||||
throw new Win32Exception(error);
|
||||
|
||||
for (var i = 0; i < modeCount; i++)
|
||||
if (displayModes[i].infoType == DISPLAYCONFIG_MODE_INFO_TYPE.DISPLAYCONFIG_MODE_INFO_TYPE_TARGET)
|
||||
yield return DeviceName(displayModes[i].adapterId, displayModes[i].id);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public class NativeMethods
|
||||
{
|
||||
@@ -327,7 +22,6 @@ public class NativeMethods
|
||||
|
||||
}
|
||||
|
||||
|
||||
private const int WM_SYSCOMMAND = 0x0112;
|
||||
private const int SC_MONITORPOWER = 0xF170;
|
||||
private const int MONITOR_OFF = 2;
|
||||
@@ -412,339 +106,5 @@ public class NativeMethods
|
||||
}
|
||||
|
||||
|
||||
[DllImport("Powrprof.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
|
||||
public static extern bool SetSuspendState(bool hiberate, bool forceCritical, bool disableWakeEvent);
|
||||
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
public static extern bool ShowWindowAsync(IntPtr hWnd, int nCmdShow);
|
||||
public const int SW_RESTORE = 9;
|
||||
|
||||
public static bool SwitchToCurrent()
|
||||
{
|
||||
IntPtr hWnd = IntPtr.Zero;
|
||||
Process process = Process.GetCurrentProcess();
|
||||
Process[] processes = Process.GetProcessesByName(process.ProcessName);
|
||||
foreach (Process _process in processes)
|
||||
{
|
||||
if (_process.Id != process.Id)
|
||||
{
|
||||
|
||||
if (_process.MainWindowHandle != IntPtr.Zero)
|
||||
{
|
||||
Debug.WriteLine(_process.Id);
|
||||
Debug.WriteLine(process.Id);
|
||||
|
||||
hWnd = _process.MainWindowHandle;
|
||||
ShowWindowAsync(hWnd, SW_RESTORE);
|
||||
}
|
||||
|
||||
return true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
[DllImport("PowrProf.dll", CharSet = CharSet.Unicode)]
|
||||
static extern UInt32 PowerWriteDCValueIndex(IntPtr RootPowerKey,
|
||||
[MarshalAs(UnmanagedType.LPStruct)] Guid SchemeGuid,
|
||||
[MarshalAs(UnmanagedType.LPStruct)] Guid SubGroupOfPowerSettingsGuid,
|
||||
[MarshalAs(UnmanagedType.LPStruct)] Guid PowerSettingGuid,
|
||||
int AcValueIndex);
|
||||
|
||||
[DllImport("PowrProf.dll", CharSet = CharSet.Unicode)]
|
||||
static extern UInt32 PowerWriteACValueIndex(IntPtr RootPowerKey,
|
||||
[MarshalAs(UnmanagedType.LPStruct)] Guid SchemeGuid,
|
||||
[MarshalAs(UnmanagedType.LPStruct)] Guid SubGroupOfPowerSettingsGuid,
|
||||
[MarshalAs(UnmanagedType.LPStruct)] Guid PowerSettingGuid,
|
||||
int AcValueIndex);
|
||||
|
||||
[DllImport("PowrProf.dll", CharSet = CharSet.Unicode)]
|
||||
static extern UInt32 PowerReadACValueIndex(IntPtr RootPowerKey,
|
||||
[MarshalAs(UnmanagedType.LPStruct)] Guid SchemeGuid,
|
||||
[MarshalAs(UnmanagedType.LPStruct)] Guid SubGroupOfPowerSettingsGuid,
|
||||
[MarshalAs(UnmanagedType.LPStruct)] Guid PowerSettingGuid,
|
||||
out IntPtr AcValueIndex
|
||||
);
|
||||
|
||||
[DllImport("PowrProf.dll", CharSet = CharSet.Unicode)]
|
||||
static extern UInt32 PowerReadDCValueIndex(IntPtr RootPowerKey,
|
||||
[MarshalAs(UnmanagedType.LPStruct)] Guid SchemeGuid,
|
||||
[MarshalAs(UnmanagedType.LPStruct)] Guid SubGroupOfPowerSettingsGuid,
|
||||
[MarshalAs(UnmanagedType.LPStruct)] Guid PowerSettingGuid,
|
||||
out IntPtr AcValueIndex
|
||||
);
|
||||
|
||||
|
||||
|
||||
[DllImport("PowrProf.dll", CharSet = CharSet.Unicode)]
|
||||
static extern UInt32 PowerSetActiveScheme(IntPtr RootPowerKey,
|
||||
[MarshalAs(UnmanagedType.LPStruct)] Guid SchemeGuid);
|
||||
|
||||
[DllImport("PowrProf.dll", CharSet = CharSet.Unicode)]
|
||||
static extern UInt32 PowerGetActiveScheme(IntPtr UserPowerKey, out IntPtr ActivePolicyGuid);
|
||||
|
||||
static readonly Guid GUID_CPU = new Guid("54533251-82be-4824-96c1-47b60b740d00");
|
||||
static readonly Guid GUID_BOOST = new Guid("be337238-0d82-4146-a960-4f3749d470c7");
|
||||
|
||||
[DllImportAttribute("powrprof.dll", EntryPoint = "PowerGetActualOverlayScheme")]
|
||||
public static extern uint PowerGetActualOverlayScheme(out Guid ActualOverlayGuid);
|
||||
|
||||
[DllImportAttribute("powrprof.dll", EntryPoint = "PowerGetEffectiveOverlayScheme")]
|
||||
public static extern uint PowerGetEffectiveOverlayScheme(out Guid EffectiveOverlayGuid);
|
||||
|
||||
[DllImportAttribute("powrprof.dll", EntryPoint = "PowerSetActiveOverlayScheme")]
|
||||
public static extern uint PowerSetActiveOverlayScheme(Guid OverlaySchemeGuid);
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
|
||||
public struct DEVMODE
|
||||
{
|
||||
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
|
||||
public string dmDeviceName;
|
||||
|
||||
public short dmSpecVersion;
|
||||
public short dmDriverVersion;
|
||||
public short dmSize;
|
||||
public short dmDriverExtra;
|
||||
public int dmFields;
|
||||
public int dmPositionX;
|
||||
public int dmPositionY;
|
||||
public int dmDisplayOrientation;
|
||||
public int dmDisplayFixedOutput;
|
||||
public short dmColor;
|
||||
public short dmDuplex;
|
||||
public short dmYResolution;
|
||||
public short dmTTOption;
|
||||
public short dmCollate;
|
||||
|
||||
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
|
||||
public string dmFormName;
|
||||
|
||||
public short dmLogPixels;
|
||||
public short dmBitsPerPel;
|
||||
public int dmPelsWidth;
|
||||
public int dmPelsHeight;
|
||||
public int dmDisplayFlags;
|
||||
public int dmDisplayFrequency;
|
||||
public int dmICMMethod;
|
||||
public int dmICMIntent;
|
||||
public int dmMediaType;
|
||||
public int dmDitherType;
|
||||
public int dmReserved1;
|
||||
public int dmReserved2;
|
||||
public int dmPanningWidth;
|
||||
public int dmPanningHeight;
|
||||
};
|
||||
|
||||
[Flags()]
|
||||
public enum DisplaySettingsFlags : int
|
||||
{
|
||||
CDS_UPDATEREGISTRY = 1,
|
||||
CDS_TEST = 2,
|
||||
CDS_FULLSCREEN = 4,
|
||||
CDS_GLOBAL = 8,
|
||||
CDS_SET_PRIMARY = 0x10,
|
||||
CDS_RESET = 0x40000000,
|
||||
CDS_NORESET = 0x10000000
|
||||
}
|
||||
|
||||
// PInvoke declaration for EnumDisplaySettings Win32 API
|
||||
[DllImport("user32.dll")]
|
||||
public static extern int EnumDisplaySettingsEx(
|
||||
string lpszDeviceName,
|
||||
int iModeNum,
|
||||
ref DEVMODE lpDevMode);
|
||||
|
||||
// PInvoke declaration for ChangeDisplaySettings Win32 API
|
||||
[DllImport("user32.dll")]
|
||||
public static extern int ChangeDisplaySettingsEx(
|
||||
string lpszDeviceName, ref DEVMODE lpDevMode, IntPtr hwnd,
|
||||
DisplaySettingsFlags dwflags, IntPtr lParam);
|
||||
|
||||
public static DEVMODE CreateDevmode()
|
||||
{
|
||||
DEVMODE dm = new DEVMODE();
|
||||
dm.dmDeviceName = new String(new char[32]);
|
||||
dm.dmFormName = new String(new char[32]);
|
||||
dm.dmSize = (short)Marshal.SizeOf(dm);
|
||||
return dm;
|
||||
}
|
||||
|
||||
public const int ENUM_CURRENT_SETTINGS = -1;
|
||||
public const string defaultDevice = "\\\\.\\DISPLAY1";
|
||||
|
||||
public static string FindLaptopScreen()
|
||||
{
|
||||
string laptopScreen = null;
|
||||
|
||||
try
|
||||
{
|
||||
var devices = GetAllDevices().ToArray();
|
||||
int count = 0, displayNum = -1;
|
||||
|
||||
foreach (var device in devices)
|
||||
{
|
||||
if (device.outputTechnology == DISPLAYCONFIG_VIDEO_OUTPUT_TECHNOLOGY.DISPLAYCONFIG_OUTPUT_TECHNOLOGY_INTERNAL ||
|
||||
device.outputTechnology == DISPLAYCONFIG_VIDEO_OUTPUT_TECHNOLOGY.DISPLAYCONFIG_OUTPUT_TECHNOLOGY_DISPLAYPORT_EMBEDDED)
|
||||
{
|
||||
displayNum = count;
|
||||
}
|
||||
count++;
|
||||
//Logger.WriteLine(device.outputTechnology.ToString());
|
||||
//Logger.WriteLine(device.monitorFriendlyDeviceName);
|
||||
}
|
||||
|
||||
var screens = Screen.AllScreens;
|
||||
|
||||
if (screens.Length != count) return null;
|
||||
|
||||
count = 0;
|
||||
foreach (var screen in screens)
|
||||
{
|
||||
if (count == displayNum)
|
||||
{
|
||||
laptopScreen = screen.DeviceName;
|
||||
}
|
||||
//Logger.WriteLine(screen.DeviceName);
|
||||
count++;
|
||||
}
|
||||
|
||||
if (displayNum > 0 && count == 0) laptopScreen = defaultDevice;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.WriteLine(ex.ToString());
|
||||
Logger.WriteLine("Can't detect internal screen");
|
||||
laptopScreen = Screen.PrimaryScreen.DeviceName;
|
||||
}
|
||||
|
||||
|
||||
return laptopScreen;
|
||||
}
|
||||
|
||||
public static int GetRefreshRate(bool max = false)
|
||||
{
|
||||
DEVMODE dm = CreateDevmode();
|
||||
|
||||
string laptopScreen = FindLaptopScreen();
|
||||
int frequency = -1;
|
||||
|
||||
if (laptopScreen is null)
|
||||
return -1;
|
||||
|
||||
if (max)
|
||||
{
|
||||
int i = 0;
|
||||
while (0 != NativeMethods.EnumDisplaySettingsEx(laptopScreen, i, ref dm))
|
||||
{
|
||||
if (dm.dmDisplayFrequency > frequency) frequency = dm.dmDisplayFrequency;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (0 != NativeMethods.EnumDisplaySettingsEx(laptopScreen, NativeMethods.ENUM_CURRENT_SETTINGS, ref dm))
|
||||
{
|
||||
frequency = dm.dmDisplayFrequency;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return frequency;
|
||||
}
|
||||
|
||||
public static int SetRefreshRate(int frequency = 120)
|
||||
{
|
||||
DEVMODE dm = CreateDevmode();
|
||||
string laptopScreen = FindLaptopScreen();
|
||||
|
||||
if (laptopScreen is null)
|
||||
return -1;
|
||||
|
||||
if (0 != NativeMethods.EnumDisplaySettingsEx(laptopScreen, NativeMethods.ENUM_CURRENT_SETTINGS, ref dm))
|
||||
{
|
||||
dm.dmDisplayFrequency = frequency;
|
||||
int iRet = NativeMethods.ChangeDisplaySettingsEx(laptopScreen, ref dm, IntPtr.Zero, DisplaySettingsFlags.CDS_UPDATEREGISTRY, IntPtr.Zero);
|
||||
Logger.WriteLine("Screen = " + frequency.ToString() + "Hz : " + (iRet == 0 ? "OK" : iRet));
|
||||
|
||||
return iRet;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
static Guid GetActiveScheme()
|
||||
{
|
||||
IntPtr pActiveSchemeGuid;
|
||||
var hr = PowerGetActiveScheme(IntPtr.Zero, out pActiveSchemeGuid);
|
||||
Guid activeSchemeGuid = (Guid)Marshal.PtrToStructure(pActiveSchemeGuid, typeof(Guid));
|
||||
return activeSchemeGuid;
|
||||
}
|
||||
|
||||
public static int GetCPUBoost()
|
||||
{
|
||||
IntPtr AcValueIndex;
|
||||
Guid activeSchemeGuid = GetActiveScheme();
|
||||
|
||||
UInt32 value = PowerReadACValueIndex(IntPtr.Zero,
|
||||
activeSchemeGuid,
|
||||
GUID_CPU,
|
||||
GUID_BOOST, out AcValueIndex);
|
||||
|
||||
return AcValueIndex.ToInt32();
|
||||
|
||||
}
|
||||
|
||||
public static void SetCPUBoost(int boost = 0)
|
||||
{
|
||||
Guid activeSchemeGuid = GetActiveScheme();
|
||||
|
||||
if (boost == GetCPUBoost()) return;
|
||||
|
||||
var hrAC = PowerWriteACValueIndex(
|
||||
IntPtr.Zero,
|
||||
activeSchemeGuid,
|
||||
GUID_CPU,
|
||||
GUID_BOOST,
|
||||
boost);
|
||||
|
||||
PowerSetActiveScheme(IntPtr.Zero, activeSchemeGuid);
|
||||
|
||||
var hrDC = PowerWriteDCValueIndex(
|
||||
IntPtr.Zero,
|
||||
activeSchemeGuid,
|
||||
GUID_CPU,
|
||||
GUID_BOOST,
|
||||
boost);
|
||||
|
||||
PowerSetActiveScheme(IntPtr.Zero, activeSchemeGuid);
|
||||
|
||||
Logger.WriteLine("Boost " + boost);
|
||||
}
|
||||
|
||||
public static void SetPowerScheme(string scheme)
|
||||
{
|
||||
PowerSetActiveScheme(IntPtr.Zero, new Guid(scheme));
|
||||
PowerSetActiveOverlayScheme(new Guid(scheme));
|
||||
Logger.WriteLine(scheme);
|
||||
}
|
||||
|
||||
public static void SetPowerScheme(int mode)
|
||||
{
|
||||
switch (mode)
|
||||
{
|
||||
case 0: // balanced
|
||||
PowerSetActiveOverlayScheme(new Guid("00000000-0000-0000-0000-000000000000"));
|
||||
break;
|
||||
case 1: // turbo
|
||||
PowerSetActiveOverlayScheme(new Guid("ded574b5-45a0-4f42-8737-46345c09c238"));
|
||||
break;
|
||||
case 2: //silent
|
||||
PowerSetActiveOverlayScheme(new Guid("961cc777-2547-4f9d-8174-7d86181b8a7a"));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,200 +0,0 @@
|
||||
using System;
|
||||
using NvAPIWrapper.Native.Display;
|
||||
using NvAPIWrapper.Native.Display.Structures;
|
||||
using NvAPIWrapper.Native.Interfaces.Display;
|
||||
|
||||
namespace NvAPIWrapper.Display
|
||||
{
|
||||
/// <inheritdoc cref="IColorData" />
|
||||
public class ColorData : IColorData, IEquatable<ColorData>
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates an instance of <see cref="ColorData" /> to modify the color data
|
||||
/// </summary>
|
||||
/// <param name="colorFormat">The color data color format.</param>
|
||||
/// <param name="colorimetry">The color data color space.</param>
|
||||
/// <param name="dynamicRange">The color data dynamic range.</param>
|
||||
/// <param name="colorDepth">The color data color depth.</param>
|
||||
/// <param name="colorSelectionPolicy">The color data selection policy.</param>
|
||||
/// <param name="desktopColorDepth">The color data desktop color depth.</param>
|
||||
public ColorData(
|
||||
ColorDataFormat colorFormat = ColorDataFormat.Auto,
|
||||
ColorDataColorimetry colorimetry = ColorDataColorimetry.Auto,
|
||||
ColorDataDynamicRange? dynamicRange = null,
|
||||
ColorDataDepth? colorDepth = null,
|
||||
ColorDataSelectionPolicy? colorSelectionPolicy = null,
|
||||
ColorDataDesktopDepth? desktopColorDepth = null
|
||||
)
|
||||
{
|
||||
ColorFormat = colorFormat;
|
||||
Colorimetry = colorimetry;
|
||||
DynamicRange = dynamicRange;
|
||||
ColorDepth = colorDepth;
|
||||
SelectionPolicy = colorSelectionPolicy;
|
||||
DesktopColorDepth = desktopColorDepth;
|
||||
}
|
||||
|
||||
internal ColorData(IColorData colorData)
|
||||
{
|
||||
ColorDepth = colorData.ColorDepth;
|
||||
DynamicRange = colorData.DynamicRange;
|
||||
ColorFormat = colorData.ColorFormat;
|
||||
Colorimetry = colorData.Colorimetry;
|
||||
SelectionPolicy = colorData.SelectionPolicy;
|
||||
DesktopColorDepth = colorData.DesktopColorDepth;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public ColorDataDepth? ColorDepth { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public ColorDataFormat ColorFormat { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public ColorDataColorimetry Colorimetry { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public ColorDataDesktopDepth? DesktopColorDepth { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public ColorDataDynamicRange? DynamicRange { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public ColorDataSelectionPolicy? SelectionPolicy { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool Equals(ColorData other)
|
||||
{
|
||||
if (ReferenceEquals(null, other))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ReferenceEquals(this, other))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return ColorDepth == other.ColorDepth &&
|
||||
ColorFormat == other.ColorFormat &&
|
||||
Colorimetry == other.Colorimetry &&
|
||||
DesktopColorDepth == other.DesktopColorDepth &&
|
||||
DynamicRange == other.DynamicRange &&
|
||||
SelectionPolicy == other.SelectionPolicy;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compares two instances of <see cref="ColorData" /> for equality.
|
||||
/// </summary>
|
||||
/// <param name="left">The first instance.</param>
|
||||
/// <param name="right">The second instance.</param>
|
||||
/// <returns>true if two instances are equal; otherwise false.</returns>
|
||||
public static bool operator ==(ColorData left, ColorData right)
|
||||
{
|
||||
return left?.Equals(right) == true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compares two instances of <see cref="ColorData" /> for inequality.
|
||||
/// </summary>
|
||||
/// <param name="left">The first instance.</param>
|
||||
/// <param name="right">The second instance.</param>
|
||||
/// <returns>true if two instances are not equal; otherwise false.</returns>
|
||||
public static bool operator !=(ColorData left, ColorData right)
|
||||
{
|
||||
return !(left == right);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (ReferenceEquals(null, obj))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ReferenceEquals(this, obj))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (obj.GetType() != GetType())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return Equals((ColorData) obj);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override int GetHashCode()
|
||||
{
|
||||
unchecked
|
||||
{
|
||||
var hashCode = ColorDepth.GetHashCode();
|
||||
hashCode = (hashCode * 397) ^ (int) ColorFormat;
|
||||
hashCode = (hashCode * 397) ^ (int) Colorimetry;
|
||||
hashCode = (hashCode * 397) ^ DesktopColorDepth.GetHashCode();
|
||||
hashCode = (hashCode * 397) ^ DynamicRange.GetHashCode();
|
||||
hashCode = (hashCode * 397) ^ SelectionPolicy.GetHashCode();
|
||||
|
||||
return hashCode;
|
||||
}
|
||||
}
|
||||
|
||||
internal ColorDataV1 AsColorDataV1(ColorDataCommand command)
|
||||
{
|
||||
return new ColorDataV1(
|
||||
command,
|
||||
ColorFormat,
|
||||
Colorimetry
|
||||
);
|
||||
}
|
||||
|
||||
internal ColorDataV2 AsColorDataV2(ColorDataCommand command)
|
||||
{
|
||||
return new ColorDataV2(
|
||||
command,
|
||||
ColorFormat,
|
||||
Colorimetry,
|
||||
DynamicRange ?? ColorDataDynamicRange.Auto
|
||||
);
|
||||
}
|
||||
|
||||
internal ColorDataV3 AsColorDataV3(ColorDataCommand command)
|
||||
{
|
||||
return new ColorDataV3(
|
||||
command,
|
||||
ColorFormat,
|
||||
Colorimetry,
|
||||
DynamicRange ?? ColorDataDynamicRange.Auto,
|
||||
ColorDepth ?? ColorDataDepth.Default
|
||||
);
|
||||
}
|
||||
|
||||
internal ColorDataV4 AsColorDataV4(ColorDataCommand command)
|
||||
{
|
||||
return new ColorDataV4(
|
||||
command,
|
||||
ColorFormat,
|
||||
Colorimetry,
|
||||
DynamicRange ?? ColorDataDynamicRange.Auto,
|
||||
ColorDepth ?? ColorDataDepth.Default,
|
||||
SelectionPolicy ?? ColorDataSelectionPolicy.Default
|
||||
);
|
||||
}
|
||||
|
||||
internal ColorDataV5 AsColorDataV5(ColorDataCommand command)
|
||||
{
|
||||
return new ColorDataV5(
|
||||
command,
|
||||
ColorFormat,
|
||||
Colorimetry,
|
||||
DynamicRange ?? ColorDataDynamicRange.Auto,
|
||||
ColorDepth ?? ColorDataDepth.Default,
|
||||
SelectionPolicy ?? ColorDataSelectionPolicy.Default,
|
||||
DesktopColorDepth ?? ColorDataDesktopDepth.Default
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,245 +0,0 @@
|
||||
using System;
|
||||
using NvAPIWrapper.Native.Display;
|
||||
using NvAPIWrapper.Native.Display.Structures;
|
||||
|
||||
namespace NvAPIWrapper.Display
|
||||
{
|
||||
/// <summary>
|
||||
/// Hold information about a custom display resolution
|
||||
/// </summary>
|
||||
public class CustomResolution : IEquatable<CustomResolution>
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates an instance of <see cref="CustomResolution" />.
|
||||
/// </summary>
|
||||
/// <param name="width">The screen width.</param>
|
||||
/// <param name="height">The screen height.</param>
|
||||
/// <param name="colorFormat">The color format.</param>
|
||||
/// <param name="timing">The resolution timing.</param>
|
||||
/// <param name="xRatio">The horizontal scaling ratio.</param>
|
||||
/// <param name="yRatio">The vertical scaling ratio.</param>
|
||||
public CustomResolution(
|
||||
uint width,
|
||||
uint height,
|
||||
ColorFormat colorFormat,
|
||||
Timing timing,
|
||||
float xRatio = 1,
|
||||
float yRatio = 1
|
||||
)
|
||||
{
|
||||
if (xRatio <= 0)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(xRatio));
|
||||
}
|
||||
|
||||
if (yRatio <= 0)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(yRatio));
|
||||
}
|
||||
|
||||
Width = width;
|
||||
Height = height;
|
||||
ColorFormat = colorFormat;
|
||||
XRatio = xRatio;
|
||||
YRatio = yRatio;
|
||||
Timing = timing;
|
||||
|
||||
switch (ColorFormat)
|
||||
{
|
||||
case ColorFormat.P8:
|
||||
ColorDepth = 8;
|
||||
|
||||
break;
|
||||
case ColorFormat.R5G6B5:
|
||||
ColorDepth = 16;
|
||||
|
||||
break;
|
||||
case ColorFormat.A8R8G8B8:
|
||||
ColorDepth = 24;
|
||||
|
||||
break;
|
||||
case ColorFormat.A16B16G16R16F:
|
||||
ColorDepth = 32;
|
||||
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentException("Color format is invalid.", nameof(colorFormat));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates an instance of <see cref="CustomResolution" />.
|
||||
/// </summary>
|
||||
/// <param name="width">The screen width.</param>
|
||||
/// <param name="height">The screen height.</param>
|
||||
/// <param name="colorDepth">The color depth.</param>
|
||||
/// <param name="timing">The resolution timing.</param>
|
||||
/// <param name="xRatio">The horizontal scaling ratio.</param>
|
||||
/// <param name="yRatio">The vertical scaling ratio.</param>
|
||||
public CustomResolution(
|
||||
uint width,
|
||||
uint height,
|
||||
uint colorDepth,
|
||||
Timing timing,
|
||||
float xRatio = 1,
|
||||
float yRatio = 1)
|
||||
{
|
||||
if (xRatio <= 0)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(xRatio));
|
||||
}
|
||||
|
||||
if (yRatio <= 0)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(yRatio));
|
||||
}
|
||||
|
||||
if (colorDepth != 0 && colorDepth != 8 && colorDepth != 16 && colorDepth != 24 && colorDepth != 32)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(colorDepth));
|
||||
}
|
||||
|
||||
Width = width;
|
||||
Height = height;
|
||||
ColorDepth = colorDepth;
|
||||
ColorFormat = ColorFormat.Unknown;
|
||||
XRatio = xRatio;
|
||||
YRatio = yRatio;
|
||||
Timing = timing;
|
||||
}
|
||||
|
||||
internal CustomResolution(CustomDisplay customDisplay)
|
||||
{
|
||||
Width = customDisplay.Width;
|
||||
Height = customDisplay.Height;
|
||||
ColorDepth = customDisplay.Depth;
|
||||
ColorFormat = customDisplay.ColorFormat;
|
||||
Timing = customDisplay.Timing;
|
||||
XRatio = customDisplay.XRatio;
|
||||
YRatio = customDisplay.YRatio;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the source surface color depth. "0" means all 8/16/32bpp.
|
||||
/// </summary>
|
||||
public uint ColorDepth { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the color format (optional)
|
||||
/// </summary>
|
||||
public ColorFormat ColorFormat { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the source surface (source mode) height.
|
||||
/// </summary>
|
||||
public uint Height { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the timing used to program TMDS/DAC/LVDS/HDMI/TVEncoder, etc.
|
||||
/// </summary>
|
||||
public Timing Timing { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the source surface (source mode) width.
|
||||
/// </summary>
|
||||
public uint Width { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the horizontal scaling ratio.
|
||||
/// </summary>
|
||||
public float XRatio { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the vertical scaling ratio.
|
||||
/// </summary>
|
||||
public float YRatio { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool Equals(CustomResolution other)
|
||||
{
|
||||
if (ReferenceEquals(null, other))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ReferenceEquals(this, other))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return Width == other.Width &&
|
||||
Height == other.Height &&
|
||||
ColorDepth == other.ColorDepth &&
|
||||
Timing.Equals(other.Timing) &&
|
||||
ColorFormat == other.ColorFormat &&
|
||||
XRatio.Equals(other.XRatio) &&
|
||||
YRatio.Equals(other.YRatio);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compares two instance of <see cref="CustomResolution" /> for equality.
|
||||
/// </summary>
|
||||
/// <param name="left">An first instance of <see cref="CustomResolution" /> to compare.</param>
|
||||
/// <param name="right">An Second instance of <see cref="CustomResolution" /> to compare.</param>
|
||||
/// <returns>True if both instances are equal, otherwise false.</returns>
|
||||
public static bool operator ==(CustomResolution left, CustomResolution right)
|
||||
{
|
||||
return Equals(left, right);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compares two instance of <see cref="CustomResolution" /> for inequality.
|
||||
/// </summary>
|
||||
/// <param name="left">An first instance of <see cref="CustomResolution" /> to compare.</param>
|
||||
/// <param name="right">An Second instance of <see cref="CustomResolution" /> to compare.</param>
|
||||
/// <returns>True if both instances are not equal, otherwise false.</returns>
|
||||
public static bool operator !=(CustomResolution left, CustomResolution right)
|
||||
{
|
||||
return !Equals(left, right);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (ReferenceEquals(null, obj))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ReferenceEquals(this, obj))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (obj.GetType() != GetType())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return Equals((CustomResolution) obj);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override int GetHashCode()
|
||||
{
|
||||
unchecked
|
||||
{
|
||||
var hashCode = (int) Width;
|
||||
hashCode = (hashCode * 397) ^ (int) Height;
|
||||
hashCode = (hashCode * 397) ^ (int) ColorDepth;
|
||||
hashCode = (hashCode * 397) ^ Timing.GetHashCode();
|
||||
hashCode = (hashCode * 397) ^ (int) ColorFormat;
|
||||
hashCode = (hashCode * 397) ^ XRatio.GetHashCode();
|
||||
hashCode = (hashCode * 397) ^ YRatio.GetHashCode();
|
||||
|
||||
return hashCode;
|
||||
}
|
||||
}
|
||||
|
||||
internal CustomDisplay AsCustomDisplay(bool hardwareModeSetOnly)
|
||||
{
|
||||
return new CustomDisplay(Width, Height, ColorDepth, ColorFormat, XRatio, YRatio, Timing,
|
||||
hardwareModeSetOnly);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,325 +0,0 @@
|
||||
using System;
|
||||
using NvAPIWrapper.Native;
|
||||
using NvAPIWrapper.Native.Display.Structures;
|
||||
using NvAPIWrapper.Native.GPU;
|
||||
using NvAPIWrapper.Native.Interfaces.Display;
|
||||
|
||||
namespace NvAPIWrapper.Display
|
||||
{
|
||||
/// <summary>
|
||||
/// This class contains and provides a way to modify the Digital Vibrance Control information regarding the
|
||||
/// saturation level of the display or the output
|
||||
/// </summary>
|
||||
public class DVCInformation : IDisplayDVCInfo
|
||||
{
|
||||
private readonly DisplayHandle _displayHandle = DisplayHandle.DefaultHandle;
|
||||
private readonly OutputId _outputId = OutputId.Invalid;
|
||||
private bool? _isLegacy;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the class using a DisplayHandle
|
||||
/// </summary>
|
||||
/// <param name="displayHandle">The handle of the display.</param>
|
||||
public DVCInformation(DisplayHandle displayHandle)
|
||||
{
|
||||
_displayHandle = displayHandle;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of this class using a OutputId
|
||||
/// </summary>
|
||||
/// <param name="outputId">The output identification of a display or an output</param>
|
||||
public DVCInformation(OutputId outputId)
|
||||
{
|
||||
_outputId = outputId;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets and sets the normalized saturation level in the [-1,1] inclusive range.
|
||||
/// a -1 value corresponds to the minimum saturation level and maximum under-saturation and the
|
||||
/// a 1 value corresponds to the maximum saturation level and maximum over-saturation.
|
||||
/// The value of 0 indicates the default saturation level.
|
||||
/// </summary>
|
||||
public double NormalizedLevel
|
||||
{
|
||||
get
|
||||
{
|
||||
var info = GetInfo();
|
||||
|
||||
if (info == null)
|
||||
{
|
||||
return double.NaN;
|
||||
}
|
||||
|
||||
var deviance = info.CurrentLevel - info.DefaultLevel;
|
||||
var range = deviance >= 0
|
||||
? info.MaximumLevel - info.DefaultLevel
|
||||
: info.DefaultLevel - info.MinimumLevel;
|
||||
|
||||
if (deviance == 0 || range == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return Math.Max(Math.Min((double) deviance / range, 1), -1);
|
||||
}
|
||||
set
|
||||
{
|
||||
if (double.IsNaN(value) || double.IsInfinity(value))
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(value));
|
||||
}
|
||||
|
||||
var info = GetInfo();
|
||||
|
||||
if (info == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var range = value >= 0 ? info.MaximumLevel - info.DefaultLevel : info.DefaultLevel - info.MinimumLevel;
|
||||
var level = Math.Max(Math.Min((int) (value * range) + info.DefaultLevel, info.MaximumLevel), info.MinimumLevel);
|
||||
|
||||
if (level == info.CurrentLevel)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
SetLevel(level);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets and sets the current saturation level
|
||||
/// </summary>
|
||||
public int CurrentLevel
|
||||
{
|
||||
get => GetInfo()?.CurrentLevel ?? 0;
|
||||
set
|
||||
{
|
||||
var info = GetInfo();
|
||||
|
||||
if (info == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
value = Math.Max(Math.Min(value, info.MaximumLevel), info.MinimumLevel);
|
||||
|
||||
if (info.CurrentLevel == value)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
SetLevel(value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public int DefaultLevel
|
||||
{
|
||||
get => GetInfo()?.DefaultLevel ?? 0;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public int MaximumLevel
|
||||
{
|
||||
get => GetInfo()?.MaximumLevel ?? 0;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public int MinimumLevel
|
||||
{
|
||||
get => GetInfo()?.MinimumLevel ?? 0;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string ToString()
|
||||
{
|
||||
return
|
||||
$"{CurrentLevel:D} @ [{MinimumLevel:D} <= {DefaultLevel:D} <= {MaximumLevel:D}] = {NormalizedLevel:F2}";
|
||||
}
|
||||
|
||||
private IDisplayDVCInfo GetInfo()
|
||||
{
|
||||
if (_isLegacy == true)
|
||||
{
|
||||
return GetLegacyInfo();
|
||||
}
|
||||
|
||||
if (_isLegacy == false)
|
||||
{
|
||||
return GetModernInfo();
|
||||
}
|
||||
|
||||
var info = GetModernInfo() ?? GetLegacyInfo();
|
||||
|
||||
if (info == null)
|
||||
{
|
||||
// exception occured on both, force a mode
|
||||
_isLegacy = false;
|
||||
|
||||
return GetInfo();
|
||||
}
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
private IDisplayDVCInfo GetLegacyInfo()
|
||||
{
|
||||
try
|
||||
{
|
||||
var info = _outputId == OutputId.Invalid
|
||||
? DisplayApi.GetDVCInfo(_displayHandle)
|
||||
: DisplayApi.GetDVCInfo(_outputId);
|
||||
|
||||
if (info.MaximumLevel == 0 && info.MinimumLevel == 0 && info.CurrentLevel == 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!_isLegacy.HasValue)
|
||||
{
|
||||
_isLegacy = true;
|
||||
}
|
||||
|
||||
|
||||
return info;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
if (_isLegacy == true)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
|
||||
// ignore
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private IDisplayDVCInfo GetModernInfo()
|
||||
{
|
||||
try
|
||||
{
|
||||
var info = _outputId == OutputId.Invalid
|
||||
? DisplayApi.GetDVCInfoEx(_displayHandle)
|
||||
: DisplayApi.GetDVCInfoEx(_outputId);
|
||||
|
||||
if (info.MaximumLevel == 0 && info.MinimumLevel == 0 && info.CurrentLevel == 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!_isLegacy.HasValue)
|
||||
{
|
||||
_isLegacy = false;
|
||||
}
|
||||
|
||||
return info;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
if (_isLegacy == false)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
|
||||
// ignore
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private bool SetLegacyLevel(int level)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (_outputId == OutputId.Invalid)
|
||||
{
|
||||
DisplayApi.SetDVCLevel(_displayHandle, level);
|
||||
}
|
||||
else
|
||||
{
|
||||
DisplayApi.SetDVCLevel(_outputId, level);
|
||||
}
|
||||
|
||||
if (!_isLegacy.HasValue)
|
||||
{
|
||||
_isLegacy = true;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
if (_isLegacy == true)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
|
||||
// ignore
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private void SetLevel(int level)
|
||||
{
|
||||
if (_isLegacy == true)
|
||||
{
|
||||
SetLegacyLevel(level);
|
||||
}
|
||||
else if (_isLegacy == false)
|
||||
{
|
||||
SetModernLevel(level);
|
||||
}
|
||||
else
|
||||
{
|
||||
var success = SetModernLevel(level) || SetLegacyLevel(level);
|
||||
|
||||
if (!success)
|
||||
{
|
||||
// exception occured on both, force a mode
|
||||
_isLegacy = false;
|
||||
|
||||
SetLevel(level);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bool SetModernLevel(int level)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (_outputId == OutputId.Invalid)
|
||||
{
|
||||
DisplayApi.SetDVCLevelEx(_displayHandle, level);
|
||||
}
|
||||
else
|
||||
{
|
||||
DisplayApi.SetDVCLevelEx(_outputId, level);
|
||||
}
|
||||
|
||||
if (!_isLegacy.HasValue)
|
||||
{
|
||||
_isLegacy = false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
if (_isLegacy == false)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
|
||||
// ignore
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,232 +0,0 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using NvAPIWrapper.GPU;
|
||||
using NvAPIWrapper.Native;
|
||||
using NvAPIWrapper.Native.Display;
|
||||
using NvAPIWrapper.Native.Display.Structures;
|
||||
using NvAPIWrapper.Native.Exceptions;
|
||||
using NvAPIWrapper.Native.GPU;
|
||||
using NvAPIWrapper.Native.Interfaces.Display;
|
||||
|
||||
namespace NvAPIWrapper.Display
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents an attached display
|
||||
/// </summary>
|
||||
public class Display : IEquatable<Display>
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates a new Display
|
||||
/// </summary>
|
||||
/// <param name="handle">Handle of the display device</param>
|
||||
public Display(DisplayHandle handle)
|
||||
{
|
||||
Handle = handle;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new Display
|
||||
/// </summary>
|
||||
/// <param name="displayName">Name of the display device</param>
|
||||
public Display(string displayName)
|
||||
{
|
||||
Handle = DisplayApi.GetAssociatedNvidiaDisplayHandle(displayName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the corresponding Digital Vibrance Control information
|
||||
/// </summary>
|
||||
public DVCInformation DigitalVibranceControl
|
||||
{
|
||||
get => new DVCInformation(Handle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets corresponding DisplayDevice based on display name
|
||||
/// </summary>
|
||||
public DisplayDevice DisplayDevice
|
||||
{
|
||||
get => new DisplayDevice(Name);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets display driver build title
|
||||
/// </summary>
|
||||
public string DriverBuildTitle
|
||||
{
|
||||
get => DisplayApi.GetDisplayDriverBuildTitle(Handle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets display handle
|
||||
/// </summary>
|
||||
public DisplayHandle Handle { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the display HDMI support information
|
||||
/// </summary>
|
||||
public IHDMISupportInfo HDMISupportInfo
|
||||
{
|
||||
get
|
||||
{
|
||||
var outputId = OutputId.Invalid;
|
||||
try
|
||||
{
|
||||
outputId = DisplayApi.GetAssociatedDisplayOutputId(Handle);
|
||||
}
|
||||
catch (NVIDIAApiException)
|
||||
{
|
||||
// ignore
|
||||
}
|
||||
return DisplayApi.GetHDMISupportInfo(Handle, outputId);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the corresponding HUE information
|
||||
/// </summary>
|
||||
public HUEInformation HUEControl
|
||||
{
|
||||
get => new HUEInformation(Handle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the driving logical GPU
|
||||
/// </summary>
|
||||
public LogicalGPU LogicalGPU
|
||||
{
|
||||
get => new LogicalGPU(GPUApi.GetLogicalGPUFromDisplay(Handle));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets display name
|
||||
/// </summary>
|
||||
public string Name
|
||||
{
|
||||
get => DisplayApi.GetAssociatedNvidiaDisplayName(Handle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the connected GPU output
|
||||
/// </summary>
|
||||
public GPUOutput Output
|
||||
{
|
||||
get => new GPUOutput(DisplayApi.GetAssociatedDisplayOutputId(Handle), PhysicalGPUs.FirstOrDefault());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the list of all physical GPUs responsible for this display, with the first GPU returned as the one with the
|
||||
/// attached active output.
|
||||
/// </summary>
|
||||
public PhysicalGPU[] PhysicalGPUs
|
||||
{
|
||||
get => GPUApi.GetPhysicalGPUsFromDisplay(Handle).Select(handle => new PhysicalGPU(handle)).ToArray();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool Equals(Display other)
|
||||
{
|
||||
if (ReferenceEquals(null, other))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ReferenceEquals(this, other))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return Handle.Equals(other.Handle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This function returns all NVIDIA displays
|
||||
/// Note: Display handles can get invalidated on a modeset.
|
||||
/// </summary>
|
||||
/// <returns>An array of Display objects</returns>
|
||||
public static Display[] GetDisplays()
|
||||
{
|
||||
return DisplayApi.EnumNvidiaDisplayHandle().Select(handle => new Display(handle)).ToArray();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks for equality between two objects of same type
|
||||
/// </summary>
|
||||
/// <param name="left">The first object</param>
|
||||
/// <param name="right">The second object</param>
|
||||
/// <returns>true, if both objects are equal, otherwise false</returns>
|
||||
public static bool operator ==(Display left, Display right)
|
||||
{
|
||||
return right?.Equals(left) ?? ReferenceEquals(left, null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks for inequality between two objects of same type
|
||||
/// </summary>
|
||||
/// <param name="left">The first object</param>
|
||||
/// <param name="right">The second object</param>
|
||||
/// <returns>true, if both objects are not equal, otherwise false</returns>
|
||||
public static bool operator !=(Display left, Display right)
|
||||
{
|
||||
return !(right == left);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (ReferenceEquals(null, obj))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ReferenceEquals(this, obj))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (obj.GetType() != GetType())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return Equals((Display) obj);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return Handle.GetHashCode();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string ToString()
|
||||
{
|
||||
return Name;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets all the supported NVIDIA display views (nView and Dualview modes) for this display.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public TargetViewMode[] GetSupportedViews()
|
||||
{
|
||||
return DisplayApi.GetSupportedViews(Handle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Overrides the refresh rate on this display.
|
||||
/// The new refresh rate can be applied right away or deferred to be applied with the next OS
|
||||
/// mode-set.
|
||||
/// The override is good for only one mode-set (regardless whether it's deferred or immediate).
|
||||
/// </summary>
|
||||
/// <param name="refreshRate">The refresh rate to be applied.</param>
|
||||
/// <param name="isDeferred">
|
||||
/// A boolean value indicating if the refresh rate override should be deferred to the next OS
|
||||
/// mode-set.
|
||||
/// </param>
|
||||
public void OverrideRefreshRate(float refreshRate, bool isDeferred = false)
|
||||
{
|
||||
DisplayApi.SetRefreshRateOverride(Handle, refreshRate, isDeferred);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,893 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using NvAPIWrapper.GPU;
|
||||
using NvAPIWrapper.Native;
|
||||
using NvAPIWrapper.Native.Display;
|
||||
using NvAPIWrapper.Native.Display.Structures;
|
||||
using NvAPIWrapper.Native.Exceptions;
|
||||
using NvAPIWrapper.Native.General;
|
||||
using NvAPIWrapper.Native.GPU;
|
||||
using NvAPIWrapper.Native.GPU.Structures;
|
||||
using NvAPIWrapper.Native.Interfaces.Display;
|
||||
using NvAPIWrapper.Native.Interfaces.GPU;
|
||||
|
||||
namespace NvAPIWrapper.Display
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents an NVIDIA display device
|
||||
/// </summary>
|
||||
public class DisplayDevice : IEquatable<DisplayDevice>
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates a new DisplayDevice
|
||||
/// </summary>
|
||||
/// <param name="displayId">Display identification of the device</param>
|
||||
public DisplayDevice(uint displayId)
|
||||
{
|
||||
DisplayId = displayId;
|
||||
var extraInformation = PhysicalGPU.GetDisplayDevices().FirstOrDefault(ids => ids.DisplayId == DisplayId);
|
||||
|
||||
if (extraInformation != null)
|
||||
{
|
||||
IsAvailable = true;
|
||||
ScanOutInformation = new ScanOutInformation(this);
|
||||
ConnectionType = extraInformation.ConnectionType;
|
||||
IsDynamic = extraInformation.IsDynamic;
|
||||
IsMultiStreamRootNode = extraInformation.IsMultiStreamRootNode;
|
||||
IsActive = extraInformation.IsActive;
|
||||
IsCluster = extraInformation.IsCluster;
|
||||
IsOSVisible = extraInformation.IsOSVisible;
|
||||
IsWFD = extraInformation.IsWFD;
|
||||
IsConnected = extraInformation.IsConnected;
|
||||
IsPhysicallyConnected = extraInformation.IsPhysicallyConnected;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new DisplayDevice
|
||||
/// </summary>
|
||||
/// <param name="displayIds">Display identification and attributes of the display device</param>
|
||||
public DisplayDevice(IDisplayIds displayIds)
|
||||
{
|
||||
IsAvailable = true;
|
||||
DisplayId = displayIds.DisplayId;
|
||||
ScanOutInformation = new ScanOutInformation(this);
|
||||
ConnectionType = displayIds.ConnectionType;
|
||||
IsDynamic = displayIds.IsDynamic;
|
||||
IsMultiStreamRootNode = displayIds.IsMultiStreamRootNode;
|
||||
IsActive = displayIds.IsActive;
|
||||
IsCluster = displayIds.IsCluster;
|
||||
IsOSVisible = displayIds.IsOSVisible;
|
||||
IsWFD = displayIds.IsWFD;
|
||||
IsConnected = displayIds.IsConnected;
|
||||
IsPhysicallyConnected = displayIds.IsPhysicallyConnected;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new DisplayDevice
|
||||
/// </summary>
|
||||
/// <param name="displayName">Display name of the display device</param>
|
||||
public DisplayDevice(string displayName) : this(DisplayApi.GetDisplayIdByDisplayName(displayName))
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the display device connection type
|
||||
/// </summary>
|
||||
public MonitorConnectionType ConnectionType { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current display color data
|
||||
/// </summary>
|
||||
public ColorData CurrentColorData
|
||||
{
|
||||
get
|
||||
{
|
||||
var instances = new IColorData[]
|
||||
{
|
||||
new ColorDataV5(ColorDataCommand.Get),
|
||||
new ColorDataV4(ColorDataCommand.Get),
|
||||
new ColorDataV3(ColorDataCommand.Get),
|
||||
new ColorDataV2(ColorDataCommand.Get),
|
||||
new ColorDataV1(ColorDataCommand.Get)
|
||||
};
|
||||
|
||||
var instance = DisplayApi.ColorControl(DisplayId, instances);
|
||||
|
||||
return new ColorData(instance);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current display device timing
|
||||
/// </summary>
|
||||
public Timing CurrentTiming
|
||||
{
|
||||
get => DisplayApi.GetTiming(DisplayId, new TimingInput(TimingOverride.Current));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the default display color data
|
||||
/// </summary>
|
||||
public ColorData DefaultColorData
|
||||
{
|
||||
get
|
||||
{
|
||||
var instances = new IColorData[]
|
||||
{
|
||||
new ColorDataV5(ColorDataCommand.GetDefault),
|
||||
new ColorDataV4(ColorDataCommand.GetDefault),
|
||||
new ColorDataV3(ColorDataCommand.GetDefault),
|
||||
new ColorDataV2(ColorDataCommand.GetDefault),
|
||||
new ColorDataV1(ColorDataCommand.GetDefault)
|
||||
};
|
||||
|
||||
var instance = DisplayApi.ColorControl(DisplayId, instances);
|
||||
|
||||
return new ColorData(instance);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the NVIDIA display identification
|
||||
/// </summary>
|
||||
public uint DisplayId { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the monitor Display port capabilities
|
||||
/// </summary>
|
||||
public MonitorColorData[] DisplayPortColorCapabilities
|
||||
{
|
||||
get
|
||||
{
|
||||
if (ConnectionType != MonitorConnectionType.DisplayPort)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return DisplayApi.GetMonitorColorCapabilities(DisplayId);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the display driver EDID specified HDR capabilities
|
||||
/// </summary>
|
||||
public HDRCapabilitiesV1 DriverHDRCapabilities
|
||||
{
|
||||
get => DisplayApi.GetHDRCapabilities(DisplayId, true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the display currently effective HDR capabilities
|
||||
/// </summary>
|
||||
public HDRCapabilitiesV1 EffectiveHDRCapabilities
|
||||
{
|
||||
get => DisplayApi.GetHDRCapabilities(DisplayId, false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the HDMI audio info-frame current information
|
||||
/// </summary>
|
||||
public InfoFrameAudio? HDMIAudioFrameCurrentInformation
|
||||
{
|
||||
get
|
||||
{
|
||||
try
|
||||
{
|
||||
var infoFrame = new InfoFrameData(InfoFrameCommand.Get, InfoFrameDataType.AudioInformation);
|
||||
DisplayApi.InfoFrameControl(DisplayId, ref infoFrame);
|
||||
|
||||
return infoFrame.AudioInformation;
|
||||
}
|
||||
catch (NVIDIAApiException e)
|
||||
{
|
||||
if (e.Status == Status.NotSupported)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets the HDMI audio info-frame default information
|
||||
/// </summary>
|
||||
public InfoFrameAudio? HDMIAudioFrameDefaultInformation
|
||||
{
|
||||
get
|
||||
{
|
||||
try
|
||||
{
|
||||
var infoFrame = new InfoFrameData(InfoFrameCommand.GetDefault, InfoFrameDataType.AudioInformation);
|
||||
DisplayApi.InfoFrameControl(DisplayId, ref infoFrame);
|
||||
|
||||
return infoFrame.AudioInformation;
|
||||
}
|
||||
catch (NVIDIAApiException e)
|
||||
{
|
||||
if (e.Status == Status.NotSupported)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the HDMI audio info-frame override information
|
||||
/// </summary>
|
||||
public InfoFrameAudio? HDMIAudioFrameOverrideInformation
|
||||
{
|
||||
get
|
||||
{
|
||||
try
|
||||
{
|
||||
var infoFrame = new InfoFrameData(InfoFrameCommand.GetOverride, InfoFrameDataType.AudioInformation);
|
||||
DisplayApi.InfoFrameControl(DisplayId, ref infoFrame);
|
||||
|
||||
return infoFrame.AudioInformation;
|
||||
}
|
||||
catch (NVIDIAApiException e)
|
||||
{
|
||||
if (e.Status == Status.NotSupported)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the HDMI audio info-frame property information
|
||||
/// </summary>
|
||||
public InfoFrameProperty? HDMIAudioFramePropertyInformation
|
||||
{
|
||||
get
|
||||
{
|
||||
try
|
||||
{
|
||||
var infoFrame = new InfoFrameData(InfoFrameCommand.GetProperty, InfoFrameDataType.AudioInformation);
|
||||
DisplayApi.InfoFrameControl(DisplayId, ref infoFrame);
|
||||
|
||||
return infoFrame.PropertyInformation;
|
||||
}
|
||||
catch (NVIDIAApiException e)
|
||||
{
|
||||
if (e.Status == Status.NotSupported)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the device HDMI support information
|
||||
/// </summary>
|
||||
public IHDMISupportInfo HDMISupportInfo
|
||||
{
|
||||
get => DisplayApi.GetHDMISupportInfo(DisplayId);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets the HDMI auxiliary video info-frame current information
|
||||
/// </summary>
|
||||
public InfoFrameVideo? HDMIVideoFrameCurrentInformation
|
||||
{
|
||||
get
|
||||
{
|
||||
try
|
||||
{
|
||||
var infoFrame =
|
||||
new InfoFrameData(InfoFrameCommand.Get, InfoFrameDataType.AuxiliaryVideoInformation);
|
||||
DisplayApi.InfoFrameControl(DisplayId, ref infoFrame);
|
||||
|
||||
return infoFrame.AuxiliaryVideoInformation;
|
||||
}
|
||||
catch (NVIDIAApiException e)
|
||||
{
|
||||
if (e.Status == Status.NotSupported)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the HDMI auxiliary video info-frame default information
|
||||
/// </summary>
|
||||
public InfoFrameVideo? HDMIVideoFrameDefaultInformation
|
||||
{
|
||||
get
|
||||
{
|
||||
try
|
||||
{
|
||||
var infoFrame = new InfoFrameData(InfoFrameCommand.GetDefault,
|
||||
InfoFrameDataType.AuxiliaryVideoInformation);
|
||||
DisplayApi.InfoFrameControl(DisplayId, ref infoFrame);
|
||||
|
||||
return infoFrame.AuxiliaryVideoInformation;
|
||||
}
|
||||
catch (NVIDIAApiException e)
|
||||
{
|
||||
if (e.Status == Status.NotSupported)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the HDMI auxiliary video info-frame override information
|
||||
/// </summary>
|
||||
public InfoFrameVideo? HDMIVideoFrameOverrideInformation
|
||||
{
|
||||
get
|
||||
{
|
||||
try
|
||||
{
|
||||
var infoFrame = new InfoFrameData(InfoFrameCommand.GetOverride,
|
||||
InfoFrameDataType.AuxiliaryVideoInformation);
|
||||
DisplayApi.InfoFrameControl(DisplayId, ref infoFrame);
|
||||
|
||||
return infoFrame.AuxiliaryVideoInformation;
|
||||
}
|
||||
catch (NVIDIAApiException e)
|
||||
{
|
||||
if (e.Status == Status.NotSupported)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the HDMI auxiliary video info-frame property information
|
||||
/// </summary>
|
||||
public InfoFrameProperty? HDMIVideoFramePropertyInformation
|
||||
{
|
||||
get
|
||||
{
|
||||
try
|
||||
{
|
||||
var infoFrame = new InfoFrameData(InfoFrameCommand.GetProperty,
|
||||
InfoFrameDataType.AuxiliaryVideoInformation);
|
||||
DisplayApi.InfoFrameControl(DisplayId, ref infoFrame);
|
||||
|
||||
return infoFrame.PropertyInformation;
|
||||
}
|
||||
catch (NVIDIAApiException e)
|
||||
{
|
||||
if (e.Status == Status.NotSupported)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the HDR color data, or null if the HDR is disabled or unavailable
|
||||
/// </summary>
|
||||
public HDRColorData HDRColorData
|
||||
{
|
||||
get
|
||||
{
|
||||
try
|
||||
{
|
||||
var instances = new IHDRColorData[]
|
||||
{
|
||||
new HDRColorDataV2(ColorDataHDRCommand.Get),
|
||||
new HDRColorDataV1(ColorDataHDRCommand.Get)
|
||||
};
|
||||
|
||||
var instance = DisplayApi.HDRColorControl(DisplayId, instances);
|
||||
|
||||
if (instance.HDRMode == ColorDataHDRMode.Off)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return new HDRColorData(instance);
|
||||
}
|
||||
catch (NVIDIAApiException e)
|
||||
{
|
||||
if (e.Status == Status.NotSupported)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Indicates if the display is being actively driven
|
||||
/// </summary>
|
||||
public bool IsActive { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates if the display device is currently available
|
||||
/// </summary>
|
||||
public bool IsAvailable { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates if the display is the representative display
|
||||
/// </summary>
|
||||
public bool IsCluster { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates if the display is connected
|
||||
/// </summary>
|
||||
public bool IsConnected { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates if the display is part of MST topology and it's a dynamic
|
||||
/// </summary>
|
||||
public bool IsDynamic { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates if the display identification belongs to a multi stream enabled connector (root node). Note that when
|
||||
/// multi stream is enabled and a single multi stream capable monitor is connected to it, the monitor will share the
|
||||
/// display id with the RootNode.
|
||||
/// When there is more than one monitor connected in a multi stream topology, then the root node will have a separate
|
||||
/// displayId.
|
||||
/// </summary>
|
||||
public bool IsMultiStreamRootNode { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates if the display is reported to the OS
|
||||
/// </summary>
|
||||
public bool IsOSVisible { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates if the display is a physically connected display; Valid only when IsConnected is true
|
||||
/// </summary>
|
||||
public bool IsPhysicallyConnected { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates if the display is wireless
|
||||
/// </summary>
|
||||
public bool IsWFD { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the connected GPU output
|
||||
/// </summary>
|
||||
public GPUOutput Output
|
||||
{
|
||||
get
|
||||
{
|
||||
PhysicalGPUHandle handle;
|
||||
var outputId = GPUApi.GetGPUAndOutputIdFromDisplayId(DisplayId, out handle);
|
||||
|
||||
return new GPUOutput(outputId, new PhysicalGPU(handle));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the connected physical GPU
|
||||
/// </summary>
|
||||
public PhysicalGPU PhysicalGPU
|
||||
{
|
||||
get
|
||||
{
|
||||
try
|
||||
{
|
||||
var gpuHandle = GPUApi.GetPhysicalGPUFromDisplayId(DisplayId);
|
||||
|
||||
return new PhysicalGPU(gpuHandle);
|
||||
}
|
||||
catch
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
|
||||
return Output.PhysicalGPU;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets information regarding the scan-out settings of this display device
|
||||
/// </summary>
|
||||
public ScanOutInformation ScanOutInformation { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets monitor capabilities from the Video Capability Data Block if available, otherwise null
|
||||
/// </summary>
|
||||
public MonitorVCDBCapabilities? VCDBMonitorCapabilities
|
||||
{
|
||||
get => DisplayApi.GetMonitorCapabilities(DisplayId, MonitorCapabilitiesType.VCDB)?.VCDBCapabilities;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets monitor capabilities from the Vendor Specific Data Block if available, otherwise null
|
||||
/// </summary>
|
||||
public MonitorVSDBCapabilities? VSDBMonitorCapabilities
|
||||
{
|
||||
get => DisplayApi.GetMonitorCapabilities(DisplayId, MonitorCapabilitiesType.VSDB)?.VSDBCapabilities;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool Equals(DisplayDevice other)
|
||||
{
|
||||
if (ReferenceEquals(null, other))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ReferenceEquals(this, other))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return DisplayId == other.DisplayId;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Deletes a custom resolution.
|
||||
/// </summary>
|
||||
/// <param name="customResolution">The custom resolution to delete.</param>
|
||||
/// <param name="displayIds">A list of display ids to remove the custom resolution from.</param>
|
||||
public static void DeleteCustomResolution(CustomResolution customResolution, uint[] displayIds)
|
||||
{
|
||||
var customDisplay = customResolution.AsCustomDisplay(false);
|
||||
DisplayApi.DeleteCustomDisplay(displayIds, customDisplay);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns an instance of <see cref="DisplayDevice" /> representing the primary GDI display device.
|
||||
/// </summary>
|
||||
/// <returns>An instance of <see cref="DisplayDevice" />.</returns>
|
||||
public static DisplayDevice GetGDIPrimaryDisplayDevice()
|
||||
{
|
||||
var displayId = DisplayApi.GetGDIPrimaryDisplayId();
|
||||
|
||||
if (displayId == 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return new DisplayDevice(displayId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks for equality between two objects of same type
|
||||
/// </summary>
|
||||
/// <param name="left">The first object</param>
|
||||
/// <param name="right">The second object</param>
|
||||
/// <returns>true, if both objects are equal, otherwise false</returns>
|
||||
public static bool operator ==(DisplayDevice left, DisplayDevice right)
|
||||
{
|
||||
return right?.Equals(left) ?? ReferenceEquals(left, null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks for inequality between two objects of same type
|
||||
/// </summary>
|
||||
/// <param name="left">The first object</param>
|
||||
/// <param name="right">The second object</param>
|
||||
/// <returns>true, if both objects are not equal, otherwise false</returns>
|
||||
public static bool operator !=(DisplayDevice left, DisplayDevice right)
|
||||
{
|
||||
return !(right == left);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reverts the custom resolution currently on trial.
|
||||
/// </summary>
|
||||
/// <param name="displayIds">A list of display ids to revert the custom resolution from.</param>
|
||||
public static void RevertCustomResolution(uint[] displayIds)
|
||||
{
|
||||
DisplayApi.RevertCustomDisplayTrial(displayIds);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Saves the custom resolution currently on trial.
|
||||
/// </summary>
|
||||
/// <param name="displayIds">A list of display ids to save the custom resolution for.</param>
|
||||
/// <param name="isThisOutputIdOnly">
|
||||
/// If set, the saved custom display will only be applied on the monitor with the same
|
||||
/// outputId.
|
||||
/// </param>
|
||||
/// <param name="isThisMonitorOnly">
|
||||
/// If set, the saved custom display will only be applied on the monitor with the same EDID
|
||||
/// ID or the same TV connector in case of analog TV.
|
||||
/// </param>
|
||||
public static void SaveCustomResolution(uint[] displayIds, bool isThisOutputIdOnly, bool isThisMonitorOnly)
|
||||
{
|
||||
DisplayApi.SaveCustomDisplay(displayIds, isThisOutputIdOnly, isThisMonitorOnly);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Applies a custom resolution into trial
|
||||
/// </summary>
|
||||
/// <param name="customResolution">The custom resolution to apply.</param>
|
||||
/// <param name="displayIds">A list of display ids to apply the custom resolution on.</param>
|
||||
/// <param name="hardwareModeSetOnly">
|
||||
/// A boolean value indicating that a hardware mode-set without OS update should be
|
||||
/// performed.
|
||||
/// </param>
|
||||
public static void TrialCustomResolution(
|
||||
CustomResolution customResolution,
|
||||
uint[] displayIds,
|
||||
bool hardwareModeSetOnly = true)
|
||||
{
|
||||
var customDisplay = customResolution.AsCustomDisplay(hardwareModeSetOnly);
|
||||
DisplayApi.TryCustomDisplay(displayIds.ToDictionary(u => u, u => customDisplay));
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (ReferenceEquals(null, obj))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ReferenceEquals(this, obj))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (obj.GetType() != GetType())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return Equals((DisplayDevice) obj);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return (int) DisplayId;
|
||||
}
|
||||
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string ToString()
|
||||
{
|
||||
return $"Display #{DisplayId}";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculates a valid timing based on the argument passed
|
||||
/// </summary>
|
||||
/// <param name="width">The preferred width.</param>
|
||||
/// <param name="height">The preferred height.</param>
|
||||
/// <param name="refreshRate">The preferred refresh rate.</param>
|
||||
/// <param name="isInterlaced">The boolean value indicating if the preferred resolution is an interlaced resolution.</param>
|
||||
/// <returns>Returns a valid instance of <see cref="Timing" />.</returns>
|
||||
public Timing CalculateTiming(uint width, uint height, float refreshRate, bool isInterlaced)
|
||||
{
|
||||
return DisplayApi.GetTiming(
|
||||
DisplayId,
|
||||
new TimingInput(width, height, refreshRate, TimingOverride.Auto, isInterlaced)
|
||||
);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Deletes a custom resolution.
|
||||
/// </summary>
|
||||
/// <param name="customResolution">The custom resolution to delete.</param>
|
||||
public void DeleteCustomResolution(CustomResolution customResolution)
|
||||
{
|
||||
DeleteCustomResolution(customResolution, new[] {DisplayId});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the list of custom resolutions saved for this display device
|
||||
/// </summary>
|
||||
/// <returns>A list of <see cref="CustomResolution" /> instances.</returns>
|
||||
public IEnumerable<CustomResolution> GetCustomResolutions()
|
||||
{
|
||||
return DisplayApi.EnumCustomDisplays(DisplayId).Select(custom => new CustomResolution(custom));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks if a color data is supported on this display
|
||||
/// </summary>
|
||||
/// <param name="colorData">The color data to be checked.</param>
|
||||
/// <returns>true if the color data passed is supported; otherwise false</returns>
|
||||
public bool IsColorDataSupported(ColorData colorData)
|
||||
{
|
||||
var instances = new IColorData[]
|
||||
{
|
||||
colorData.AsColorDataV5(ColorDataCommand.IsSupportedColor),
|
||||
colorData.AsColorDataV4(ColorDataCommand.IsSupportedColor),
|
||||
colorData.AsColorDataV3(ColorDataCommand.IsSupportedColor),
|
||||
colorData.AsColorDataV2(ColorDataCommand.IsSupportedColor),
|
||||
colorData.AsColorDataV1(ColorDataCommand.IsSupportedColor)
|
||||
};
|
||||
|
||||
try
|
||||
{
|
||||
DisplayApi.ColorControl(DisplayId, instances);
|
||||
|
||||
return true;
|
||||
}
|
||||
catch (NVIDIAApiException e)
|
||||
{
|
||||
if (e.Status == Status.NotSupported)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets the HDMI audio info-frame information to default
|
||||
/// </summary>
|
||||
public void ResetHDMIAudioFrameInformation()
|
||||
{
|
||||
var infoFrame = new InfoFrameData(
|
||||
InfoFrameCommand.Reset,
|
||||
InfoFrameDataType.AudioInformation
|
||||
);
|
||||
DisplayApi.InfoFrameControl(DisplayId, ref infoFrame);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets the HDMI auxiliary video info-frame information to default
|
||||
/// </summary>
|
||||
public void ResetHDMIVideoFrameInformation()
|
||||
{
|
||||
var infoFrame = new InfoFrameData(
|
||||
InfoFrameCommand.Reset,
|
||||
InfoFrameDataType.AuxiliaryVideoInformation
|
||||
);
|
||||
DisplayApi.InfoFrameControl(DisplayId, ref infoFrame);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reverts the custom resolution currently on trial.
|
||||
/// </summary>
|
||||
public void RevertCustomResolution()
|
||||
{
|
||||
RevertCustomResolution(new[] {DisplayId});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Saves the custom resolution currently on trial.
|
||||
/// </summary>
|
||||
/// <param name="isThisOutputIdOnly">
|
||||
/// If set, the saved custom display will only be applied on the monitor with the same
|
||||
/// outputId.
|
||||
/// </param>
|
||||
/// <param name="isThisMonitorOnly">
|
||||
/// If set, the saved custom display will only be applied on the monitor with the same EDID
|
||||
/// ID or the same TV connector in case of analog TV.
|
||||
/// </param>
|
||||
public void SaveCustomResolution(bool isThisOutputIdOnly = true, bool isThisMonitorOnly = true)
|
||||
{
|
||||
SaveCustomResolution(new[] {DisplayId}, isThisOutputIdOnly, isThisMonitorOnly);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Changes the display current color data configuration
|
||||
/// </summary>
|
||||
/// <param name="colorData">The color data to be set.</param>
|
||||
public void SetColorData(ColorData colorData)
|
||||
{
|
||||
var instances = new IColorData[]
|
||||
{
|
||||
colorData.AsColorDataV5(ColorDataCommand.Set),
|
||||
colorData.AsColorDataV4(ColorDataCommand.Set),
|
||||
colorData.AsColorDataV3(ColorDataCommand.Set),
|
||||
colorData.AsColorDataV2(ColorDataCommand.Set),
|
||||
colorData.AsColorDataV1(ColorDataCommand.Set)
|
||||
};
|
||||
|
||||
DisplayApi.ColorControl(DisplayId, instances);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the HDMI video info-frame current or override information
|
||||
/// </summary>
|
||||
/// <param name="audio">The new information.</param>
|
||||
/// <param name="isOverride">A boolean value indicating if the changes should persist mode-set and OS restart.</param>
|
||||
public void SetHDMIAudioFrameInformation(InfoFrameAudio audio, bool isOverride = false)
|
||||
{
|
||||
var infoFrame = new InfoFrameData(
|
||||
isOverride ? InfoFrameCommand.SetOverride : InfoFrameCommand.Set,
|
||||
audio
|
||||
);
|
||||
DisplayApi.InfoFrameControl(DisplayId, ref infoFrame);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the HDMI audio info-frame property information
|
||||
/// </summary>
|
||||
/// <param name="property">The new property information.</param>
|
||||
public void SetHDMIAudioFramePropertyInformation(InfoFrameProperty property)
|
||||
{
|
||||
var infoFrame = new InfoFrameData(
|
||||
InfoFrameCommand.SetProperty,
|
||||
InfoFrameDataType.AudioInformation,
|
||||
property
|
||||
);
|
||||
DisplayApi.InfoFrameControl(DisplayId, ref infoFrame);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the HDMI auxiliary video info-frame current or override information
|
||||
/// </summary>
|
||||
/// <param name="video">The new information.</param>
|
||||
/// <param name="isOverride">A boolean value indicating if the changes should persist mode-set and OS restart.</param>
|
||||
public void SetHDMIVideoFrameInformation(InfoFrameVideo video, bool isOverride = false)
|
||||
{
|
||||
var infoFrame = new InfoFrameData(
|
||||
isOverride ? InfoFrameCommand.SetOverride : InfoFrameCommand.Set,
|
||||
video
|
||||
);
|
||||
DisplayApi.InfoFrameControl(DisplayId, ref infoFrame);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the HDMI auxiliary video info-frame property information
|
||||
/// </summary>
|
||||
/// <param name="property">The new property information.</param>
|
||||
public void SetHDMIVideoFramePropertyInformation(InfoFrameProperty property)
|
||||
{
|
||||
var infoFrame = new InfoFrameData(
|
||||
InfoFrameCommand.SetProperty,
|
||||
InfoFrameDataType.AuxiliaryVideoInformation,
|
||||
property
|
||||
);
|
||||
DisplayApi.InfoFrameControl(DisplayId, ref infoFrame);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Changes the display HDR color data configuration
|
||||
/// </summary>
|
||||
/// <param name="colorData">The color data to be set.</param>
|
||||
public void SetHDRColorData(HDRColorData colorData)
|
||||
{
|
||||
var instances = new IHDRColorData[]
|
||||
{
|
||||
colorData.AsHDRColorDataV2(ColorDataHDRCommand.Set),
|
||||
colorData.AsHDRColorDataV1(ColorDataHDRCommand.Set)
|
||||
};
|
||||
|
||||
DisplayApi.HDRColorControl(DisplayId, instances);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Applies a custom resolution into trial.
|
||||
/// </summary>
|
||||
/// <param name="customResolution">The custom resolution to apply.</param>
|
||||
/// <param name="hardwareModeSetOnly">
|
||||
/// A boolean value indicating that a hardware mode-set without OS update should be
|
||||
/// performed.
|
||||
/// </param>
|
||||
public void TrialCustomResolution(CustomResolution customResolution, bool hardwareModeSetOnly = true)
|
||||
{
|
||||
TrialCustomResolution(customResolution, new[] {DisplayId}, hardwareModeSetOnly);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,183 +0,0 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
|
||||
namespace NvAPIWrapper.Display
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a texture of float values
|
||||
/// </summary>
|
||||
public class FloatTexture : IEquatable<FloatTexture>
|
||||
{
|
||||
/// <summary>
|
||||
/// Underlying float array containing the values of all channels in all pixels
|
||||
/// </summary>
|
||||
protected readonly float[] UnderlyingArray;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of <see cref="FloatTexture" />.
|
||||
/// </summary>
|
||||
/// <param name="width">The texture width.</param>
|
||||
/// <param name="height">The texture height.</param>
|
||||
/// <param name="channels">The number of texture channels.</param>
|
||||
public FloatTexture(int width, int height, int channels) : this(width, height, channels, null)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of <see cref="FloatTexture" />.
|
||||
/// </summary>
|
||||
/// <param name="width">The texture width.</param>
|
||||
/// <param name="height">The texture height.</param>
|
||||
/// <param name="channels">The number of texture channels.</param>
|
||||
/// <param name="array">The underlying array containing all float values.</param>
|
||||
// ReSharper disable once TooManyDependencies
|
||||
protected FloatTexture(int width, int height, int channels, float[] array)
|
||||
{
|
||||
Width = width;
|
||||
Height = height;
|
||||
Channels = channels;
|
||||
UnderlyingArray = array ?? new float[width * height * channels];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the number of texture channels
|
||||
/// </summary>
|
||||
public int Channels { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the texture height in pixel
|
||||
/// </summary>
|
||||
public int Height { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the texture width in pixels
|
||||
/// </summary>
|
||||
public int Width { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool Equals(FloatTexture other)
|
||||
{
|
||||
if (other == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ReferenceEquals(this, other))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (other.UnderlyingArray.Length != UnderlyingArray.Length)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (other.Width != Width || other.Height != Height || other.Channels != Channels)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return !UnderlyingArray.Where((t, i) => Math.Abs(other.UnderlyingArray[i] - t) > 0.0001).Any();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a new instance of FloatTexture from the passed array of float values.
|
||||
/// </summary>
|
||||
/// <param name="width">The texture width.</param>
|
||||
/// <param name="height">The texture height.</param>
|
||||
/// <param name="channels">The texture channels.</param>
|
||||
/// <param name="floats">The array of float values.</param>
|
||||
/// <returns>A new instance of <see cref="FloatTexture" />.</returns>
|
||||
// ReSharper disable once TooManyArguments
|
||||
public static FloatTexture FromFloatArray(int width, int height, int channels, float[] floats)
|
||||
{
|
||||
if (floats.Length != width * height * channels)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(floats));
|
||||
}
|
||||
|
||||
return new FloatTexture(width, height, channels, floats.ToArray());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compares two instance of <see cref="FloatTexture" /> for equality.
|
||||
/// </summary>
|
||||
/// <param name="left">The first instance.</param>
|
||||
/// <param name="right">The second instance.</param>
|
||||
/// <returns><see langword="true" /> if both instances are equal, otherwise <see langword="false" /></returns>
|
||||
public static bool operator ==(FloatTexture left, FloatTexture right)
|
||||
{
|
||||
return Equals(left, right) || left?.Equals(right) == true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compares two instance of <see cref="FloatTexture" /> for in-equality.
|
||||
/// </summary>
|
||||
/// <param name="left">The first instance.</param>
|
||||
/// <param name="right">The second instance.</param>
|
||||
/// <returns><see langword="true" /> if both instances are not equal, otherwise <see langword="false" /></returns>
|
||||
public static bool operator !=(FloatTexture left, FloatTexture right)
|
||||
{
|
||||
return !(left == right);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (obj == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ReferenceEquals(this, obj))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return Equals(obj as FloatTexture);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return UnderlyingArray.GetHashCode();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the values of each channel at a specific location
|
||||
/// </summary>
|
||||
/// <param name="x">The horizontal location.</param>
|
||||
/// <param name="y">The vertical location.</param>
|
||||
/// <returns>An array of float values each representing a channel value.</returns>
|
||||
public float[] GetValues(int x, int y)
|
||||
{
|
||||
return UnderlyingArray.Skip(y * Width + x).Take(Channels).ToArray();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the value of each channel at a specific location
|
||||
/// </summary>
|
||||
/// <param name="x">The horizontal location.</param>
|
||||
/// <param name="y">The vertical location.</param>
|
||||
/// <param name="floats">An array of float values each representing a channel value.</param>
|
||||
public void SetValues(int x, int y, params float[] floats)
|
||||
{
|
||||
var index = y * Width + x;
|
||||
|
||||
for (var i = 0; i < Math.Min(Channels, floats.Length); i++)
|
||||
{
|
||||
UnderlyingArray[index + i] = floats[i];
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns this instance of <see cref="FloatTexture" /> as an array of float values.
|
||||
/// </summary>
|
||||
/// <returns>An array of float values representing this instance of <see cref="FloatTexture" />.</returns>
|
||||
public float[] ToFloatArray()
|
||||
{
|
||||
// Returns a copy of the underlying array
|
||||
return UnderlyingArray.ToArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,157 +0,0 @@
|
||||
using System;
|
||||
using NvAPIWrapper.Native.Display;
|
||||
using NvAPIWrapper.Native.Display.Structures;
|
||||
using NvAPIWrapper.Native.Interfaces.Display;
|
||||
|
||||
namespace NvAPIWrapper.Display
|
||||
{
|
||||
/// <inheritdoc cref="IHDRColorData" />
|
||||
public class HDRColorData : IHDRColorData, IEquatable<HDRColorData>
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates an instance of <see cref="HDRColorData" />.
|
||||
/// </summary>
|
||||
/// <param name="hdrMode">The hdr mode.</param>
|
||||
/// <param name="masteringDisplayData">The display color space configurations.</param>
|
||||
/// <param name="colorFormat">The color data color format.</param>
|
||||
/// <param name="dynamicRange">The color data dynamic range.</param>
|
||||
/// <param name="colorDepth">The color data color depth.</param>
|
||||
public HDRColorData(
|
||||
ColorDataHDRMode hdrMode,
|
||||
MasteringDisplayColorData masteringDisplayData,
|
||||
ColorDataFormat? colorFormat = null,
|
||||
ColorDataDynamicRange? dynamicRange = null,
|
||||
ColorDataDepth? colorDepth = null
|
||||
)
|
||||
{
|
||||
HDRMode = hdrMode;
|
||||
MasteringDisplayData = masteringDisplayData;
|
||||
ColorFormat = colorFormat;
|
||||
DynamicRange = dynamicRange;
|
||||
ColorDepth = colorDepth;
|
||||
}
|
||||
|
||||
internal HDRColorData(IHDRColorData colorData)
|
||||
{
|
||||
HDRMode = colorData.HDRMode;
|
||||
MasteringDisplayData = colorData.MasteringDisplayData;
|
||||
ColorDepth = colorData.ColorDepth;
|
||||
ColorFormat = colorData.ColorFormat;
|
||||
DynamicRange = colorData.DynamicRange;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool Equals(HDRColorData other)
|
||||
{
|
||||
if (ReferenceEquals(null, other))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ReferenceEquals(this, other))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return ColorDepth == other.ColorDepth &&
|
||||
ColorFormat == other.ColorFormat &&
|
||||
DynamicRange == other.DynamicRange &&
|
||||
HDRMode == other.HDRMode &&
|
||||
MasteringDisplayData.Equals(other.MasteringDisplayData);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public ColorDataDepth? ColorDepth { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public ColorDataFormat? ColorFormat { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public ColorDataDynamicRange? DynamicRange { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public ColorDataHDRMode HDRMode { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public MasteringDisplayColorData MasteringDisplayData { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Compares two instances of <see cref="HDRColorData" /> for equality.
|
||||
/// </summary>
|
||||
/// <param name="left">The first instance.</param>
|
||||
/// <param name="right">The second instance.</param>
|
||||
/// <returns>true if two instances are equal; otherwise false.</returns>
|
||||
public static bool operator ==(HDRColorData left, HDRColorData right)
|
||||
{
|
||||
return left?.Equals(right) == true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compares two instances of <see cref="HDRColorData" /> for inequality.
|
||||
/// </summary>
|
||||
/// <param name="left">The first instance.</param>
|
||||
/// <param name="right">The second instance.</param>
|
||||
/// <returns>true if two instances are not equal; otherwise false.</returns>
|
||||
public static bool operator !=(HDRColorData left, HDRColorData right)
|
||||
{
|
||||
return !(left == right);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (ReferenceEquals(null, obj))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ReferenceEquals(this, obj))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (obj.GetType() != GetType())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return Equals((HDRColorData) obj);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override int GetHashCode()
|
||||
{
|
||||
unchecked
|
||||
{
|
||||
var hashCode = ColorDepth.GetHashCode();
|
||||
hashCode = (hashCode * 397) ^ ColorFormat.GetHashCode();
|
||||
hashCode = (hashCode * 397) ^ DynamicRange.GetHashCode();
|
||||
hashCode = (hashCode * 397) ^ (int) HDRMode;
|
||||
hashCode = (hashCode * 397) ^ MasteringDisplayData.GetHashCode();
|
||||
|
||||
return hashCode;
|
||||
}
|
||||
}
|
||||
|
||||
internal HDRColorDataV1 AsHDRColorDataV1(ColorDataHDRCommand command)
|
||||
{
|
||||
return new HDRColorDataV1(
|
||||
command,
|
||||
HDRMode,
|
||||
MasteringDisplayData
|
||||
);
|
||||
}
|
||||
|
||||
internal HDRColorDataV2 AsHDRColorDataV2(ColorDataHDRCommand command)
|
||||
{
|
||||
return new HDRColorDataV2(
|
||||
command,
|
||||
HDRMode,
|
||||
MasteringDisplayData,
|
||||
ColorFormat ?? ColorDataFormat.Auto,
|
||||
DynamicRange ?? ColorDataDynamicRange.Auto,
|
||||
ColorDepth ?? ColorDataDepth.Default
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,97 +0,0 @@
|
||||
using NvAPIWrapper.Native;
|
||||
using NvAPIWrapper.Native.Display.Structures;
|
||||
using NvAPIWrapper.Native.GPU;
|
||||
|
||||
namespace NvAPIWrapper.Display
|
||||
{
|
||||
/// <summary>
|
||||
/// This class contains and provides a way to modify the HUE angle
|
||||
/// </summary>
|
||||
public class HUEInformation
|
||||
{
|
||||
private readonly DisplayHandle _displayHandle = DisplayHandle.DefaultHandle;
|
||||
private readonly OutputId _outputId = OutputId.Invalid;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the class using a DisplayHandle
|
||||
/// </summary>
|
||||
/// <param name="displayHandle">The handle of the display.</param>
|
||||
public HUEInformation(DisplayHandle displayHandle)
|
||||
{
|
||||
_displayHandle = displayHandle;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of this class using a OutputId
|
||||
/// </summary>
|
||||
/// <param name="outputId">The output identification of a display or an output</param>
|
||||
public HUEInformation(OutputId outputId)
|
||||
{
|
||||
_outputId = outputId;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the current HUE offset angle [0-359]
|
||||
/// </summary>
|
||||
public int CurrentAngle
|
||||
{
|
||||
get
|
||||
{
|
||||
PrivateDisplayHUEInfo? hueInfo = null;
|
||||
|
||||
if (_displayHandle != DisplayHandle.DefaultHandle)
|
||||
{
|
||||
hueInfo = DisplayApi.GetHUEInfo(_displayHandle);
|
||||
}
|
||||
else if (_outputId != OutputId.Invalid)
|
||||
{
|
||||
hueInfo = DisplayApi.GetHUEInfo(_outputId);
|
||||
}
|
||||
|
||||
return hueInfo?.CurrentAngle ?? 0;
|
||||
}
|
||||
set
|
||||
{
|
||||
value %= 360;
|
||||
|
||||
if (_displayHandle != DisplayHandle.DefaultHandle)
|
||||
{
|
||||
DisplayApi.SetHUEAngle(_displayHandle, value);
|
||||
}
|
||||
else if (_outputId != OutputId.Invalid)
|
||||
{
|
||||
DisplayApi.SetHUEAngle(_outputId, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the default HUE offset angle [0-359]
|
||||
/// </summary>
|
||||
public int DefaultAngle
|
||||
{
|
||||
get
|
||||
{
|
||||
PrivateDisplayHUEInfo? hueInfo = null;
|
||||
|
||||
if (_displayHandle != DisplayHandle.DefaultHandle)
|
||||
{
|
||||
hueInfo = DisplayApi.GetHUEInfo(_displayHandle);
|
||||
}
|
||||
else if (_outputId != OutputId.Invalid)
|
||||
{
|
||||
hueInfo = DisplayApi.GetHUEInfo(_outputId);
|
||||
}
|
||||
|
||||
return hueInfo?.DefaultAngle ?? 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{CurrentAngle:D}º [{DefaultAngle:D}º]";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,70 +0,0 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
|
||||
namespace NvAPIWrapper.Display
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a texture of intensity values
|
||||
/// </summary>
|
||||
public class IntensityTexture : FloatTexture
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates a new instance of <see cref="IntensityTexture" />.
|
||||
/// </summary>
|
||||
/// <param name="width">The texture width.</param>
|
||||
/// <param name="height">The texture height.</param>
|
||||
public IntensityTexture(int width, int height) : base(width, height, 3)
|
||||
{
|
||||
}
|
||||
|
||||
private IntensityTexture(int width, int height, float[] floats) : base(width, height, 3, floats)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a new instance of FloatTexture from the passed array of float values.
|
||||
/// </summary>
|
||||
/// <param name="width">The texture width.</param>
|
||||
/// <param name="height">The texture height.</param>
|
||||
/// <param name="floats">The array of float values.</param>
|
||||
/// <returns>A new instance of <see cref="FloatTexture" />.</returns>
|
||||
// ReSharper disable once TooManyArguments
|
||||
public static IntensityTexture FromFloatArray(int width, int height, float[] floats)
|
||||
{
|
||||
if (floats.Length != width * height * 3)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(floats));
|
||||
}
|
||||
|
||||
return new IntensityTexture(width, height, floats.ToArray());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the value of intensity pixel at a specific location.
|
||||
/// </summary>
|
||||
/// <param name="x">The horizontal location.</param>
|
||||
/// <param name="y">The vertical location.</param>
|
||||
/// <returns>An instance of <see cref="IntensityTexturePixel" />.</returns>
|
||||
public IntensityTexturePixel GetPixel(int x, int y)
|
||||
{
|
||||
return IntensityTexturePixel.FromFloatArray(UnderlyingArray, y * Width + x);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the value of intensity pixel at a specific location
|
||||
/// </summary>
|
||||
/// <param name="x">The horizontal location.</param>
|
||||
/// <param name="y">The vertical location.</param>
|
||||
/// <param name="pixel">An instance of <see cref="IntensityTexturePixel" />.</param>
|
||||
public void SetPixel(int x, int y, IntensityTexturePixel pixel)
|
||||
{
|
||||
var index = y * Width + x;
|
||||
var floats = pixel.ToFloatArray();
|
||||
|
||||
for (var i = 0; i < Math.Min(Channels, floats.Length); i++)
|
||||
{
|
||||
UnderlyingArray[index + i] = floats[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,117 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace NvAPIWrapper.Display
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a RGB intensity texture pixel
|
||||
/// </summary>
|
||||
public class IntensityTexturePixel : IEquatable<IntensityTexturePixel>
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates a new instance of <see cref="IntensityTexturePixel" />.
|
||||
/// </summary>
|
||||
/// <param name="redIntensity">The intensity of the red light (0-1)</param>
|
||||
/// <param name="greenIntensity">The intensity of the green light (0-1)</param>
|
||||
/// <param name="blueIntensity">The intensity of the blue light (0-1)</param>
|
||||
public IntensityTexturePixel(float redIntensity, float greenIntensity, float blueIntensity)
|
||||
{
|
||||
RedIntensity = Math.Max(Math.Min(redIntensity, 1), 0);
|
||||
GreenIntensity = Math.Max(Math.Min(greenIntensity, 1), 0);
|
||||
BlueIntensity = Math.Max(Math.Min(blueIntensity, 1), 0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the intensity of the blue light (0-1)
|
||||
/// </summary>
|
||||
public float BlueIntensity { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the intensity of the green light (0-1)
|
||||
/// </summary>
|
||||
public float GreenIntensity { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the intensity of the red light (0-1)
|
||||
/// </summary>
|
||||
public float RedIntensity { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool Equals(IntensityTexturePixel other)
|
||||
{
|
||||
if (other == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ReferenceEquals(this, other))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return Math.Abs(RedIntensity - other.RedIntensity) < 0.0001 &&
|
||||
Math.Abs(GreenIntensity - other.GreenIntensity) < 0.0001 &&
|
||||
Math.Abs(BlueIntensity - other.BlueIntensity) < 0.0001;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compares two instance of <see cref="IntensityTexturePixel" /> for equality.
|
||||
/// </summary>
|
||||
/// <param name="left">The first instance.</param>
|
||||
/// <param name="right">The second instance.</param>
|
||||
/// <returns><see langword="true" /> if both instances are equal, otherwise <see langword="false" /></returns>
|
||||
public static bool operator ==(IntensityTexturePixel left, IntensityTexturePixel right)
|
||||
{
|
||||
return Equals(left, right) || left?.Equals(right) == true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compares two instance of <see cref="IntensityTexturePixel" /> for in-equality.
|
||||
/// </summary>
|
||||
/// <param name="left">The first instance.</param>
|
||||
/// <param name="right">The second instance.</param>
|
||||
/// <returns><see langword="true" /> if both instances are not equal, otherwise <see langword="false" /></returns>
|
||||
public static bool operator !=(IntensityTexturePixel left, IntensityTexturePixel right)
|
||||
{
|
||||
return !(left == right);
|
||||
}
|
||||
|
||||
internal static IntensityTexturePixel FromFloatArray(float[] floats, int index)
|
||||
{
|
||||
return new IntensityTexturePixel(floats[index], floats[index + 1], floats[index + 2]);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (obj == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ReferenceEquals(this, obj))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return Equals(obj as IntensityTexturePixel);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override int GetHashCode()
|
||||
{
|
||||
unchecked
|
||||
{
|
||||
var hashCode = RedIntensity.GetHashCode();
|
||||
hashCode = (hashCode * 397) ^ GreenIntensity.GetHashCode();
|
||||
hashCode = (hashCode * 397) ^ BlueIntensity.GetHashCode();
|
||||
|
||||
return hashCode;
|
||||
}
|
||||
}
|
||||
|
||||
internal float[] ToFloatArray()
|
||||
{
|
||||
return new[] {RedIntensity, GreenIntensity, BlueIntensity};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,288 +0,0 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using NvAPIWrapper.Native;
|
||||
using NvAPIWrapper.Native.Display;
|
||||
using NvAPIWrapper.Native.Display.Structures;
|
||||
using NvAPIWrapper.Native.Exceptions;
|
||||
using NvAPIWrapper.Native.General;
|
||||
using NvAPIWrapper.Native.Helpers;
|
||||
using NvAPIWrapper.Native.Interfaces.Display;
|
||||
|
||||
namespace NvAPIWrapper.Display
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a configuration path
|
||||
/// </summary>
|
||||
public class PathInfo : IEquatable<PathInfo>
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates a new PathInfo
|
||||
/// </summary>
|
||||
/// <param name="resolution">Display resolution</param>
|
||||
/// <param name="colorFormat">Display color format</param>
|
||||
/// <param name="targetInfos">Target configuration informations</param>
|
||||
public PathInfo(Resolution resolution, ColorFormat colorFormat, PathTargetInfo[] targetInfos)
|
||||
{
|
||||
Resolution = resolution;
|
||||
ColorFormat = colorFormat;
|
||||
TargetsInfo = targetInfos;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new PathInfo
|
||||
/// </summary>
|
||||
/// <param name="info">IPathInfo implamented object</param>
|
||||
public PathInfo(IPathInfo info)
|
||||
{
|
||||
SourceId = info.SourceId;
|
||||
Resolution = info.SourceModeInfo.Resolution;
|
||||
ColorFormat = info.SourceModeInfo.ColorFormat;
|
||||
Position = info.SourceModeInfo.Position;
|
||||
SpanningOrientation = info.SourceModeInfo.SpanningOrientation;
|
||||
IsGDIPrimary = info.SourceModeInfo.IsGDIPrimary;
|
||||
IsSLIFocus = info.SourceModeInfo.IsSLIFocus;
|
||||
TargetsInfo =
|
||||
info.TargetsInfo.Select(targetInfo => new PathTargetInfo(targetInfo)).ToArray();
|
||||
|
||||
if (info is PathInfoV2)
|
||||
{
|
||||
OSAdapterLUID = ((PathInfoV2) info).OSAdapterLUID;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the display color format
|
||||
/// </summary>
|
||||
public ColorFormat ColorFormat { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a boolean value indicating if the this is the primary GDI display
|
||||
/// </summary>
|
||||
public bool IsGDIPrimary { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a boolean value indicating if the this is the SLI focus display
|
||||
/// </summary>
|
||||
public bool IsSLIFocus { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets OS Adapter of LUID for Non-NVIDIA adapters
|
||||
/// </summary>
|
||||
public LUID? OSAdapterLUID { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the display position
|
||||
/// </summary>
|
||||
public Position Position { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the display resolution
|
||||
/// </summary>
|
||||
public Resolution Resolution { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Windows CCD display source identification. This can be optionally set.
|
||||
/// </summary>
|
||||
public uint SourceId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the display spanning orientation, valid for XP only
|
||||
/// </summary>
|
||||
public SpanningOrientation SpanningOrientation { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets information about path targets
|
||||
/// </summary>
|
||||
public PathTargetInfo[] TargetsInfo { get; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Checks for equality with a PathInfo instance
|
||||
/// </summary>
|
||||
/// <param name="other">The PathInfo object to check with</param>
|
||||
/// <returns>true if both objects are equal, otherwise false</returns>
|
||||
public bool Equals(PathInfo other)
|
||||
{
|
||||
if (ReferenceEquals(null, other))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ReferenceEquals(this, other))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return Resolution.Equals(other.Resolution) &&
|
||||
ColorFormat == other.ColorFormat &&
|
||||
Position.Equals(other.Position) &&
|
||||
SpanningOrientation == other.SpanningOrientation &&
|
||||
IsGDIPrimary == other.IsGDIPrimary &&
|
||||
IsSLIFocus == other.IsSLIFocus &&
|
||||
TargetsInfo.SequenceEqual(other.TargetsInfo);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Creates and fills a PathInfo object
|
||||
/// </summary>
|
||||
/// <returns>The newly created PathInfo object</returns>
|
||||
public static PathInfo[] GetDisplaysConfig()
|
||||
{
|
||||
var configs = DisplayApi.GetDisplayConfig();
|
||||
var logicalDisplays = configs.Select(info => new PathInfo(info)).ToArray();
|
||||
configs.DisposeAll();
|
||||
|
||||
return logicalDisplays;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks for equality between two objects of same type
|
||||
/// </summary>
|
||||
/// <param name="left">The first object</param>
|
||||
/// <param name="right">The second object</param>
|
||||
/// <returns>true, if both objects are equal, otherwise false</returns>
|
||||
public static bool operator ==(PathInfo left, PathInfo right)
|
||||
{
|
||||
return right?.Equals(left) ?? ReferenceEquals(left, null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks for inequality between two objects of same type
|
||||
/// </summary>
|
||||
/// <param name="left">The first object</param>
|
||||
/// <param name="right">The second object</param>
|
||||
/// <returns>true, if both objects are not equal, otherwise false</returns>
|
||||
public static bool operator !=(PathInfo left, PathInfo right)
|
||||
{
|
||||
return !(left == right);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Applies one or more path information configurations
|
||||
/// </summary>
|
||||
/// <param name="pathInfos">An array of path information configuration</param>
|
||||
/// <param name="flags">DisplayConfigFlags flags</param>
|
||||
public static void SetDisplaysConfig(PathInfo[] pathInfos, DisplayConfigFlags flags)
|
||||
{
|
||||
try
|
||||
{
|
||||
var configsV2 = pathInfos.Select(config => config.GetPathInfoV2()).Cast<IPathInfo>().ToArray();
|
||||
DisplayApi.SetDisplayConfig(configsV2, flags);
|
||||
configsV2.DisposeAll();
|
||||
}
|
||||
catch (NVIDIAApiException ex)
|
||||
{
|
||||
if (ex.Status != Status.IncompatibleStructureVersion)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
catch (NVIDIANotSupportedException)
|
||||
{
|
||||
// ignore
|
||||
}
|
||||
|
||||
var configsV1 = pathInfos.Select(config => config.GetPathInfoV1()).Cast<IPathInfo>().ToArray();
|
||||
DisplayApi.SetDisplayConfig(configsV1, flags);
|
||||
configsV1.DisposeAll();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (ReferenceEquals(null, obj))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ReferenceEquals(this, obj))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (obj.GetType() != GetType())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return Equals((PathInfo) obj);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override int GetHashCode()
|
||||
{
|
||||
unchecked
|
||||
{
|
||||
var hashCode = Resolution.GetHashCode();
|
||||
hashCode = (hashCode * 397) ^ (int) ColorFormat;
|
||||
hashCode = (hashCode * 397) ^ Position.GetHashCode();
|
||||
hashCode = (hashCode * 397) ^ (int) SpanningOrientation;
|
||||
hashCode = (hashCode * 397) ^ IsGDIPrimary.GetHashCode();
|
||||
hashCode = (hashCode * 397) ^ IsSLIFocus.GetHashCode();
|
||||
hashCode = (hashCode * 397) ^ (TargetsInfo?.GetHashCode() ?? 0);
|
||||
|
||||
return hashCode;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{Resolution} @ {Position} [{TargetsInfo.Length}]";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates and fills a GetPathInfoV1 object
|
||||
/// </summary>
|
||||
/// <returns>The newly created GetPathInfoV1 object</returns>
|
||||
public PathInfoV1 GetPathInfoV1()
|
||||
{
|
||||
var sourceModeInfo = GetSourceModeInfo();
|
||||
var pathTargetInfoV1 = GetPathTargetInfoV1Array();
|
||||
|
||||
return new PathInfoV1(pathTargetInfoV1, sourceModeInfo, SourceId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates and fills a GetPathInfoV2 object
|
||||
/// </summary>
|
||||
/// <returns>The newly created GetPathInfoV2 object</returns>
|
||||
public PathInfoV2 GetPathInfoV2()
|
||||
{
|
||||
var sourceModeInfo = GetSourceModeInfo();
|
||||
var pathTargetInfoV2 = GetPathTargetInfoV2Array();
|
||||
|
||||
return new PathInfoV2(pathTargetInfoV2, sourceModeInfo, SourceId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates and fills an array of GetPathTargetInfoV1 object
|
||||
/// </summary>
|
||||
/// <returns>The newly created array of GetPathTargetInfoV1 objects</returns>
|
||||
public PathTargetInfoV1[] GetPathTargetInfoV1Array()
|
||||
{
|
||||
return TargetsInfo.Select(config => config.GetPathTargetInfoV1()).ToArray();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates and fills an array of GetPathTargetInfoV2 object
|
||||
/// </summary>
|
||||
/// <returns>The newly created array of GetPathTargetInfoV2 objects</returns>
|
||||
public PathTargetInfoV2[] GetPathTargetInfoV2Array()
|
||||
{
|
||||
return TargetsInfo.Select(config => config.GetPathTargetInfoV2()).ToArray();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates and fills a SourceModeInfo object
|
||||
/// </summary>
|
||||
/// <returns>The newly created SourceModeInfo object</returns>
|
||||
public SourceModeInfo GetSourceModeInfo()
|
||||
{
|
||||
return new SourceModeInfo(Resolution, ColorFormat, Position, SpanningOrientation, IsGDIPrimary, IsSLIFocus);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,304 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using NvAPIWrapper.Native.Display;
|
||||
using NvAPIWrapper.Native.Display.Structures;
|
||||
using NvAPIWrapper.Native.Exceptions;
|
||||
using NvAPIWrapper.Native.GPU;
|
||||
using NvAPIWrapper.Native.Interfaces.Display;
|
||||
|
||||
namespace NvAPIWrapper.Display
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a display configuration on a path
|
||||
/// </summary>
|
||||
public class PathTargetInfo : IEquatable<PathTargetInfo>
|
||||
{
|
||||
private TimingOverride _timingOverride;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new PathTargetInfo
|
||||
/// </summary>
|
||||
/// <param name="info">IPathTargetInfo implamented object</param>
|
||||
public PathTargetInfo(IPathTargetInfo info)
|
||||
{
|
||||
DisplayDevice = new DisplayDevice(info.DisplayId);
|
||||
|
||||
if (info.Details.HasValue)
|
||||
{
|
||||
Rotation = info.Details.Value.Rotation;
|
||||
Scaling = info.Details.Value.Scaling;
|
||||
TVConnectorType = info.Details.Value.ConnectorType;
|
||||
TVFormat = info.Details.Value.TVFormat;
|
||||
RefreshRateInMillihertz = info.Details.Value.RefreshRateInMillihertz;
|
||||
TimingOverride = info.Details.Value.TimingOverride;
|
||||
IsInterlaced = info.Details.Value.IsInterlaced;
|
||||
IsClonePrimary = info.Details.Value.IsClonePrimary;
|
||||
IsClonePanAndScanTarget = info.Details.Value.IsClonePanAndScanTarget;
|
||||
DisableVirtualModeSupport = info.Details.Value.DisableVirtualModeSupport;
|
||||
IsPreferredUnscaledTarget = info.Details.Value.IsPreferredUnscaledTarget;
|
||||
}
|
||||
|
||||
if (info is PathTargetInfoV2)
|
||||
{
|
||||
WindowsCCDTargetId = ((PathTargetInfoV2) info).WindowsCCDTargetId;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new PathTargetInfo
|
||||
/// </summary>
|
||||
/// <param name="device">DisplayDevice object</param>
|
||||
public PathTargetInfo(DisplayDevice device)
|
||||
{
|
||||
DisplayDevice = device;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the virtual mode support
|
||||
/// </summary>
|
||||
public bool DisableVirtualModeSupport { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets corresponding DisplayDevice
|
||||
/// </summary>
|
||||
public DisplayDevice DisplayDevice { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the pan and scan is availability. Valid only when the target is part of clone
|
||||
/// topology.
|
||||
/// </summary>
|
||||
public bool IsClonePanAndScanTarget { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the primary display in clone configuration. This is *NOT* GDI Primary.
|
||||
/// Only one target can be primary per source. If no primary is specified, the first target will automatically be
|
||||
/// primary.
|
||||
/// </summary>
|
||||
public bool IsClonePrimary { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the interlaced mode flag, ignored if refreshRate == 0
|
||||
/// </summary>
|
||||
public bool IsInterlaced { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the preferred unscaled mode of target
|
||||
/// </summary>
|
||||
public bool IsPreferredUnscaledTarget { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets and sets the non-interlaced Refresh Rate of the mode, multiplied by 1000, 0 = ignored
|
||||
/// This is the value which driver reports to the OS.
|
||||
/// </summary>
|
||||
public uint RefreshRateInMillihertz { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets and sets the rotation setting
|
||||
/// </summary>
|
||||
public Rotate Rotation { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets and sets the scaling setting
|
||||
/// </summary>
|
||||
public Scaling Scaling { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets and sets the custom timing of display
|
||||
/// Ignored if TimingOverride == TimingOverride.Current
|
||||
/// </summary>
|
||||
public TimingOverride TimingOverride
|
||||
{
|
||||
get => _timingOverride;
|
||||
set
|
||||
{
|
||||
if (value == TimingOverride.Custom)
|
||||
{
|
||||
throw new NVIDIANotSupportedException("Custom timing is not supported yet.");
|
||||
}
|
||||
|
||||
_timingOverride = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets and sets the connector type. For TV only, ignored if TVFormat == TVFormat.None.
|
||||
/// </summary>
|
||||
public ConnectorType TVConnectorType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets and sets the TV format. For TV only, otherwise set to TVFormat.None
|
||||
/// </summary>
|
||||
public TVFormat TVFormat { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the Windows CCD target ID. Must be present only for non-NVIDIA adapter, for NVIDIA adapter this parameter is
|
||||
/// ignored.
|
||||
/// </summary>
|
||||
public uint WindowsCCDTargetId { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Checks for equality with a PathTargetInfo instance
|
||||
/// </summary>
|
||||
/// <param name="other">The PathTargetInfo object to check with</param>
|
||||
/// <returns>true if both objects are equal, otherwise false</returns>
|
||||
public bool Equals(PathTargetInfo other)
|
||||
{
|
||||
if (ReferenceEquals(null, other))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ReferenceEquals(this, other))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return _timingOverride == other._timingOverride &&
|
||||
Rotation == other.Rotation &&
|
||||
Scaling == other.Scaling &&
|
||||
RefreshRateInMillihertz == other.RefreshRateInMillihertz &&
|
||||
(TVFormat == TVFormat.None || TVConnectorType == other.TVConnectorType) &&
|
||||
TVFormat == other.TVFormat &&
|
||||
DisplayDevice.Equals(other.DisplayDevice) &&
|
||||
IsInterlaced == other.IsInterlaced &&
|
||||
IsClonePrimary == other.IsClonePrimary &&
|
||||
IsClonePanAndScanTarget == other.IsClonePanAndScanTarget &&
|
||||
DisableVirtualModeSupport == other.DisableVirtualModeSupport &&
|
||||
IsPreferredUnscaledTarget == other.IsPreferredUnscaledTarget;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks for equality between two objects of same type
|
||||
/// </summary>
|
||||
/// <param name="left">The first object</param>
|
||||
/// <param name="right">The second object</param>
|
||||
/// <returns>true, if both objects are equal, otherwise false</returns>
|
||||
public static bool operator ==(PathTargetInfo left, PathTargetInfo right)
|
||||
{
|
||||
return right?.Equals(left) ?? ReferenceEquals(left, null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks for inequality between two objects of same type
|
||||
/// </summary>
|
||||
/// <param name="left">The first object</param>
|
||||
/// <param name="right">The second object</param>
|
||||
/// <returns>true, if both objects are not equal, otherwise false</returns>
|
||||
public static bool operator !=(PathTargetInfo left, PathTargetInfo right)
|
||||
{
|
||||
return !(left == right);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (ReferenceEquals(null, obj))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ReferenceEquals(this, obj))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (obj.GetType() != GetType())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return Equals((PathTargetInfo) obj);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override int GetHashCode()
|
||||
{
|
||||
unchecked
|
||||
{
|
||||
var hashCode = (int) _timingOverride;
|
||||
hashCode = (hashCode * 397) ^ (int) Rotation;
|
||||
hashCode = (hashCode * 397) ^ (int) Scaling;
|
||||
hashCode = (hashCode * 397) ^ (int) RefreshRateInMillihertz;
|
||||
hashCode = (hashCode * 397) ^ (int) TVFormat;
|
||||
hashCode = (hashCode * 397) ^ (TVFormat != TVFormat.None ? (int) TVConnectorType : 0);
|
||||
hashCode = (hashCode * 397) ^ (DisplayDevice?.GetHashCode() ?? 0);
|
||||
hashCode = (hashCode * 397) ^ IsInterlaced.GetHashCode();
|
||||
hashCode = (hashCode * 397) ^ IsClonePrimary.GetHashCode();
|
||||
hashCode = (hashCode * 397) ^ IsClonePanAndScanTarget.GetHashCode();
|
||||
hashCode = (hashCode * 397) ^ DisableVirtualModeSupport.GetHashCode();
|
||||
hashCode = (hashCode * 397) ^ IsPreferredUnscaledTarget.GetHashCode();
|
||||
|
||||
return hashCode;
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string ToString()
|
||||
{
|
||||
var strs = new List<string>
|
||||
{
|
||||
DisplayDevice.ToString()
|
||||
};
|
||||
|
||||
if (RefreshRateInMillihertz > 0)
|
||||
{
|
||||
strs.Add($"@ {RefreshRateInMillihertz / 1000}hz");
|
||||
}
|
||||
|
||||
if (TVFormat != TVFormat.None)
|
||||
{
|
||||
strs.Add($"- TV {TVFormat}");
|
||||
}
|
||||
|
||||
strs.Add(IsInterlaced ? "Interlaced" : "Progressive");
|
||||
|
||||
if (Rotation != Rotate.Degree0)
|
||||
{
|
||||
strs.Add($"- Rotation: {Rotation}");
|
||||
}
|
||||
|
||||
return string.Join(" ", strs);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Creates and fills a PathAdvancedTargetInfo object
|
||||
/// </summary>
|
||||
/// <returns>The newly created PathAdvancedTargetInfo object</returns>
|
||||
public PathAdvancedTargetInfo GetPathAdvancedTargetInfo()
|
||||
{
|
||||
if (TVFormat == TVFormat.None)
|
||||
{
|
||||
return new PathAdvancedTargetInfo(Rotation, Scaling, RefreshRateInMillihertz, TimingOverride,
|
||||
IsInterlaced, IsClonePrimary, IsClonePanAndScanTarget, DisableVirtualModeSupport,
|
||||
IsPreferredUnscaledTarget);
|
||||
}
|
||||
|
||||
return new PathAdvancedTargetInfo(Rotation, Scaling, TVFormat, TVConnectorType, RefreshRateInMillihertz,
|
||||
TimingOverride, IsInterlaced, IsClonePrimary, IsClonePanAndScanTarget, DisableVirtualModeSupport,
|
||||
IsPreferredUnscaledTarget);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates and fills a PathTargetInfoV1 object
|
||||
/// </summary>
|
||||
/// <returns>The newly created PathTargetInfoV1 object</returns>
|
||||
public PathTargetInfoV1 GetPathTargetInfoV1()
|
||||
{
|
||||
var pathAdvancedTargetInfo = GetPathAdvancedTargetInfo();
|
||||
|
||||
return new PathTargetInfoV1(DisplayDevice.DisplayId, pathAdvancedTargetInfo);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates and fills a PathTargetInfoV2 object
|
||||
/// </summary>
|
||||
/// <returns>The newly created PathTargetInfoV2 object</returns>
|
||||
public PathTargetInfoV2 GetPathTargetInfoV2()
|
||||
{
|
||||
var pathAdvancedTargetInfo = GetPathAdvancedTargetInfo();
|
||||
|
||||
return new PathTargetInfoV2(DisplayDevice.DisplayId, WindowsCCDTargetId, pathAdvancedTargetInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,218 +0,0 @@
|
||||
using System.Linq;
|
||||
using NvAPIWrapper.Native;
|
||||
using NvAPIWrapper.Native.Display;
|
||||
using NvAPIWrapper.Native.Display.Structures;
|
||||
using NvAPIWrapper.Native.General.Structures;
|
||||
using Rectangle = NvAPIWrapper.Native.General.Structures.Rectangle;
|
||||
|
||||
namespace NvAPIWrapper.Display
|
||||
{
|
||||
/// <summary>
|
||||
/// Contains information regarding the scan-out buffer settings of a display device
|
||||
/// </summary>
|
||||
public class ScanOutInformation
|
||||
{
|
||||
internal ScanOutInformation(DisplayDevice displayDevice)
|
||||
{
|
||||
DisplayDevice = displayDevice;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the clone importance assigned to the target if the target is a cloned view of the SourceDesktopRectangle
|
||||
/// (0:primary,1 secondary,...).
|
||||
/// </summary>
|
||||
public uint CloneImportance
|
||||
{
|
||||
get => DisplayApi.GetScanOutConfiguration(DisplayDevice.DisplayId).CloneImportance;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the display device that this instance describes
|
||||
/// </summary>
|
||||
public DisplayDevice DisplayDevice { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a boolean value indicating if the display device scan out output is warped
|
||||
/// </summary>
|
||||
public bool IsDisplayWarped
|
||||
{
|
||||
get => DisplayApi.GetScanOutWarpingState(DisplayDevice.DisplayId).IsEnabled;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a boolean value indicating if the display device intensity is modified
|
||||
/// </summary>
|
||||
public bool IsIntensityModified
|
||||
{
|
||||
get => DisplayApi.GetScanOutIntensityState(DisplayDevice.DisplayId).IsEnabled;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the operating system display device rectangle in desktop coordinates displayId is scanning out from.
|
||||
/// </summary>
|
||||
public Rectangle SourceDesktopRectangle
|
||||
{
|
||||
get => DisplayApi.GetScanOutConfiguration(DisplayDevice.DisplayId).SourceDesktopRectangle;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the rotation performed between the SourceViewPortRectangle and the TargetViewPortRectangle.
|
||||
/// </summary>
|
||||
public Rotate SourceToTargetRotation
|
||||
{
|
||||
get => DisplayApi.GetScanOutConfiguration(DisplayDevice.DisplayId).SourceToTargetRotation;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the area inside the SourceDesktopRectangle which is scanned out to the display.
|
||||
/// </summary>
|
||||
public Rectangle SourceViewPortRectangle
|
||||
{
|
||||
get => DisplayApi.GetScanOutConfiguration(DisplayDevice.DisplayId).SourceViewPortRectangle;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the vertical size of the active resolution scanned out to the display.
|
||||
/// </summary>
|
||||
public uint TargetDisplayHeight
|
||||
{
|
||||
get => DisplayApi.GetScanOutConfiguration(DisplayDevice.DisplayId).TargetDisplayHeight;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the horizontal size of the active resolution scanned out to the display.
|
||||
/// </summary>
|
||||
public uint TargetDisplayWidth
|
||||
{
|
||||
get => DisplayApi.GetScanOutConfiguration(DisplayDevice.DisplayId).TargetDisplayWidth;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the area inside the rectangle described by targetDisplayWidth/Height SourceViewPortRectangle is scanned out
|
||||
/// to.
|
||||
/// </summary>
|
||||
public Rectangle TargetViewPortRectangle
|
||||
{
|
||||
get => DisplayApi.GetScanOutConfiguration(DisplayDevice.DisplayId).TargetViewPortRectangle;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Disables the intensity modification on the display device scan-out buffer.
|
||||
/// </summary>
|
||||
/// <param name="isSticky">A boolean value that indicates whether the settings will be kept over a reboot.</param>
|
||||
public void DisableIntensityModifications(out bool isSticky)
|
||||
{
|
||||
DisplayApi.SetScanOutIntensity(DisplayDevice.DisplayId, null, out isSticky);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Disables the warping of display device scan-out buffer.
|
||||
/// </summary>
|
||||
/// <param name="isSticky">A boolean value that indicates whether the settings will be kept over a reboot.</param>
|
||||
public void DisableWarping(out bool isSticky)
|
||||
{
|
||||
var vorticesCount = 0;
|
||||
DisplayApi.SetScanOutWarping(DisplayDevice.DisplayId, null, ref vorticesCount, out isSticky);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Enables the intensity modification on the display device scan-out buffer.
|
||||
/// </summary>
|
||||
/// <param name="intensityTexture">The intensity texture to apply to the scan-out buffer.</param>
|
||||
/// <param name="isSticky">A boolean value that indicates whether the settings will be kept over a reboot.</param>
|
||||
public void EnableIntensityModifications(IntensityTexture intensityTexture, out bool isSticky)
|
||||
{
|
||||
using (
|
||||
var intensity = new ScanOutIntensityV1(
|
||||
(uint) intensityTexture.Width,
|
||||
(uint) intensityTexture.Height,
|
||||
intensityTexture.ToFloatArray()
|
||||
)
|
||||
)
|
||||
{
|
||||
DisplayApi.SetScanOutIntensity(DisplayDevice.DisplayId, intensity, out isSticky);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Enables the intensity modification on the display device scan-out buffer.
|
||||
/// </summary>
|
||||
/// <param name="intensityTexture">The intensity texture to apply to the scan-out buffer.</param>
|
||||
/// <param name="offsetTexture">The offset texture to apply to the scan-out buffer.</param>
|
||||
/// <param name="isSticky">A boolean value that indicates whether the settings will be kept over a reboot.</param>
|
||||
public void EnableIntensityModifications(
|
||||
IntensityTexture intensityTexture,
|
||||
FloatTexture offsetTexture,
|
||||
out bool isSticky)
|
||||
{
|
||||
using (
|
||||
var intensity = new ScanOutIntensityV2(
|
||||
(uint) intensityTexture.Width,
|
||||
(uint) intensityTexture.Height,
|
||||
intensityTexture.ToFloatArray(),
|
||||
(uint) offsetTexture.Channels,
|
||||
offsetTexture.ToFloatArray()
|
||||
)
|
||||
)
|
||||
{
|
||||
DisplayApi.SetScanOutIntensity(DisplayDevice.DisplayId, intensity, out isSticky);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Enables the warping of display device scan-out buffer
|
||||
/// </summary>
|
||||
/// <param name="warpingVerticeFormat">The type of warping vortexes.</param>
|
||||
/// <param name="vortices">An array of warping vortexes.</param>
|
||||
/// <param name="textureRectangle">The rectangle in desktop coordinates describing the source area for the warping.</param>
|
||||
/// <param name="isSticky">A boolean value that indicates whether the settings will be kept over a reboot.</param>
|
||||
// ReSharper disable once TooManyArguments
|
||||
public void EnableWarping(
|
||||
WarpingVerticeFormat warpingVerticeFormat,
|
||||
XYUVRQVortex[] vortices,
|
||||
Rectangle textureRectangle,
|
||||
out bool isSticky)
|
||||
{
|
||||
using (
|
||||
var warping = new ScanOutWarpingV1(
|
||||
warpingVerticeFormat,
|
||||
vortices.SelectMany(vortex => vortex.AsFloatArray()).ToArray(),
|
||||
textureRectangle
|
||||
)
|
||||
)
|
||||
{
|
||||
var vorticesCount = vortices.Length;
|
||||
DisplayApi.SetScanOutWarping(DisplayDevice.DisplayId, warping, ref vorticesCount, out isSticky);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Queries the current state of one of the various scan-out composition parameters.
|
||||
/// </summary>
|
||||
/// <param name="parameter">The scan-out composition parameter.</param>
|
||||
/// <param name="additionalValue">The additional value included with the parameter value.</param>
|
||||
/// <returns>The scan-out composition parameter value.</returns>
|
||||
public ScanOutCompositionParameterValue GetCompositionParameterValue(
|
||||
ScanOutCompositionParameter parameter,
|
||||
out float additionalValue)
|
||||
{
|
||||
return DisplayApi.GetScanOutCompositionParameter(DisplayDevice.DisplayId, parameter, out additionalValue);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Sets the current state of one of the various scan-out composition parameters.
|
||||
/// </summary>
|
||||
/// <param name="parameter">The scan-out composition parameter.</param>
|
||||
/// <param name="parameterValue">The scan-out composition parameter value.</param>
|
||||
/// <param name="additionalValue">The additional value included with the parameter value.</param>
|
||||
public void SetCompositionParameterValue(
|
||||
ScanOutCompositionParameter parameter,
|
||||
ScanOutCompositionParameterValue parameterValue,
|
||||
float additionalValue)
|
||||
{
|
||||
DisplayApi.SetScanOutCompositionParameter(DisplayDevice.DisplayId, parameter, parameterValue,
|
||||
ref additionalValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,150 +0,0 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using NvAPIWrapper.GPU;
|
||||
using NvAPIWrapper.Native;
|
||||
using NvAPIWrapper.Native.Display.Structures;
|
||||
|
||||
namespace NvAPIWrapper.Display
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents an unattached display
|
||||
/// </summary>
|
||||
public class UnAttachedDisplay : IEquatable<UnAttachedDisplay>
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates a new UnAttachedDisplay
|
||||
/// </summary>
|
||||
/// <param name="handle">Handle of the unattached display device</param>
|
||||
public UnAttachedDisplay(UnAttachedDisplayHandle handle)
|
||||
{
|
||||
Handle = handle;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new UnAttachedDisplay
|
||||
/// </summary>
|
||||
/// <param name="displayName">Name of the unattached display device</param>
|
||||
public UnAttachedDisplay(string displayName)
|
||||
{
|
||||
Handle = DisplayApi.GetAssociatedUnAttachedNvidiaDisplayHandle(displayName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets display handle
|
||||
/// </summary>
|
||||
public UnAttachedDisplayHandle Handle { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets display name
|
||||
/// </summary>
|
||||
public string Name
|
||||
{
|
||||
get => DisplayApi.GetUnAttachedAssociatedDisplayName(Handle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets corresponding physical GPU
|
||||
/// </summary>
|
||||
public PhysicalGPU PhysicalGPU
|
||||
{
|
||||
get => new PhysicalGPU(GPUApi.GetPhysicalGPUFromUnAttachedDisplay(Handle));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks for equality with a UnAttachedDisplay instance
|
||||
/// </summary>
|
||||
/// <param name="other">The Display object to check with</param>
|
||||
/// <returns>true if both objects are equal, otherwise false</returns>
|
||||
public bool Equals(UnAttachedDisplay other)
|
||||
{
|
||||
if (ReferenceEquals(null, other))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ReferenceEquals(this, other))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return Handle.Equals(other.Handle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This function returns all unattached NVIDIA displays
|
||||
/// Note: Display handles can get invalidated on a modeset.
|
||||
/// </summary>
|
||||
/// <returns>An array of Display objects</returns>
|
||||
public static UnAttachedDisplay[] GetUnAttachedDisplays()
|
||||
{
|
||||
return
|
||||
DisplayApi.EnumNvidiaUnAttachedDisplayHandle().Select(handle => new UnAttachedDisplay(handle))
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks for equality between two objects of same type
|
||||
/// </summary>
|
||||
/// <param name="left">The first object</param>
|
||||
/// <param name="right">The second object</param>
|
||||
/// <returns>true, if both objects are equal, otherwise false</returns>
|
||||
public static bool operator ==(UnAttachedDisplay left, UnAttachedDisplay right)
|
||||
{
|
||||
return right?.Equals(left) ?? ReferenceEquals(left, null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks for inequality between two objects of same type
|
||||
/// </summary>
|
||||
/// <param name="left">The first object</param>
|
||||
/// <param name="right">The second object</param>
|
||||
/// <returns>true, if both objects are not equal, otherwise false</returns>
|
||||
public static bool operator !=(UnAttachedDisplay left, UnAttachedDisplay right)
|
||||
{
|
||||
return !(left == right);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (ReferenceEquals(null, obj))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ReferenceEquals(this, obj))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (obj.GetType() != GetType())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return Equals((UnAttachedDisplay) obj);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return Handle.GetHashCode();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string ToString()
|
||||
{
|
||||
return Name;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new active attached display from this unattached display
|
||||
/// At least one GPU must be present in the system and running an NVIDIA display driver.
|
||||
/// </summary>
|
||||
/// <returns>An active attached display</returns>
|
||||
public Display CreateDisplay()
|
||||
{
|
||||
return new Display(DisplayApi.CreateDisplayFromUnAttachedDisplay(Handle));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,165 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace NvAPIWrapper.Display
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a XYUVRQ scan-out warping vortex
|
||||
/// </summary>
|
||||
public class XYUVRQVortex : IEquatable<XYUVRQVortex>
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates a new instance of <see cref="XYUVRQVortex" />.
|
||||
/// </summary>
|
||||
/// <param name="x">The target view port mesh horizontal coordinate</param>
|
||||
/// <param name="y">The target view port mesh vertical coordinate</param>
|
||||
/// <param name="u">The desktop view port texture horizontal coordinate</param>
|
||||
/// <param name="v">The desktop view port texture vertical coordinate</param>
|
||||
/// <param name="r">The 3D warp perspective R factor</param>
|
||||
/// <param name="q">The 3D warp perspective Q factor</param>
|
||||
// ReSharper disable once TooManyDependencies
|
||||
public XYUVRQVortex(int x, int y, int u, int v, float r, float q)
|
||||
{
|
||||
X = x;
|
||||
Y = y;
|
||||
U = u;
|
||||
V = v;
|
||||
R = r;
|
||||
Q = q;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 3D warp perspective Q factor
|
||||
/// </summary>
|
||||
public float Q { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 3D warp perspective R factor
|
||||
/// </summary>
|
||||
public float R { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Desktop view port texture horizontal coordinate
|
||||
/// </summary>
|
||||
public int U { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Desktop view port texture vertical coordinate
|
||||
/// </summary>
|
||||
public int V { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Target view port mesh horizontal coordinate
|
||||
/// </summary>
|
||||
public int X { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Target view port mesh vertical coordinate
|
||||
/// </summary>
|
||||
public int Y { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool Equals(XYUVRQVortex other)
|
||||
{
|
||||
if (other == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ReferenceEquals(this, other))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return Math.Abs(Q - other.Q) < 0.0001 &&
|
||||
Math.Abs(R - other.R) < 0.0001 &&
|
||||
U == other.U &&
|
||||
V == other.V &&
|
||||
X == other.X &&
|
||||
Y == other.Y;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parses an array of floats and returns the corresponding <see cref="XYUVRQVortex" />s.
|
||||
/// </summary>
|
||||
/// <param name="floats">The array of float representing one or more <see cref="XYUVRQVortex" />s.</param>
|
||||
/// <returns>Instances of <see cref="XYUVRQVortex" />.</returns>
|
||||
public static IEnumerable<XYUVRQVortex> FromFloatArray(float[] floats)
|
||||
{
|
||||
for (var i = 0; i + 6 <= floats.Length; i += 6)
|
||||
{
|
||||
yield return new XYUVRQVortex(
|
||||
(int) floats[i],
|
||||
(int) floats[i + 1],
|
||||
(int) floats[i + 2],
|
||||
(int) floats[i + 3],
|
||||
floats[i + 4],
|
||||
floats[i + 5]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compares two instance of <see cref="XYUVRQVortex" /> for equality.
|
||||
/// </summary>
|
||||
/// <param name="left">The first instance.</param>
|
||||
/// <param name="right">The second instance.</param>
|
||||
/// <returns><see langword="true" /> if both instances are equal, otherwise <see langword="false" /></returns>
|
||||
public static bool operator ==(XYUVRQVortex left, XYUVRQVortex right)
|
||||
{
|
||||
return Equals(left, right) || left?.Equals(right) == true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compares two instance of <see cref="XYUVRQVortex" /> for in-equality.
|
||||
/// </summary>
|
||||
/// <param name="left">The first instance.</param>
|
||||
/// <param name="right">The second instance.</param>
|
||||
/// <returns><see langword="true" /> if both instances are not equal, otherwise <see langword="false" /></returns>
|
||||
public static bool operator !=(XYUVRQVortex left, XYUVRQVortex right)
|
||||
{
|
||||
return !(left == right);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (obj == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ReferenceEquals(this, obj))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return Equals(obj as XYUVRQVortex);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override int GetHashCode()
|
||||
{
|
||||
unchecked
|
||||
{
|
||||
var hashCode = Q.GetHashCode();
|
||||
hashCode = (hashCode * 397) ^ R.GetHashCode();
|
||||
hashCode = (hashCode * 397) ^ U;
|
||||
hashCode = (hashCode * 397) ^ V;
|
||||
hashCode = (hashCode * 397) ^ X;
|
||||
hashCode = (hashCode * 397) ^ Y;
|
||||
|
||||
return hashCode;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns this instance of <see cref="XYUVRQVortex"/> as a float array.
|
||||
/// </summary>
|
||||
/// <returns>An array of float values representing this instance of <see cref="XYUVRQVortex"/>.</returns>
|
||||
public float[] AsFloatArray()
|
||||
{
|
||||
return new[] {X, Y, U, V, R, Q};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
namespace NvAPIWrapper.GPU
|
||||
{
|
||||
/// <summary>
|
||||
/// Contains information about the accelerated graphics connection
|
||||
/// </summary>
|
||||
public class AGPInformation
|
||||
{
|
||||
internal AGPInformation(int aperture, int currentRate)
|
||||
{
|
||||
ApertureInMB = aperture;
|
||||
CurrentRate = currentRate;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets AGP aperture in megabytes
|
||||
/// </summary>
|
||||
public int ApertureInMB { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets current AGP Rate (0 = AGP not present, 1 = 1x, 2 = 2x, etc.)
|
||||
/// </summary>
|
||||
public int CurrentRate { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string ToString()
|
||||
{
|
||||
return $"AGP Aperture: {ApertureInMB}MB, Current Rate: {CurrentRate}x";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,201 +0,0 @@
|
||||
using NvAPIWrapper.Native;
|
||||
using NvAPIWrapper.Native.GPU;
|
||||
|
||||
namespace NvAPIWrapper.GPU
|
||||
{
|
||||
/// <summary>
|
||||
/// Contains information about the ECC memory
|
||||
/// </summary>
|
||||
public class ECCMemoryInformation
|
||||
{
|
||||
internal ECCMemoryInformation(PhysicalGPU physicalGPU)
|
||||
{
|
||||
PhysicalGPU = physicalGPU;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the number of aggregated ECC memory double bit errors
|
||||
/// </summary>
|
||||
public ulong AggregatedDoubleBitErrors
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!IsSupported || !IsEnabled)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return GPUApi.GetECCErrorInfo(PhysicalGPU.Handle).AggregatedErrors.DoubleBitErrors;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets the number of aggregated ECC memory single bit errors
|
||||
/// </summary>
|
||||
public ulong AggregatedSingleBitErrors
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!IsSupported || !IsEnabled)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return GPUApi.GetECCErrorInfo(PhysicalGPU.Handle).AggregatedErrors.SingleBitErrors;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the ECC memory configuration in regard to how changes are applied
|
||||
/// </summary>
|
||||
public ECCConfiguration Configuration
|
||||
{
|
||||
get
|
||||
{
|
||||
try
|
||||
{
|
||||
return GPUApi.GetECCStatusInfo(PhysicalGPU.Handle).ConfigurationOptions;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return ECCConfiguration.NotSupported;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the number of current ECC memory double bit errors
|
||||
/// </summary>
|
||||
public ulong CurrentDoubleBitErrors
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!IsSupported || !IsEnabled)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return GPUApi.GetECCErrorInfo(PhysicalGPU.Handle).CurrentErrors.DoubleBitErrors;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the number of current ECC memory single bit errors
|
||||
/// </summary>
|
||||
public ulong CurrentSingleBitErrors
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!IsSupported || !IsEnabled)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return GPUApi.GetECCErrorInfo(PhysicalGPU.Handle).CurrentErrors.SingleBitErrors;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a boolean value indicating if ECC memory error correction is enabled
|
||||
/// </summary>
|
||||
|
||||
public bool IsEnabled
|
||||
{
|
||||
get => IsSupported &&
|
||||
GPUApi.GetECCStatusInfo(PhysicalGPU.Handle).IsEnabled &&
|
||||
GPUApi.GetECCConfigurationInfo(PhysicalGPU.Handle).IsEnabled;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a boolean value indicating if ECC memory is enabled by default
|
||||
/// </summary>
|
||||
public bool IsEnabledByDefault
|
||||
{
|
||||
get => IsSupported &&
|
||||
GPUApi.GetECCConfigurationInfo(PhysicalGPU.Handle).IsEnabledByDefault;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a boolean value indicating if ECC memory is supported and available
|
||||
/// </summary>
|
||||
public bool IsSupported
|
||||
{
|
||||
get
|
||||
{
|
||||
try
|
||||
{
|
||||
return GPUApi.GetECCStatusInfo(PhysicalGPU.Handle).IsSupported;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the physical GPU that this instance describes
|
||||
/// </summary>
|
||||
public PhysicalGPU PhysicalGPU { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string ToString()
|
||||
{
|
||||
if (!IsSupported)
|
||||
{
|
||||
return "[Not Supported]";
|
||||
}
|
||||
|
||||
if (!IsEnabled)
|
||||
{
|
||||
return "[Disabled]";
|
||||
}
|
||||
|
||||
return
|
||||
$"{CurrentSingleBitErrors}, {CurrentDoubleBitErrors} ({AggregatedSingleBitErrors}, {AggregatedDoubleBitErrors})";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clears aggregated error counters.
|
||||
/// </summary>
|
||||
public void ClearAggregatedErrors()
|
||||
{
|
||||
GPUApi.ResetECCErrorInfo(PhysicalGPU.Handle, false, true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clears current error counters.
|
||||
/// </summary>
|
||||
public void ClearCurrentErrors()
|
||||
{
|
||||
GPUApi.ResetECCErrorInfo(PhysicalGPU.Handle, true, false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clears all error counters.
|
||||
/// </summary>
|
||||
public void ClearErrors()
|
||||
{
|
||||
GPUApi.ResetECCErrorInfo(PhysicalGPU.Handle, true, true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Disables ECC memory error correction.
|
||||
/// </summary>
|
||||
/// <param name="immediate">A boolean value to indicate if this change should get applied immediately</param>
|
||||
public void Disable(bool immediate)
|
||||
{
|
||||
GPUApi.SetECCConfiguration(PhysicalGPU.Handle, false, immediate);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Enables ECC memory error correction.
|
||||
/// </summary>
|
||||
/// <param name="immediate">A boolean value to indicate if this change should get applied immediately</param>
|
||||
public void Enable(bool immediate)
|
||||
{
|
||||
GPUApi.SetECCConfiguration(PhysicalGPU.Handle, true, immediate);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,115 +0,0 @@
|
||||
using NvAPIWrapper.Native;
|
||||
|
||||
namespace NvAPIWrapper.GPU
|
||||
{
|
||||
/// <summary>
|
||||
/// Contains physical GPU architect information
|
||||
/// </summary>
|
||||
public class GPUArchitectInformation
|
||||
{
|
||||
internal GPUArchitectInformation(PhysicalGPU physicalGPU)
|
||||
{
|
||||
PhysicalGPU = physicalGPU;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets total number of cores defined for this GPU, or zero for older architectures
|
||||
/// </summary>
|
||||
public int NumberOfCores
|
||||
{
|
||||
get => (int) GPUApi.GetGPUCoreCount(PhysicalGPU.Handle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the number of graphics processing clusters (aka GPU Partitions)
|
||||
/// </summary>
|
||||
public int NumberOfGPC
|
||||
{
|
||||
get => (int) GPUApi.GetPartitionCount(PhysicalGPU.Handle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the number of render output units
|
||||
/// </summary>
|
||||
public int NumberOfROPs
|
||||
{
|
||||
get => (int) GPUApi.GetROPCount(PhysicalGPU.Handle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the number of shader pipelines
|
||||
/// </summary>
|
||||
public int NumberOfShaderPipelines
|
||||
{
|
||||
get => (int) GPUApi.GetShaderPipeCount(PhysicalGPU.Handle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the number of shader sub pipelines
|
||||
/// </summary>
|
||||
public int NumberOfShaderSubPipelines
|
||||
{
|
||||
get => (int) GPUApi.GetShaderSubPipeCount(PhysicalGPU.Handle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the number of video processing engines
|
||||
/// </summary>
|
||||
public int NumberOfVPEs
|
||||
{
|
||||
get => (int) GPUApi.GetVPECount(PhysicalGPU.Handle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the physical GPU that this instance describes
|
||||
/// </summary>
|
||||
public PhysicalGPU PhysicalGPU { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the GPU revision number (should be displayed as a hex string)
|
||||
/// </summary>
|
||||
public int Revision
|
||||
{
|
||||
get => (int) GPUApi.GetArchitectInfo(PhysicalGPU.Handle).Revision;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the GPU short name (aka Codename)
|
||||
/// </summary>
|
||||
public string ShortName
|
||||
{
|
||||
get => GPUApi.GetShortName(PhysicalGPU.Handle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the total number of streaming multiprocessors
|
||||
/// </summary>
|
||||
public int TotalNumberOfSMs
|
||||
{
|
||||
get => (int) GPUApi.GetTotalSMCount(PhysicalGPU.Handle);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets the total number of streaming processors
|
||||
/// </summary>
|
||||
public int TotalNumberOfSPs
|
||||
{
|
||||
get => (int) GPUApi.GetTotalSPCount(PhysicalGPU.Handle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the total number of texture processing clusters
|
||||
/// </summary>
|
||||
public int TotalNumberOfTPCs
|
||||
{
|
||||
get => (int) GPUApi.GetTotalTPCCount(PhysicalGPU.Handle);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string ToString()
|
||||
{
|
||||
return $"[{ShortName} REV{Revision:X}] Cores: {NumberOfCores}";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,118 +0,0 @@
|
||||
using NvAPIWrapper.Native;
|
||||
using NvAPIWrapper.Native.GPU;
|
||||
|
||||
namespace NvAPIWrapper.GPU
|
||||
{
|
||||
/// <summary>
|
||||
/// Contains information about the GPU bus
|
||||
/// </summary>
|
||||
public class GPUBusInformation
|
||||
{
|
||||
internal GPUBusInformation(PhysicalGPU physicalGPU)
|
||||
{
|
||||
PhysicalGPU = physicalGPU;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets accelerated graphics port information
|
||||
/// </summary>
|
||||
public AGPInformation AGPInformation
|
||||
{
|
||||
get
|
||||
{
|
||||
if (BusType != GPUBusType.AGP)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return new AGPInformation(
|
||||
GPUApi.GetAGPAperture(PhysicalGPU.Handle),
|
||||
GPUApi.GetCurrentAGPRate(PhysicalGPU.Handle)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the bus identification
|
||||
/// </summary>
|
||||
public int BusId
|
||||
{
|
||||
get => GPUApi.GetBusId(PhysicalGPU.Handle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the bus slot identification
|
||||
/// </summary>
|
||||
public int BusSlot
|
||||
{
|
||||
get => GPUApi.GetBusSlotId(PhysicalGPU.Handle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the the bus type
|
||||
/// </summary>
|
||||
public GPUBusType BusType
|
||||
{
|
||||
get => GPUApi.GetBusType(PhysicalGPU.Handle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets number of PCIe lanes being used for the PCIe interface downstream
|
||||
/// </summary>
|
||||
public int CurrentPCIeLanes
|
||||
{
|
||||
get
|
||||
{
|
||||
if (BusType == GPUBusType.PCIExpress)
|
||||
{
|
||||
return GPUApi.GetCurrentPCIEDownStreamWidth(PhysicalGPU.Handle);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets GPU interrupt number
|
||||
/// </summary>
|
||||
public int IRQ
|
||||
{
|
||||
get => GPUApi.GetIRQ(PhysicalGPU.Handle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the PCI identifiers
|
||||
/// </summary>
|
||||
public PCIIdentifiers PCIIdentifiers
|
||||
{
|
||||
get
|
||||
{
|
||||
if (BusType == GPUBusType.FPCI || BusType == GPUBusType.PCI || BusType == GPUBusType.PCIExpress)
|
||||
{
|
||||
GPUApi.GetPCIIdentifiers(
|
||||
PhysicalGPU.Handle,
|
||||
out var deviceId,
|
||||
out var subSystemId,
|
||||
out var revisionId,
|
||||
out var extDeviceId
|
||||
);
|
||||
|
||||
return new PCIIdentifiers(deviceId, subSystemId, revisionId, (int) extDeviceId);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the physical GPU that this instance describes
|
||||
/// </summary>
|
||||
public PhysicalGPU PhysicalGPU { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string ToString()
|
||||
{
|
||||
return $"[{BusType}] Bus #{BusId}, Slot #{BusSlot}";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,130 +0,0 @@
|
||||
using System;
|
||||
using NvAPIWrapper.Native.GPU;
|
||||
using NvAPIWrapper.Native.GPU.Structures;
|
||||
|
||||
namespace NvAPIWrapper.GPU
|
||||
{
|
||||
/// <summary>
|
||||
/// Holds information regarding a GPU cooler entry
|
||||
/// </summary>
|
||||
public class GPUCooler
|
||||
{
|
||||
internal GPUCooler(int coolerId, PrivateCoolerSettingsV1.CoolerSetting coolerSetting, int currentRPM = -1)
|
||||
{
|
||||
CoolerId = coolerId;
|
||||
CurrentLevel = (int) coolerSetting.CurrentLevel;
|
||||
DefaultMinimumLevel = (int) coolerSetting.DefaultMinimumLevel;
|
||||
DefaultMaximumLevel = (int) coolerSetting.DefaultMaximumLevel;
|
||||
CurrentMinimumLevel = (int) coolerSetting.CurrentMinimumLevel;
|
||||
CurrentMaximumLevel = (int) coolerSetting.CurrentMaximumLevel;
|
||||
CoolerType = coolerSetting.CoolerType;
|
||||
CoolerController = coolerSetting.CoolerController;
|
||||
DefaultPolicy = coolerSetting.DefaultPolicy;
|
||||
CurrentPolicy = coolerSetting.CurrentPolicy;
|
||||
Target = coolerSetting.Target;
|
||||
ControlMode = coolerSetting.ControlMode;
|
||||
CurrentFanSpeedInRPM = currentRPM;
|
||||
}
|
||||
|
||||
// ReSharper disable once TooManyDependencies
|
||||
internal GPUCooler(
|
||||
PrivateFanCoolersInfoV1.FanCoolersInfoEntry infoEntry,
|
||||
PrivateFanCoolersStatusV1.FanCoolersStatusEntry statusEntry,
|
||||
PrivateFanCoolersControlV1.FanCoolersControlEntry controlEntry)
|
||||
{
|
||||
if (infoEntry.CoolerId != statusEntry.CoolerId || statusEntry.CoolerId != controlEntry.CoolerId)
|
||||
{
|
||||
throw new ArgumentException("Passed arguments are meant to be for different coolers.");
|
||||
}
|
||||
|
||||
CoolerId = (int) statusEntry.CoolerId;
|
||||
CurrentLevel = (int) statusEntry.CurrentLevel;
|
||||
DefaultMinimumLevel = (int) statusEntry.CurrentMinimumLevel;
|
||||
DefaultMaximumLevel = (int) statusEntry.CurrentMaximumLevel;
|
||||
CurrentMinimumLevel = (int) statusEntry.CurrentMinimumLevel;
|
||||
CurrentMaximumLevel = (int) statusEntry.CurrentMaximumLevel;
|
||||
CoolerType = CoolerType.Fan;
|
||||
CoolerController = CoolerController.Internal;
|
||||
DefaultPolicy = CoolerPolicy.None;
|
||||
CurrentPolicy = controlEntry.ControlMode == FanCoolersControlMode.Manual
|
||||
? CoolerPolicy.Manual
|
||||
: CoolerPolicy.None;
|
||||
Target = CoolerTarget.All;
|
||||
ControlMode = CoolerControlMode.Variable;
|
||||
CurrentFanSpeedInRPM = (int) statusEntry.CurrentRPM;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the cooler control mode
|
||||
/// </summary>
|
||||
public CoolerControlMode ControlMode { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the cooler controller
|
||||
/// </summary>
|
||||
public CoolerController CoolerController { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the cooler identification number or index
|
||||
/// </summary>
|
||||
public int CoolerId { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the cooler type
|
||||
/// </summary>
|
||||
public CoolerType CoolerType { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the GPU fan speed in revolutions per minute
|
||||
/// </summary>
|
||||
public int CurrentFanSpeedInRPM { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the cooler current level in percentage
|
||||
/// </summary>
|
||||
public int CurrentLevel { get; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets the cooler current maximum level in percentage
|
||||
/// </summary>
|
||||
public int CurrentMaximumLevel { get; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets the cooler current minimum level in percentage
|
||||
/// </summary>
|
||||
public int CurrentMinimumLevel { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the cooler current policy
|
||||
/// </summary>
|
||||
public CoolerPolicy CurrentPolicy { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the cooler default maximum level in percentage
|
||||
/// </summary>
|
||||
public int DefaultMaximumLevel { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the cooler default minimum level in percentage
|
||||
/// </summary>
|
||||
public int DefaultMinimumLevel { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the cooler default policy
|
||||
/// </summary>
|
||||
public CoolerPolicy DefaultPolicy { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the cooler target
|
||||
/// </summary>
|
||||
public CoolerTarget Target { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string ToString()
|
||||
{
|
||||
return $"[{CoolerId} @ {CoolerController}] {Target}: {CurrentLevel}%";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,340 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using NvAPIWrapper.Native;
|
||||
using NvAPIWrapper.Native.Exceptions;
|
||||
using NvAPIWrapper.Native.General;
|
||||
using NvAPIWrapper.Native.GPU;
|
||||
using NvAPIWrapper.Native.GPU.Structures;
|
||||
|
||||
namespace NvAPIWrapper.GPU
|
||||
{
|
||||
/// <summary>
|
||||
/// Contains information about the GPU coolers and current fan speed
|
||||
/// </summary>
|
||||
public class GPUCoolerInformation
|
||||
{
|
||||
internal GPUCoolerInformation(PhysicalGPU physicalGPU)
|
||||
{
|
||||
PhysicalGPU = physicalGPU;
|
||||
|
||||
// TODO: Add Support For Pascal Only Policy Table Method
|
||||
// TODO: GPUApi.GetCoolerPolicyTable & GPUApi.SetCoolerPolicyTable & GPUApi.RestoreCoolerPolicyTable
|
||||
// TODO: Better support of ClientFanCoolers set of APIs
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a list of all available coolers along with their current settings and status
|
||||
/// </summary>
|
||||
public IEnumerable<GPUCooler> Coolers
|
||||
{
|
||||
get
|
||||
{
|
||||
PrivateCoolerSettingsV1? settings = null;
|
||||
|
||||
try
|
||||
{
|
||||
settings = GPUApi.GetCoolerSettings(PhysicalGPU.Handle);
|
||||
}
|
||||
catch (NVIDIAApiException e)
|
||||
{
|
||||
if (e.Status != Status.NotSupported)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
if (settings != null)
|
||||
{
|
||||
for (var i = 0; i < settings.Value.CoolerSettings.Length; i++)
|
||||
{
|
||||
if (i == 0)
|
||||
{
|
||||
var currentRPM = -1;
|
||||
try
|
||||
{
|
||||
currentRPM = (int)GPUApi.GetTachReading(PhysicalGPU.Handle);
|
||||
}
|
||||
catch (NVIDIAApiException)
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
|
||||
if (currentRPM >= 0)
|
||||
{
|
||||
yield return new GPUCooler(
|
||||
i,
|
||||
settings.Value.CoolerSettings[i],
|
||||
currentRPM
|
||||
);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
yield return new GPUCooler(
|
||||
i,
|
||||
settings.Value.CoolerSettings[i]
|
||||
);
|
||||
}
|
||||
|
||||
yield break;
|
||||
}
|
||||
|
||||
PrivateFanCoolersStatusV1? status = null;
|
||||
PrivateFanCoolersInfoV1? info = null;
|
||||
PrivateFanCoolersControlV1? control = null;
|
||||
|
||||
try
|
||||
{
|
||||
status = GPUApi.GetClientFanCoolersStatus(PhysicalGPU.Handle);
|
||||
info = GPUApi.GetClientFanCoolersInfo(PhysicalGPU.Handle);
|
||||
control = GPUApi.GetClientFanCoolersControl(PhysicalGPU.Handle);
|
||||
}
|
||||
catch (NVIDIAApiException e)
|
||||
{
|
||||
if (e.Status != Status.NotSupported)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
if (status != null && info != null && control != null)
|
||||
{
|
||||
for (var i = 0; i < status.Value.FanCoolersStatusEntries.Length; i++)
|
||||
{
|
||||
if (info.Value.FanCoolersInfoEntries.Length > i &&
|
||||
control.Value.FanCoolersControlEntries.Length > i)
|
||||
{
|
||||
yield return new GPUCooler(
|
||||
info.Value.FanCoolersInfoEntries[i],
|
||||
status.Value.FanCoolersStatusEntries[i],
|
||||
control.Value.FanCoolersControlEntries[i]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
yield break;
|
||||
}
|
||||
|
||||
throw new NVIDIAApiException(Status.NotSupported);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the GPU fan speed in revolutions per minute
|
||||
/// </summary>
|
||||
public int CurrentFanSpeedInRPM
|
||||
{
|
||||
get
|
||||
{
|
||||
try
|
||||
{
|
||||
return (int) GPUApi.GetTachReading(PhysicalGPU.Handle);
|
||||
}
|
||||
catch
|
||||
{
|
||||
return Coolers.FirstOrDefault(cooler => cooler.Target == CoolerTarget.All)?.CurrentFanSpeedInRPM ??
|
||||
0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current fan speed in percentage if available
|
||||
/// </summary>
|
||||
public int CurrentFanSpeedLevel
|
||||
{
|
||||
get
|
||||
{
|
||||
try
|
||||
{
|
||||
return (int) GPUApi.GetCurrentFanSpeedLevel(PhysicalGPU.Handle);
|
||||
}
|
||||
catch
|
||||
{
|
||||
return Coolers.FirstOrDefault(cooler => cooler.Target == CoolerTarget.All)?.CurrentLevel ?? 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the physical GPU that this instance describes
|
||||
/// </summary>
|
||||
public PhysicalGPU PhysicalGPU { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{CurrentFanSpeedInRPM} RPM ({CurrentFanSpeedLevel}%)";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets all cooler settings to default.
|
||||
/// </summary>
|
||||
public void RestoreCoolerSettingsToDefault()
|
||||
{
|
||||
RestoreCoolerSettingsToDefault(Coolers.Select(cooler => cooler.CoolerId).ToArray());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets one or more cooler settings to default.
|
||||
/// </summary>
|
||||
/// <param name="coolerIds">The cooler identification numbers (indexes) to reset their settings to default.</param>
|
||||
public void RestoreCoolerSettingsToDefault(params int[] coolerIds)
|
||||
{
|
||||
var availableCoolerIds = Coolers.Select(cooler => cooler.CoolerId).ToArray();
|
||||
|
||||
if (coolerIds.Any(i => !availableCoolerIds.Contains(i)))
|
||||
{
|
||||
throw new ArgumentException("Invalid cooler identification number provided.", nameof(coolerIds));
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
GPUApi.RestoreCoolerSettings(PhysicalGPU.Handle, coolerIds.Select(i => (uint) i).ToArray());
|
||||
|
||||
return;
|
||||
}
|
||||
catch (NVIDIAApiException e)
|
||||
{
|
||||
if (e.Status != Status.NotSupported)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
var currentControl = GPUApi.GetClientFanCoolersControl(PhysicalGPU.Handle);
|
||||
var newControl = new PrivateFanCoolersControlV1(
|
||||
currentControl.FanCoolersControlEntries.Select(
|
||||
entry => coolerIds.Contains((int) entry.CoolerId)
|
||||
? new PrivateFanCoolersControlV1.FanCoolersControlEntry(
|
||||
entry.CoolerId,
|
||||
FanCoolersControlMode.Auto
|
||||
)
|
||||
: entry
|
||||
)
|
||||
.ToArray(),
|
||||
currentControl.UnknownUInt
|
||||
);
|
||||
GPUApi.SetClientFanCoolersControl(PhysicalGPU.Handle, newControl);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Changes a cooler settings by modifying the policy and the current level
|
||||
/// </summary>
|
||||
/// <param name="coolerId">The cooler identification number (index) to change the settings.</param>
|
||||
/// <param name="policy">The new cooler policy.</param>
|
||||
/// <param name="newLevel">The new cooler level. Valid only if policy is set to manual.</param>
|
||||
// ReSharper disable once TooManyDeclarations
|
||||
public void SetCoolerSettings(int coolerId, CoolerPolicy policy, int newLevel)
|
||||
{
|
||||
if (Coolers.All(cooler => cooler.CoolerId != coolerId))
|
||||
{
|
||||
throw new ArgumentException("Invalid cooler identification number provided.", nameof(coolerId));
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
GPUApi.SetCoolerLevels(
|
||||
PhysicalGPU.Handle,
|
||||
(uint) coolerId,
|
||||
new PrivateCoolerLevelsV1(new[]
|
||||
{
|
||||
new PrivateCoolerLevelsV1.CoolerLevel(policy, (uint) newLevel)
|
||||
}
|
||||
),
|
||||
1
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
catch (NVIDIAApiException e)
|
||||
{
|
||||
if (e.Status != Status.NotSupported)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
var currentControl = GPUApi.GetClientFanCoolersControl(PhysicalGPU.Handle);
|
||||
var newControl = new PrivateFanCoolersControlV1(
|
||||
currentControl.FanCoolersControlEntries.Select(
|
||||
entry => entry.CoolerId == coolerId
|
||||
? new PrivateFanCoolersControlV1.FanCoolersControlEntry(
|
||||
entry.CoolerId,
|
||||
policy == CoolerPolicy.Manual
|
||||
? FanCoolersControlMode.Manual
|
||||
: FanCoolersControlMode.Auto,
|
||||
policy == CoolerPolicy.Manual ? (uint)newLevel : 0u)
|
||||
: entry
|
||||
)
|
||||
.ToArray(),
|
||||
currentControl.UnknownUInt
|
||||
);
|
||||
GPUApi.SetClientFanCoolersControl(PhysicalGPU.Handle, newControl);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Changes a cooler setting by modifying the policy
|
||||
/// </summary>
|
||||
/// <param name="coolerId">The cooler identification number (index) to change the settings.</param>
|
||||
/// <param name="policy">The new cooler policy.</param>
|
||||
// ReSharper disable once TooManyDeclarations
|
||||
public void SetCoolerSettings(int coolerId, CoolerPolicy policy)
|
||||
{
|
||||
if (Coolers.All(cooler => cooler.CoolerId != coolerId))
|
||||
{
|
||||
throw new ArgumentException("Invalid cooler identification number provided.", nameof(coolerId));
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
GPUApi.SetCoolerLevels(
|
||||
PhysicalGPU.Handle,
|
||||
(uint) coolerId,
|
||||
new PrivateCoolerLevelsV1(new[]
|
||||
{
|
||||
new PrivateCoolerLevelsV1.CoolerLevel(policy)
|
||||
}
|
||||
),
|
||||
1
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
catch (NVIDIAApiException e)
|
||||
{
|
||||
if (e.Status != Status.NotSupported)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
var currentControl = GPUApi.GetClientFanCoolersControl(PhysicalGPU.Handle);
|
||||
var newControl = new PrivateFanCoolersControlV1(
|
||||
currentControl.FanCoolersControlEntries.Select(
|
||||
entry => entry.CoolerId == coolerId
|
||||
? new PrivateFanCoolersControlV1.FanCoolersControlEntry(
|
||||
entry.CoolerId,
|
||||
policy == CoolerPolicy.Manual
|
||||
? FanCoolersControlMode.Manual
|
||||
: FanCoolersControlMode.Auto)
|
||||
: entry
|
||||
)
|
||||
.ToArray(),
|
||||
currentControl.UnknownUInt
|
||||
);
|
||||
GPUApi.SetClientFanCoolersControl(PhysicalGPU.Handle, newControl);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Changes a cooler settings by modifying the policy to manual and sets a new level
|
||||
/// </summary>
|
||||
/// <param name="coolerId">The cooler identification number (index) to change the settings.</param>
|
||||
/// <param name="newLevel">The new cooler level.</param>
|
||||
public void SetCoolerSettings(int coolerId, int newLevel)
|
||||
{
|
||||
SetCoolerSettings(coolerId, CoolerPolicy.Manual, newLevel);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,222 +0,0 @@
|
||||
using System;
|
||||
using NvAPIWrapper.Native;
|
||||
using NvAPIWrapper.Native.GPU;
|
||||
using NvAPIWrapper.Native.Interfaces.GPU;
|
||||
|
||||
namespace NvAPIWrapper.GPU
|
||||
{
|
||||
/// <summary>
|
||||
/// Contains information regarding the available and total memory as well as the type of memory and other information
|
||||
/// regarding the GPU RAM and frame buffer
|
||||
/// </summary>
|
||||
public class GPUMemoryInformation : IDisplayDriverMemoryInfo
|
||||
{
|
||||
internal GPUMemoryInformation(PhysicalGPU physicalGPU)
|
||||
{
|
||||
PhysicalGPU = physicalGPU;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the frame buffer bandwidth
|
||||
/// </summary>
|
||||
|
||||
public int FrameBufferBandwidth
|
||||
{
|
||||
get
|
||||
{
|
||||
GPUApi.GetFrameBufferWidthAndLocation(PhysicalGPU.Handle, out var width, out _);
|
||||
|
||||
return (int) width;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the frame buffer location index
|
||||
/// </summary>
|
||||
public int FrameBufferLocation
|
||||
{
|
||||
get
|
||||
{
|
||||
GPUApi.GetFrameBufferWidthAndLocation(PhysicalGPU.Handle, out _, out var location);
|
||||
|
||||
return (int) location;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the internal clock to bus clock factor based on the type of RAM
|
||||
/// </summary>
|
||||
public int InternalClockToBusClockFactor
|
||||
{
|
||||
get => GetMemoryBusClockFactor(RAMType);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the internal clock to transfer rate factor based on the type of RAM
|
||||
/// </summary>
|
||||
public int InternalClockToTransferRateFactor
|
||||
{
|
||||
get => GetMemoryTransferRateFactor(RAMType);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets GPU physical frame buffer size in KB. This does NOT include any system RAM that may be dedicated for use by
|
||||
/// the GPU.
|
||||
/// </summary>
|
||||
public int PhysicalFrameBufferSizeInkB
|
||||
{
|
||||
get => GPUApi.GetPhysicalFrameBufferSize(PhysicalGPU.Handle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the physical GPU that this instance describes
|
||||
/// </summary>
|
||||
public PhysicalGPU PhysicalGPU { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the number of memory banks
|
||||
/// </summary>
|
||||
public uint RAMBanks
|
||||
{
|
||||
get => GPUApi.GetRAMBankCount(PhysicalGPU.Handle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the memory bus width
|
||||
/// </summary>
|
||||
public uint RAMBusWidth
|
||||
{
|
||||
get => GPUApi.GetRAMBusWidth(PhysicalGPU.Handle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the memory maker (brand)
|
||||
/// </summary>
|
||||
public GPUMemoryMaker RAMMaker
|
||||
{
|
||||
get => GPUApi.GetRAMMaker(PhysicalGPU.Handle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the memory type
|
||||
/// </summary>
|
||||
public GPUMemoryType RAMType
|
||||
{
|
||||
get => GPUApi.GetRAMType(PhysicalGPU.Handle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets virtual size of frame-buffer in KB for this GPU. This includes the physical RAM plus any system RAM that has
|
||||
/// been dedicated for use by the GPU.
|
||||
/// </summary>
|
||||
public int VirtualFrameBufferSizeInkB
|
||||
{
|
||||
get => GPUApi.GetVirtualFrameBufferSize(PhysicalGPU.Handle);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public uint AvailableDedicatedVideoMemoryInkB
|
||||
{
|
||||
get => GPUApi.GetMemoryInfo(PhysicalGPU.Handle).AvailableDedicatedVideoMemoryInkB;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public uint CurrentAvailableDedicatedVideoMemoryInkB
|
||||
{
|
||||
get => GPUApi.GetMemoryInfo(PhysicalGPU.Handle).CurrentAvailableDedicatedVideoMemoryInkB;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public uint DedicatedVideoMemoryInkB
|
||||
{
|
||||
get => GPUApi.GetMemoryInfo(PhysicalGPU.Handle).DedicatedVideoMemoryInkB;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public uint SharedSystemMemoryInkB
|
||||
{
|
||||
get => GPUApi.GetMemoryInfo(PhysicalGPU.Handle).SharedSystemMemoryInkB;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public uint SystemVideoMemoryInkB
|
||||
{
|
||||
get => GPUApi.GetMemoryInfo(PhysicalGPU.Handle).SystemVideoMemoryInkB;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the memory bus clock to internal memory clock factor
|
||||
/// </summary>
|
||||
/// <param name="memoryType"></param>
|
||||
/// <returns>The value of X in X(InternalMemoryClock)=(BusMemoryClock)</returns>
|
||||
public static int GetMemoryBusClockFactor(GPUMemoryType memoryType)
|
||||
{
|
||||
switch (memoryType)
|
||||
{
|
||||
case GPUMemoryType.SDRAM:
|
||||
|
||||
// Bus Clocks Per Internal Clock = 1
|
||||
return 1;
|
||||
case GPUMemoryType.DDR1:
|
||||
case GPUMemoryType.DDR2:
|
||||
case GPUMemoryType.DDR3:
|
||||
case GPUMemoryType.GDDR2:
|
||||
case GPUMemoryType.GDDR3:
|
||||
case GPUMemoryType.GDDR4:
|
||||
case GPUMemoryType.LPDDR2:
|
||||
case GPUMemoryType.GDDR5:
|
||||
case GPUMemoryType.GDDR5X:
|
||||
|
||||
// Bus Clocks Per Internal Clock = 2
|
||||
return 2;
|
||||
default:
|
||||
|
||||
throw new ArgumentOutOfRangeException(nameof(memoryType));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the number of transfers per internal memory clock factor
|
||||
/// </summary>
|
||||
/// <param name="memoryType"></param>
|
||||
/// <returns>The value of X in X(InternalMemoryClock)=(OperationsPerSecond)</returns>
|
||||
public static int GetMemoryTransferRateFactor(GPUMemoryType memoryType)
|
||||
{
|
||||
switch (memoryType)
|
||||
{
|
||||
case GPUMemoryType.SDRAM:
|
||||
|
||||
// Transfers Per Internal Clock = 1
|
||||
return 1;
|
||||
case GPUMemoryType.DDR1:
|
||||
case GPUMemoryType.DDR2:
|
||||
case GPUMemoryType.DDR3:
|
||||
case GPUMemoryType.GDDR2:
|
||||
case GPUMemoryType.GDDR3:
|
||||
case GPUMemoryType.GDDR4:
|
||||
case GPUMemoryType.LPDDR2:
|
||||
|
||||
// Transfers Per Internal Clock = 1
|
||||
return 2;
|
||||
case GPUMemoryType.GDDR5:
|
||||
|
||||
// Transfers Per Internal Clock = 2
|
||||
return 4;
|
||||
case GPUMemoryType.GDDR5X:
|
||||
|
||||
// Transfers Per Internal Clock = 4
|
||||
return 8;
|
||||
default:
|
||||
|
||||
throw new ArgumentOutOfRangeException(nameof(memoryType));
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string ToString()
|
||||
{
|
||||
return
|
||||
$"[{RAMMaker} {RAMType}] Total: {AvailableDedicatedVideoMemoryInkB:N0} kB - Available: {CurrentAvailableDedicatedVideoMemoryInkB:N0} kB";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,264 +0,0 @@
|
||||
using System;
|
||||
using NvAPIWrapper.Display;
|
||||
using NvAPIWrapper.Native;
|
||||
using NvAPIWrapper.Native.Exceptions;
|
||||
using NvAPIWrapper.Native.General;
|
||||
using NvAPIWrapper.Native.GPU;
|
||||
using NvAPIWrapper.Native.GPU.Structures;
|
||||
|
||||
namespace NvAPIWrapper.GPU
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a single GPU output
|
||||
/// </summary>
|
||||
public class GPUOutput : IEquatable<GPUOutput>
|
||||
{
|
||||
internal GPUOutput(OutputId outputId, PhysicalGPUHandle gpuHandle)
|
||||
{
|
||||
OutputId = outputId;
|
||||
OutputType = !gpuHandle.IsNull ? GPUApi.GetOutputType(gpuHandle, outputId) : OutputType.Unknown;
|
||||
PhysicalGPU = new PhysicalGPU(gpuHandle);
|
||||
}
|
||||
|
||||
internal GPUOutput(OutputId outputId, PhysicalGPU gpu)
|
||||
: this(outputId, gpu?.Handle ?? PhysicalGPUHandle.DefaultHandle)
|
||||
{
|
||||
PhysicalGPU = gpu;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the corresponding Digital Vibrance Control information
|
||||
/// </summary>
|
||||
public DVCInformation DigitalVibranceControl
|
||||
{
|
||||
get => new DVCInformation(OutputId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the corresponding HUE information
|
||||
/// </summary>
|
||||
public HUEInformation HUEControl
|
||||
{
|
||||
get => new HUEInformation(OutputId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the output identification as a single bit unsigned integer
|
||||
/// </summary>
|
||||
public OutputId OutputId { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the output type
|
||||
/// </summary>
|
||||
public OutputType OutputType { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the corresponding physical GPU
|
||||
/// </summary>
|
||||
public PhysicalGPU PhysicalGPU { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool Equals(GPUOutput other)
|
||||
{
|
||||
if (ReferenceEquals(null, other))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ReferenceEquals(this, other))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return PhysicalGPU.Equals(other.PhysicalGPU) && OutputId == other.OutputId;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks for equality between two objects of same type
|
||||
/// </summary>
|
||||
/// <param name="left">The first object</param>
|
||||
/// <param name="right">The second object</param>
|
||||
/// <returns>true, if both objects are equal, otherwise false</returns>
|
||||
public static bool operator ==(GPUOutput left, GPUOutput right)
|
||||
{
|
||||
return right?.Equals(left) ?? ReferenceEquals(left, null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks for inequality between two objects of same type
|
||||
/// </summary>
|
||||
/// <param name="left">The first object</param>
|
||||
/// <param name="right">The second object</param>
|
||||
/// <returns>true, if both objects are not equal, otherwise false</returns>
|
||||
public static bool operator !=(GPUOutput left, GPUOutput right)
|
||||
{
|
||||
return !(left == right);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (ReferenceEquals(null, obj))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ReferenceEquals(this, obj))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (obj.GetType() != GetType())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return Equals((GPUOutput) obj);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override int GetHashCode()
|
||||
{
|
||||
unchecked
|
||||
{
|
||||
return ((PhysicalGPU != null ? PhysicalGPU.GetHashCode() : 0) * 397) ^ (int) OutputId;
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{OutputId} {OutputType} @ {PhysicalGPU}";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Overrides the refresh rate on this output.
|
||||
/// The new refresh rate can be applied right away or deferred to be applied with the next OS
|
||||
/// mode-set.
|
||||
/// The override is good for only one mode-set (regardless whether it's deferred or immediate).
|
||||
/// </summary>
|
||||
/// <param name="refreshRate">The refresh rate to be applied.</param>
|
||||
/// <param name="isDeferred">
|
||||
/// A boolean value indicating if the refresh rate override should be deferred to the next OS
|
||||
/// mode-set.
|
||||
/// </param>
|
||||
public void OverrideRefreshRate(float refreshRate, bool isDeferred = false)
|
||||
{
|
||||
DisplayApi.SetRefreshRateOverride(OutputId, refreshRate, isDeferred);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads data from the I2C bus
|
||||
/// </summary>
|
||||
/// <param name="portId">The port id on which device is connected</param>
|
||||
/// <param name="useDDCPort">A boolean value indicating that the DDC port should be used instead of the communication port</param>
|
||||
/// <param name="deviceAddress">The device I2C slave address</param>
|
||||
/// <param name="registerAddress">The target I2C register address</param>
|
||||
/// <param name="readDataLength">The length of the buffer to allocate for the read operation.</param>
|
||||
/// <param name="speed">The target speed of the transaction in kHz</param>
|
||||
public byte[] ReadI2C(
|
||||
byte? portId,
|
||||
bool useDDCPort,
|
||||
byte deviceAddress,
|
||||
byte[] registerAddress,
|
||||
uint readDataLength,
|
||||
I2CSpeed speed = I2CSpeed.Default
|
||||
)
|
||||
{
|
||||
try
|
||||
{
|
||||
// ReSharper disable once InconsistentNaming
|
||||
var i2cInfoV3 = new I2CInfoV3(
|
||||
OutputId,
|
||||
portId,
|
||||
useDDCPort,
|
||||
deviceAddress,
|
||||
registerAddress,
|
||||
readDataLength,
|
||||
speed
|
||||
);
|
||||
|
||||
return PhysicalGPU.ReadI2C(i2cInfoV3);
|
||||
}
|
||||
catch (NVIDIAApiException e)
|
||||
{
|
||||
if (e.Status != Status.IncompatibleStructureVersion || portId != null)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
|
||||
// ignore
|
||||
}
|
||||
|
||||
// ReSharper disable once InconsistentNaming
|
||||
var i2cInfoV2 = new I2CInfoV2(
|
||||
OutputId,
|
||||
useDDCPort,
|
||||
deviceAddress,
|
||||
registerAddress,
|
||||
readDataLength,
|
||||
speed
|
||||
);
|
||||
|
||||
return PhysicalGPU.ReadI2C(i2cInfoV2);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes data to the I2C bus
|
||||
/// </summary>
|
||||
/// <param name="portId">The port id on which device is connected</param>
|
||||
/// <param name="useDDCPort">A boolean value indicating that the DDC port should be used instead of the communication port</param>
|
||||
/// <param name="deviceAddress">The device I2C slave address</param>
|
||||
/// <param name="registerAddress">The target I2C register address</param>
|
||||
/// <param name="data">The payload data</param>
|
||||
/// <param name="speed">The target speed of the transaction in kHz</param>
|
||||
public void WriteI2C(
|
||||
byte? portId,
|
||||
bool useDDCPort,
|
||||
byte deviceAddress,
|
||||
byte[] registerAddress,
|
||||
byte[] data,
|
||||
I2CSpeed speed = I2CSpeed.Default
|
||||
)
|
||||
{
|
||||
try
|
||||
{
|
||||
// ReSharper disable once InconsistentNaming
|
||||
var i2cInfoV3 = new I2CInfoV3(
|
||||
OutputId,
|
||||
portId,
|
||||
useDDCPort,
|
||||
deviceAddress,
|
||||
registerAddress,
|
||||
data,
|
||||
speed
|
||||
);
|
||||
|
||||
PhysicalGPU.WriteI2C(i2cInfoV3);
|
||||
|
||||
return;
|
||||
}
|
||||
catch (NVIDIAApiException e)
|
||||
{
|
||||
if (e.Status != Status.IncompatibleStructureVersion || portId != null)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
|
||||
// ignore
|
||||
}
|
||||
|
||||
// ReSharper disable once InconsistentNaming
|
||||
var i2cInfoV2 = new I2CInfoV2(
|
||||
OutputId,
|
||||
useDDCPort,
|
||||
deviceAddress,
|
||||
registerAddress,
|
||||
data,
|
||||
speed
|
||||
);
|
||||
|
||||
PhysicalGPU.WriteI2C(i2cInfoV2);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,124 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using NvAPIWrapper.Native;
|
||||
using NvAPIWrapper.Native.GPU;
|
||||
|
||||
namespace NvAPIWrapper.GPU
|
||||
{
|
||||
/// <summary>
|
||||
/// Contains information regarding the GPU performance control and limitations
|
||||
/// </summary>
|
||||
public class GPUPerformanceControl
|
||||
{
|
||||
internal GPUPerformanceControl(PhysicalGPU physicalGPU)
|
||||
{
|
||||
PhysicalGPU = physicalGPU;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current active performance limitation
|
||||
/// </summary>
|
||||
public PerformanceLimit CurrentActiveLimit
|
||||
{
|
||||
get => GPUApi.PerformancePoliciesGetStatus(PhysicalGPU.Handle).PerformanceLimit;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current performance decrease reason
|
||||
/// </summary>
|
||||
public PerformanceDecreaseReason CurrentPerformanceDecreaseReason
|
||||
{
|
||||
get => GPUApi.GetPerformanceDecreaseInfo(PhysicalGPU.Handle);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets a boolean value indicating if no load limit is supported with this GPU
|
||||
/// </summary>
|
||||
public bool IsNoLoadLimitSupported
|
||||
{
|
||||
get => GPUApi.PerformancePoliciesGetInfo(PhysicalGPU.Handle).IsNoLoadLimitSupported;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets a boolean value indicating if power limit is supported with this GPU
|
||||
/// </summary>
|
||||
public bool IsPowerLimitSupported
|
||||
{
|
||||
get => GPUApi.PerformancePoliciesGetInfo(PhysicalGPU.Handle).IsPowerLimitSupported;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets a boolean value indicating if temperature limit is supported with this GPU
|
||||
/// </summary>
|
||||
public bool IsTemperatureLimitSupported
|
||||
{
|
||||
get => GPUApi.PerformancePoliciesGetInfo(PhysicalGPU.Handle).IsTemperatureLimitSupported;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a boolean value indicating if voltage limit is supported with this GPU
|
||||
/// </summary>
|
||||
public bool IsVoltageLimitSupported
|
||||
{
|
||||
get => GPUApi.PerformancePoliciesGetInfo(PhysicalGPU.Handle).IsVoltageLimitSupported;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the physical GPU that this instance describes
|
||||
/// </summary>
|
||||
public PhysicalGPU PhysicalGPU { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets information regarding possible power limit policies and their acceptable range
|
||||
/// </summary>
|
||||
public IEnumerable<GPUPowerLimitInfo> PowerLimitInformation
|
||||
{
|
||||
get
|
||||
{
|
||||
return GPUApi.ClientPowerPoliciesGetInfo(PhysicalGPU.Handle).PowerPolicyInfoEntries
|
||||
.Select(entry => new GPUPowerLimitInfo(entry));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current active power limit policies
|
||||
/// </summary>
|
||||
public IEnumerable<GPUPowerLimitPolicy> PowerLimitPolicies
|
||||
{
|
||||
get
|
||||
{
|
||||
// TODO: GPUApi.ClientPowerPoliciesSetStatus();
|
||||
return GPUApi.ClientPowerPoliciesGetStatus(PhysicalGPU.Handle).PowerPolicyStatusEntries
|
||||
.Select(entry => new GPUPowerLimitPolicy(entry));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets information regarding possible thermal limit policies and their acceptable range
|
||||
/// </summary>
|
||||
public IEnumerable<GPUThermalLimitInfo> ThermalLimitInformation
|
||||
{
|
||||
get
|
||||
{
|
||||
return GPUApi.GetThermalPoliciesInfo(PhysicalGPU.Handle).ThermalPoliciesInfoEntries
|
||||
.Select(entry => new GPUThermalLimitInfo(entry));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current active thermal limit policies
|
||||
/// </summary>
|
||||
public IEnumerable<GPUThermalLimitPolicy> ThermalLimitPolicies
|
||||
{
|
||||
get
|
||||
{
|
||||
// TODO: GPUApi.SetThermalPoliciesStatus();
|
||||
return GPUApi.GetThermalPoliciesStatus(PhysicalGPU.Handle).ThermalPoliciesStatusEntries
|
||||
.Select(entry => new GPUThermalLimitPolicy(entry));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,70 +0,0 @@
|
||||
using System.Linq;
|
||||
using NvAPIWrapper.Native.GPU;
|
||||
using NvAPIWrapper.Native.Interfaces.GPU;
|
||||
|
||||
namespace NvAPIWrapper.GPU
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a performance state
|
||||
/// </summary>
|
||||
public class GPUPerformanceState
|
||||
{
|
||||
// ReSharper disable once TooManyDependencies
|
||||
internal GPUPerformanceState(
|
||||
int index,
|
||||
IPerformanceState20 performanceState,
|
||||
IPerformanceStates20ClockEntry[] statesClockEntries,
|
||||
IPerformanceStates20VoltageEntry[] baseVoltageEntries,
|
||||
PCIeInformation pcieInformation)
|
||||
{
|
||||
StateIndex = index;
|
||||
StateId = performanceState.StateId;
|
||||
IsReadOnly = !performanceState.IsEditable;
|
||||
Clocks = statesClockEntries.Select(entry => new GPUPerformanceStateClock(entry)).ToArray();
|
||||
Voltages = baseVoltageEntries.Select(entry => new GPUPerformanceStateVoltage(entry)).ToArray();
|
||||
PCIeInformation = pcieInformation;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a list of clocks associated with this performance state
|
||||
/// </summary>
|
||||
|
||||
public GPUPerformanceStateClock[] Clocks { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a boolean value indicating if this performance state is readonly
|
||||
/// </summary>
|
||||
public bool IsReadOnly { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the PCI-e information regarding this performance state.
|
||||
/// </summary>
|
||||
public PCIeInformation PCIeInformation { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the performance state identification
|
||||
/// </summary>
|
||||
public PerformanceStateId StateId { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the state index
|
||||
/// </summary>
|
||||
public int StateIndex { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a list of voltages associated with this performance state
|
||||
/// </summary>
|
||||
public GPUPerformanceStateVoltage[] Voltages { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string ToString()
|
||||
{
|
||||
if (IsReadOnly)
|
||||
{
|
||||
return $"{StateId} (ReadOnly)";
|
||||
}
|
||||
|
||||
return StateId.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,99 +0,0 @@
|
||||
using NvAPIWrapper.Native.GPU;
|
||||
using NvAPIWrapper.Native.Interfaces.GPU;
|
||||
|
||||
namespace NvAPIWrapper.GPU
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a performance state clock settings
|
||||
/// </summary>
|
||||
public class GPUPerformanceStateClock
|
||||
{
|
||||
internal GPUPerformanceStateClock(IPerformanceStates20ClockEntry states20ClockEntry)
|
||||
{
|
||||
ClockDomain = states20ClockEntry.DomainId;
|
||||
IsReadOnly = !states20ClockEntry.IsEditable;
|
||||
ClockDeltaInkHz = states20ClockEntry.FrequencyDeltaInkHz.DeltaValue;
|
||||
ClockDeltaRangeInkHz = new GPUPerformanceStateValueRange(
|
||||
states20ClockEntry.FrequencyDeltaInkHz.DeltaRange.Minimum,
|
||||
states20ClockEntry.FrequencyDeltaInkHz.DeltaRange.Maximum
|
||||
);
|
||||
|
||||
if (states20ClockEntry.ClockType == PerformanceStates20ClockType.Range)
|
||||
{
|
||||
CurrentClockInkHz = new GPUPerformanceStateValueRange(
|
||||
states20ClockEntry.FrequencyRange.MinimumFrequencyInkHz,
|
||||
states20ClockEntry.FrequencyRange.MaximumFrequencyInkHz
|
||||
);
|
||||
BaseClockInkHz = new GPUPerformanceStateValueRange(
|
||||
CurrentClockInkHz.Minimum - ClockDeltaInkHz,
|
||||
CurrentClockInkHz.Maximum - ClockDeltaInkHz
|
||||
);
|
||||
DependentVoltageDomain = states20ClockEntry.FrequencyRange.VoltageDomainId;
|
||||
DependentVoltageRangeInMicroVolt = new GPUPerformanceStateValueRange(
|
||||
states20ClockEntry.FrequencyRange.MinimumVoltageInMicroVolt,
|
||||
states20ClockEntry.FrequencyRange.MaximumVoltageInMicroVolt
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
CurrentClockInkHz = new GPUPerformanceStateValueRange(
|
||||
states20ClockEntry.SingleFrequency.FrequencyInkHz
|
||||
);
|
||||
BaseClockInkHz = new GPUPerformanceStateValueRange(
|
||||
CurrentClockInkHz.Minimum - ClockDeltaInkHz
|
||||
);
|
||||
DependentVoltageDomain = PerformanceVoltageDomain.Undefined;
|
||||
DependentVoltageRangeInMicroVolt = null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the base clock frequency in kHz
|
||||
/// </summary>
|
||||
public GPUPerformanceStateValueRange BaseClockInkHz { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the clock frequency delta in kHz
|
||||
/// </summary>
|
||||
public int ClockDeltaInkHz { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the clock frequency delta range in kHz
|
||||
/// </summary>
|
||||
public GPUPerformanceStateValueRange ClockDeltaRangeInkHz { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the clock domain
|
||||
/// </summary>
|
||||
public PublicClockDomain ClockDomain { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current clock frequency in kHz
|
||||
/// </summary>
|
||||
public GPUPerformanceStateValueRange CurrentClockInkHz { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the dependent voltage domain
|
||||
/// </summary>
|
||||
public PerformanceVoltageDomain DependentVoltageDomain { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the dependent voltage range in uV
|
||||
/// </summary>
|
||||
public GPUPerformanceStateValueRange DependentVoltageRangeInMicroVolt { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a boolean value indicating if this clock setting is readonly
|
||||
/// </summary>
|
||||
public bool IsReadOnly { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string ToString()
|
||||
{
|
||||
var title = IsReadOnly ? $"{ClockDomain} (ReadOnly)" : ClockDomain.ToString();
|
||||
|
||||
return
|
||||
$"{title}: {BaseClockInkHz} + ({ClockDeltaInkHz}) = {CurrentClockInkHz}";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,115 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace NvAPIWrapper.GPU
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents an integer value range
|
||||
/// </summary>
|
||||
public class GPUPerformanceStateValueRange : IEquatable<GPUPerformanceStateValueRange>
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates a new instance of <see cref="GPUPerformanceStateValueRange" />.
|
||||
/// </summary>
|
||||
/// <param name="min">The lower bound of the range.</param>
|
||||
/// <param name="max">The upper bound of the range.</param>
|
||||
public GPUPerformanceStateValueRange(long min, long max)
|
||||
{
|
||||
Minimum = min;
|
||||
Maximum = max;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new single value instance of <see cref="GPUPerformanceStateValueRange" />.
|
||||
/// </summary>
|
||||
/// <param name="value">The only value in the range</param>
|
||||
public GPUPerformanceStateValueRange(long value)
|
||||
{
|
||||
Minimum = value;
|
||||
Maximum = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the upper bound of the inclusive range
|
||||
/// </summary>
|
||||
public long Maximum { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the lower bound of the inclusive range
|
||||
/// </summary>
|
||||
public long Minimum { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool Equals(GPUPerformanceStateValueRange other)
|
||||
{
|
||||
if (other == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ReferenceEquals(this, other))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return Maximum == other.Maximum && Minimum == other.Minimum;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks two instances of <see cref="GPUPerformanceStateValueRange" /> for equality.
|
||||
/// </summary>
|
||||
/// <param name="left">The left side of the comparison.</param>
|
||||
/// <param name="right">The right side of the comparison.</param>
|
||||
/// <returns>true if instances are equal, otherwise false</returns>
|
||||
public static bool operator ==(GPUPerformanceStateValueRange left, GPUPerformanceStateValueRange right)
|
||||
{
|
||||
return Equals(left, right) || left?.Equals(right) == true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks two instances of <see cref="GPUPerformanceStateValueRange" /> for inequality.
|
||||
/// </summary>
|
||||
/// <param name="left">The left side of the comparison.</param>
|
||||
/// <param name="right">The right side of the comparison.</param>
|
||||
/// <returns>true if instances are in-equal, otherwise false</returns>
|
||||
public static bool operator !=(GPUPerformanceStateValueRange left, GPUPerformanceStateValueRange right)
|
||||
{
|
||||
return !(left == right);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (obj == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ReferenceEquals(this, obj))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return Equals(obj as GPUPerformanceStateValueRange);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override int GetHashCode()
|
||||
{
|
||||
unchecked
|
||||
{
|
||||
return ((int) Maximum * 397) ^ (int) Minimum;
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string ToString()
|
||||
{
|
||||
if (Minimum == Maximum)
|
||||
{
|
||||
return $"({Minimum})";
|
||||
}
|
||||
|
||||
return $"[({Minimum}) - ({Maximum})]";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,65 +0,0 @@
|
||||
using NvAPIWrapper.Native.GPU;
|
||||
using NvAPIWrapper.Native.Interfaces.GPU;
|
||||
|
||||
namespace NvAPIWrapper.GPU
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a performance state voltage settings
|
||||
/// </summary>
|
||||
public class GPUPerformanceStateVoltage
|
||||
{
|
||||
internal GPUPerformanceStateVoltage(IPerformanceStates20VoltageEntry states20BaseVoltageEntry)
|
||||
{
|
||||
VoltageDomain = states20BaseVoltageEntry.DomainId;
|
||||
IsReadOnly = !states20BaseVoltageEntry.IsEditable;
|
||||
|
||||
CurrentVoltageInMicroVolt = states20BaseVoltageEntry.ValueInMicroVolt;
|
||||
VoltageDeltaInMicroVolt = states20BaseVoltageEntry.ValueDeltaInMicroVolt.DeltaValue;
|
||||
BaseVoltageInMicroVolt = (int) (CurrentVoltageInMicroVolt - VoltageDeltaInMicroVolt);
|
||||
|
||||
VoltageDeltaRangeInMicroVolt = new GPUPerformanceStateValueRange(
|
||||
states20BaseVoltageEntry.ValueDeltaInMicroVolt.DeltaRange.Minimum,
|
||||
states20BaseVoltageEntry.ValueDeltaInMicroVolt.DeltaRange.Maximum
|
||||
);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the base voltage in uV
|
||||
/// </summary>
|
||||
public int BaseVoltageInMicroVolt { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current voltage in uV
|
||||
/// </summary>
|
||||
public uint CurrentVoltageInMicroVolt { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a boolean value indicating if this voltage is readonly
|
||||
/// </summary>
|
||||
public bool IsReadOnly { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the voltage delta in uV
|
||||
/// </summary>
|
||||
public int VoltageDeltaInMicroVolt { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the voltage delta range in uV
|
||||
/// </summary>
|
||||
public GPUPerformanceStateValueRange VoltageDeltaRangeInMicroVolt { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the voltage domain
|
||||
/// </summary>
|
||||
public PerformanceVoltageDomain VoltageDomain { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string ToString()
|
||||
{
|
||||
var title = IsReadOnly ? $"{VoltageDomain} (ReadOnly)" : VoltageDomain.ToString();
|
||||
|
||||
return
|
||||
$"{title}: ({BaseVoltageInMicroVolt}) + ({VoltageDeltaInMicroVolt}) = ({CurrentVoltageInMicroVolt})";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,107 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using NvAPIWrapper.Native.GPU;
|
||||
using NvAPIWrapper.Native.GPU.Structures;
|
||||
using NvAPIWrapper.Native.Interfaces.GPU;
|
||||
|
||||
namespace NvAPIWrapper.GPU
|
||||
{
|
||||
/// <summary>
|
||||
/// Holds the retrieved performance states information
|
||||
/// </summary>
|
||||
public class GPUPerformanceStatesInformation
|
||||
{
|
||||
internal GPUPerformanceStatesInformation(
|
||||
IPerformanceStates20Info states20Info,
|
||||
PerformanceStateId currentPerformanceStateId,
|
||||
PrivatePCIeInfoV2? pciInformation)
|
||||
{
|
||||
IsReadOnly = !states20Info.IsEditable;
|
||||
|
||||
GlobalVoltages = states20Info.GeneralVoltages
|
||||
.Select(entry => new GPUPerformanceStateVoltage(entry))
|
||||
.ToArray();
|
||||
|
||||
var clocks = states20Info.Clocks;
|
||||
var baseVoltages = states20Info.Voltages;
|
||||
|
||||
PerformanceStates = states20Info.PerformanceStates.Select((state20, i) =>
|
||||
{
|
||||
PCIeInformation statePCIeInfo = null;
|
||||
|
||||
if (pciInformation != null && pciInformation.Value.PCIePerformanceStateInfos.Length > i)
|
||||
{
|
||||
statePCIeInfo = new PCIeInformation(pciInformation.Value.PCIePerformanceStateInfos[i]);
|
||||
}
|
||||
|
||||
return new GPUPerformanceState(
|
||||
i,
|
||||
state20,
|
||||
clocks[state20.StateId],
|
||||
baseVoltages[state20.StateId],
|
||||
statePCIeInfo
|
||||
);
|
||||
}).ToArray();
|
||||
|
||||
CurrentPerformanceState =
|
||||
PerformanceStates.FirstOrDefault(performanceState =>
|
||||
performanceState.StateId == currentPerformanceStateId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the currently active performance state
|
||||
/// </summary>
|
||||
public GPUPerformanceState CurrentPerformanceState { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a list of global voltage settings
|
||||
/// </summary>
|
||||
public GPUPerformanceStateVoltage[] GlobalVoltages { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a boolean value indicating if performance states are readonly
|
||||
/// </summary>
|
||||
public bool IsReadOnly { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a list of all available performance states
|
||||
/// </summary>
|
||||
public GPUPerformanceState[] PerformanceStates { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string ToString()
|
||||
{
|
||||
if (PerformanceStates.Length == 0)
|
||||
{
|
||||
return "No Performance State Available";
|
||||
}
|
||||
|
||||
return string.Join(
|
||||
", ",
|
||||
PerformanceStates
|
||||
.Select(
|
||||
state =>
|
||||
{
|
||||
var attributes = new List<string>();
|
||||
|
||||
if (state.IsReadOnly)
|
||||
{
|
||||
attributes.Add("ReadOnly");
|
||||
}
|
||||
|
||||
if (CurrentPerformanceState.StateId == state.StateId)
|
||||
{
|
||||
attributes.Add("Active");
|
||||
}
|
||||
|
||||
if (attributes.Any())
|
||||
{
|
||||
return $"{state.StateId} ({string.Join(" - ", attributes)})";
|
||||
}
|
||||
|
||||
return state.StateId.ToString();
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,70 +0,0 @@
|
||||
using NvAPIWrapper.Native.GPU;
|
||||
using NvAPIWrapper.Native.GPU.Structures;
|
||||
|
||||
namespace NvAPIWrapper.GPU
|
||||
{
|
||||
/// <summary>
|
||||
/// Holds information regarding a possible power limit policy and its acceptable range
|
||||
/// </summary>
|
||||
public class GPUPowerLimitInfo
|
||||
{
|
||||
internal GPUPowerLimitInfo(PrivatePowerPoliciesInfoV1.PowerPolicyInfoEntry powerPolicyInfoEntry)
|
||||
{
|
||||
PerformanceStateId = powerPolicyInfoEntry.PerformanceStateId;
|
||||
MinimumPowerInPCM = powerPolicyInfoEntry.MinimumPowerInPCM;
|
||||
DefaultPowerInPCM = powerPolicyInfoEntry.DefaultPowerInPCM;
|
||||
MaximumPowerInPCM = powerPolicyInfoEntry.MaximumPowerInPCM;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the default policy target power in per cent mille (PCM)
|
||||
/// </summary>
|
||||
public uint DefaultPowerInPCM { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the default policy target power in percentage
|
||||
/// </summary>
|
||||
public float DefaultPowerInPercent
|
||||
{
|
||||
get => DefaultPowerInPCM / 1000f;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the maximum possible policy target power in per cent mille (PCM)
|
||||
/// </summary>
|
||||
public uint MaximumPowerInPCM { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the maximum possible policy target power in percentage
|
||||
/// </summary>
|
||||
public float MaximumPowerInPercent
|
||||
{
|
||||
get => MaximumPowerInPCM / 1000f;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the minimum possible policy target power in per cent mille (PCM)
|
||||
/// </summary>
|
||||
public uint MinimumPowerInPCM { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the minimum possible policy target power in percentage
|
||||
/// </summary>
|
||||
public float MinimumPowerInPercent
|
||||
{
|
||||
get => MinimumPowerInPCM / 1000f;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the corresponding performance state identification
|
||||
/// </summary>
|
||||
public PerformanceStateId PerformanceStateId { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string ToString()
|
||||
{
|
||||
return
|
||||
$"[{PerformanceStateId}] Default: {DefaultPowerInPercent}% - Range: ({MinimumPowerInPercent}% - {MaximumPowerInPercent}%)";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
using NvAPIWrapper.Native.GPU;
|
||||
using NvAPIWrapper.Native.GPU.Structures;
|
||||
|
||||
namespace NvAPIWrapper.GPU
|
||||
{
|
||||
/// <summary>
|
||||
/// Holds information regarding a currently active power limit policy
|
||||
/// </summary>
|
||||
public class GPUPowerLimitPolicy
|
||||
{
|
||||
internal GPUPowerLimitPolicy(PrivatePowerPoliciesStatusV1.PowerPolicyStatusEntry powerPolicyStatusEntry)
|
||||
{
|
||||
PerformanceStateId = powerPolicyStatusEntry.PerformanceStateId;
|
||||
PowerTargetInPCM = powerPolicyStatusEntry.PowerTargetInPCM;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the corresponding performance state identification
|
||||
/// </summary>
|
||||
public PerformanceStateId PerformanceStateId { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current policy target power in per cent mille (PCM)
|
||||
/// </summary>
|
||||
public uint PowerTargetInPCM { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current policy target power in percentage
|
||||
/// </summary>
|
||||
public float PowerTargetInPercent
|
||||
{
|
||||
get => PowerTargetInPCM / 1000f;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{PerformanceStateId} Target: {PowerTargetInPercent}%";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using NvAPIWrapper.Native;
|
||||
|
||||
namespace NvAPIWrapper.GPU
|
||||
{
|
||||
/// <summary>
|
||||
/// Holds information regarding current power topology and their current power usage
|
||||
/// </summary>
|
||||
public class GPUPowerTopologyInformation
|
||||
{
|
||||
internal GPUPowerTopologyInformation(PhysicalGPU physicalGPU)
|
||||
{
|
||||
PhysicalGPU = physicalGPU;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the physical GPU that this instance describes
|
||||
/// </summary>
|
||||
public PhysicalGPU PhysicalGPU { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current power topology entries
|
||||
/// </summary>
|
||||
public IEnumerable<GPUPowerTopologyStatus> PowerTopologyEntries
|
||||
{
|
||||
get
|
||||
{
|
||||
return GPUApi.ClientPowerTopologyGetStatus(PhysicalGPU.Handle).PowerPolicyStatusEntries
|
||||
.Select(entry => new GPUPowerTopologyStatus(entry));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
using NvAPIWrapper.Native.GPU;
|
||||
using NvAPIWrapper.Native.GPU.Structures;
|
||||
|
||||
namespace NvAPIWrapper.GPU
|
||||
{
|
||||
/// <summary>
|
||||
/// Contains information about a power domain usage
|
||||
/// </summary>
|
||||
public class GPUPowerTopologyStatus
|
||||
{
|
||||
internal GPUPowerTopologyStatus(
|
||||
PrivatePowerTopologiesStatusV1.PowerTopologiesStatusEntry powerTopologiesStatusEntry)
|
||||
{
|
||||
Domain = powerTopologiesStatusEntry.Domain;
|
||||
PowerUsageInPCM = powerTopologiesStatusEntry.PowerUsageInPCM;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the power usage domain
|
||||
/// </summary>
|
||||
public PowerTopologyDomain Domain { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current power usage in per cent mille (PCM)
|
||||
/// </summary>
|
||||
public uint PowerUsageInPCM { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current power usage in percentage
|
||||
/// </summary>
|
||||
public float PowerUsageInPercent
|
||||
{
|
||||
get => PowerUsageInPCM / 1000f;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string ToString()
|
||||
{
|
||||
return $"[{Domain}] {PowerUsageInPercent}%";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using NvAPIWrapper.Native;
|
||||
|
||||
namespace NvAPIWrapper.GPU
|
||||
{
|
||||
/// <summary>
|
||||
/// Holds information regarding the available thermal sensors and current thermal level of a GPU
|
||||
/// </summary>
|
||||
public class GPUThermalInformation
|
||||
{
|
||||
internal GPUThermalInformation(PhysicalGPU physicalGPU)
|
||||
{
|
||||
PhysicalGPU = physicalGPU;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current thermal level of the GPU
|
||||
/// </summary>
|
||||
public int CurrentThermalLevel
|
||||
{
|
||||
get => (int) GPUApi.GetCurrentThermalLevel(PhysicalGPU.Handle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the physical GPU that this instance describes
|
||||
/// </summary>
|
||||
public PhysicalGPU PhysicalGPU { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the list of available thermal sensors
|
||||
/// </summary>
|
||||
public IEnumerable<GPUThermalSensor> ThermalSensors
|
||||
{
|
||||
get
|
||||
{
|
||||
return GPUApi.GetThermalSettings(PhysicalGPU.Handle).Sensors
|
||||
.Select((sensor, i) => new GPUThermalSensor(i, sensor));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,47 +0,0 @@
|
||||
using NvAPIWrapper.Native.GPU;
|
||||
using NvAPIWrapper.Native.GPU.Structures;
|
||||
|
||||
namespace NvAPIWrapper.GPU
|
||||
{
|
||||
/// <summary>
|
||||
/// Holds information regarding a possible thermal limit policy and its acceptable range
|
||||
/// </summary>
|
||||
public class GPUThermalLimitInfo
|
||||
{
|
||||
internal GPUThermalLimitInfo(PrivateThermalPoliciesInfoV2.ThermalPoliciesInfoEntry policiesInfoEntry)
|
||||
{
|
||||
Controller = policiesInfoEntry.Controller;
|
||||
MinimumTemperature = policiesInfoEntry.MinimumTemperature;
|
||||
DefaultTemperature = policiesInfoEntry.DefaultTemperature;
|
||||
MaximumTemperature = policiesInfoEntry.MaximumTemperature;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the policy's thermal controller
|
||||
/// </summary>
|
||||
public ThermalController Controller { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the default policy target temperature in degree Celsius
|
||||
/// </summary>
|
||||
public int DefaultTemperature { get; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets the maximum possible policy target temperature in degree Celsius
|
||||
/// </summary>
|
||||
public int MaximumTemperature { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the minimum possible policy target temperature in degree Celsius
|
||||
/// </summary>
|
||||
public int MinimumTemperature { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string ToString()
|
||||
{
|
||||
return
|
||||
$"[{Controller}] Default: {DefaultTemperature}°C - Range: ({MinimumTemperature}°C - {MaximumTemperature}°C)";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
using NvAPIWrapper.Native.GPU;
|
||||
using NvAPIWrapper.Native.GPU.Structures;
|
||||
|
||||
namespace NvAPIWrapper.GPU
|
||||
{
|
||||
/// <summary>
|
||||
/// Holds information regarding a currently active temperature limit policy
|
||||
/// </summary>
|
||||
public class GPUThermalLimitPolicy
|
||||
{
|
||||
internal GPUThermalLimitPolicy(PrivateThermalPoliciesStatusV2.ThermalPoliciesStatusEntry thermalPoliciesEntry)
|
||||
{
|
||||
Controller = thermalPoliciesEntry.Controller;
|
||||
PerformanceStateId = thermalPoliciesEntry.PerformanceStateId;
|
||||
TargetTemperature = thermalPoliciesEntry.TargetTemperature;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the policy's thermal controller
|
||||
/// </summary>
|
||||
public ThermalController Controller { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the corresponding performance state identification
|
||||
/// </summary>
|
||||
public PerformanceStateId PerformanceStateId { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current policy target temperature in degree Celsius
|
||||
/// </summary>
|
||||
public int TargetTemperature { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string ToString()
|
||||
{
|
||||
return
|
||||
$"{PerformanceStateId} [{Controller}] Target: {TargetTemperature}°C";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
using NvAPIWrapper.Native.GPU;
|
||||
using NvAPIWrapper.Native.Interfaces.GPU;
|
||||
|
||||
namespace NvAPIWrapper.GPU
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a thermal sensor
|
||||
/// </summary>
|
||||
public class GPUThermalSensor : IThermalSensor
|
||||
{
|
||||
internal GPUThermalSensor(int sensorId, IThermalSensor thermalSensor)
|
||||
{
|
||||
SensorId = sensorId;
|
||||
Controller = thermalSensor.Controller;
|
||||
DefaultMinimumTemperature = thermalSensor.DefaultMinimumTemperature;
|
||||
DefaultMaximumTemperature = thermalSensor.DefaultMaximumTemperature;
|
||||
CurrentTemperature = thermalSensor.CurrentTemperature;
|
||||
Target = thermalSensor.Target;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the sensor identification number or index
|
||||
/// </summary>
|
||||
public int SensorId { get; set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public ThermalController Controller { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public int CurrentTemperature { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public int DefaultMaximumTemperature { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public int DefaultMinimumTemperature { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public ThermalSettingsTarget Target { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string ToString()
|
||||
{
|
||||
return
|
||||
$"[{Target} @ {Controller}] Current: {CurrentTemperature}°C - Default Range: [({DefaultMinimumTemperature}°C) , ({DefaultMaximumTemperature}°C)]";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
using NvAPIWrapper.Native.GPU;
|
||||
using NvAPIWrapper.Native.Interfaces.GPU;
|
||||
|
||||
namespace NvAPIWrapper.GPU
|
||||
{
|
||||
/// <summary>
|
||||
/// Holds information about a utilization domain
|
||||
/// </summary>
|
||||
public class GPUUsageDomainStatus
|
||||
{
|
||||
internal GPUUsageDomainStatus(UtilizationDomain domain, IUtilizationDomainInfo utilizationDomainInfo)
|
||||
{
|
||||
Domain = domain;
|
||||
Percentage = (int) utilizationDomainInfo.Percentage;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the utilization domain that this instance describes
|
||||
/// </summary>
|
||||
public UtilizationDomain Domain { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the percentage of time where the domain is considered busy in the last 1 second interval.
|
||||
/// </summary>
|
||||
public int Percentage { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string ToString()
|
||||
{
|
||||
return $"[{Domain}] {Percentage}%";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,99 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using NvAPIWrapper.Native;
|
||||
using NvAPIWrapper.Native.GPU;
|
||||
|
||||
namespace NvAPIWrapper.GPU
|
||||
{
|
||||
/// <summary>
|
||||
/// Holds information about the GPU utilization domains
|
||||
/// </summary>
|
||||
public class GPUUsageInformation
|
||||
{
|
||||
internal GPUUsageInformation(PhysicalGPU physicalGPU)
|
||||
{
|
||||
PhysicalGPU = physicalGPU;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the Bus interface (BUS) utilization
|
||||
/// </summary>
|
||||
public GPUUsageDomainStatus BusInterface
|
||||
{
|
||||
get => UtilizationDomainsStatus.FirstOrDefault(status => status.Domain == UtilizationDomain.BusInterface);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the frame buffer (FB) utilization
|
||||
/// </summary>
|
||||
public GPUUsageDomainStatus FrameBuffer
|
||||
{
|
||||
get => UtilizationDomainsStatus.FirstOrDefault(status => status.Domain == UtilizationDomain.FrameBuffer);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the graphic engine (GPU) utilization
|
||||
/// </summary>
|
||||
public GPUUsageDomainStatus GPU
|
||||
{
|
||||
get => UtilizationDomainsStatus.FirstOrDefault(status => status.Domain == UtilizationDomain.GPU);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a boolean value indicating if the dynamic performance states is enabled
|
||||
/// </summary>
|
||||
public bool IsDynamicPerformanceStatesEnabled
|
||||
{
|
||||
get => GPUApi.GetDynamicPerformanceStatesInfoEx(PhysicalGPU.Handle).IsDynamicPerformanceStatesEnabled;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the physical GPU that this instance describes
|
||||
/// </summary>
|
||||
public PhysicalGPU PhysicalGPU { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets all valid utilization domains and information
|
||||
/// </summary>
|
||||
public IEnumerable<GPUUsageDomainStatus> UtilizationDomainsStatus
|
||||
{
|
||||
get
|
||||
{
|
||||
try
|
||||
{
|
||||
var dynamicPerformanceStates = GPUApi.GetDynamicPerformanceStatesInfoEx(PhysicalGPU.Handle);
|
||||
|
||||
if (dynamicPerformanceStates.IsDynamicPerformanceStatesEnabled)
|
||||
{
|
||||
return dynamicPerformanceStates.Domains
|
||||
.Select(pair => new GPUUsageDomainStatus(pair.Key, pair.Value));
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
|
||||
return GPUApi.GetUsages(PhysicalGPU.Handle).Domains
|
||||
.Select(pair => new GPUUsageDomainStatus(pair.Key, pair.Value));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets the Video engine (VID) utilization
|
||||
/// </summary>
|
||||
public GPUUsageDomainStatus VideoEngine
|
||||
{
|
||||
get => UtilizationDomainsStatus.FirstOrDefault(status => status.Domain == UtilizationDomain.VideoEngine);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Enables dynamic performance states
|
||||
/// </summary>
|
||||
public void EnableDynamicPerformanceStates()
|
||||
{
|
||||
GPUApi.EnableDynamicPStates(PhysicalGPU.Handle);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,119 +0,0 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using NvAPIWrapper.Native;
|
||||
using NvAPIWrapper.Native.GPU.Structures;
|
||||
|
||||
namespace NvAPIWrapper.GPU
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a logical NVIDIA GPU
|
||||
/// </summary>
|
||||
public class LogicalGPU : IEquatable<LogicalGPU>
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates a new LogicalGPU
|
||||
/// </summary>
|
||||
/// <param name="handle">Logical GPU handle</param>
|
||||
public LogicalGPU(LogicalGPUHandle handle)
|
||||
{
|
||||
Handle = handle;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a list of all corresponding physical GPUs
|
||||
/// </summary>
|
||||
public PhysicalGPU[] CorrespondingPhysicalGPUs
|
||||
{
|
||||
get
|
||||
{
|
||||
return GPUApi.GetPhysicalGPUsFromLogicalGPU(Handle).Select(handle => new PhysicalGPU(handle)).ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the logical GPU handle
|
||||
/// </summary>
|
||||
public LogicalGPUHandle Handle { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool Equals(LogicalGPU other)
|
||||
{
|
||||
if (ReferenceEquals(null, other))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ReferenceEquals(this, other))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return Handle.Equals(other.Handle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets all logical GPUs
|
||||
/// </summary>
|
||||
/// <returns>An array of logical GPUs</returns>
|
||||
public static LogicalGPU[] GetLogicalGPUs()
|
||||
{
|
||||
return GPUApi.EnumLogicalGPUs().Select(handle => new LogicalGPU(handle)).ToArray();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks for equality between two objects of same type
|
||||
/// </summary>
|
||||
/// <param name="left">The first object</param>
|
||||
/// <param name="right">The second object</param>
|
||||
/// <returns>true, if both objects are equal, otherwise false</returns>
|
||||
public static bool operator ==(LogicalGPU left, LogicalGPU right)
|
||||
{
|
||||
return right?.Equals(left) ?? ReferenceEquals(left, null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks for inequality between two objects of same type
|
||||
/// </summary>
|
||||
/// <param name="left">The first object</param>
|
||||
/// <param name="right">The second object</param>
|
||||
/// <returns>true, if both objects are not equal, otherwise false</returns>
|
||||
public static bool operator !=(LogicalGPU left, LogicalGPU right)
|
||||
{
|
||||
return !(left == right);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (ReferenceEquals(null, obj))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ReferenceEquals(this, obj))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (obj.GetType() != GetType())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return Equals((LogicalGPU) obj);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return Handle.GetHashCode();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string ToString()
|
||||
{
|
||||
return
|
||||
$"Logical GPU [{CorrespondingPhysicalGPUs.Length}] {{{string.Join(", ", CorrespondingPhysicalGPUs.Select(gpu => gpu.FullName).ToArray())}}}";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,114 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace NvAPIWrapper.GPU
|
||||
{
|
||||
/// <summary>
|
||||
/// Contains information about the PCI connection
|
||||
/// </summary>
|
||||
public class PCIIdentifiers : IEquatable<PCIIdentifiers>
|
||||
{
|
||||
// ReSharper disable once TooManyDependencies
|
||||
internal PCIIdentifiers(uint deviceId, uint subSystemId, uint revisionId, int externalDeviceId = 0)
|
||||
{
|
||||
DeviceId = deviceId;
|
||||
SubSystemId = subSystemId;
|
||||
RevisionId = revisionId;
|
||||
|
||||
if (externalDeviceId > 0)
|
||||
{
|
||||
ExternalDeviceId = (ushort) externalDeviceId;
|
||||
}
|
||||
else
|
||||
{
|
||||
ExternalDeviceId = (ushort) (deviceId >> 16);
|
||||
}
|
||||
|
||||
VendorId = (ushort) ((DeviceId << 16) >> 16);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the internal PCI device identifier
|
||||
/// </summary>
|
||||
public uint DeviceId { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the external PCI device identifier
|
||||
/// </summary>
|
||||
public ushort ExternalDeviceId { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the internal PCI device-specific revision identifier
|
||||
/// </summary>
|
||||
public uint RevisionId { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the internal PCI subsystem identifier
|
||||
/// </summary>
|
||||
public uint SubSystemId { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the vendor identification calculated from internal device identification
|
||||
/// </summary>
|
||||
public ushort VendorId { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool Equals(PCIIdentifiers other)
|
||||
{
|
||||
return DeviceId == other.DeviceId &&
|
||||
SubSystemId == other.SubSystemId &&
|
||||
RevisionId == other.RevisionId;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks for equality between two objects of same type
|
||||
/// </summary>
|
||||
/// <param name="left">The first object</param>
|
||||
/// <param name="right">The second object</param>
|
||||
/// <returns>true, if both objects are equal, otherwise false</returns>
|
||||
public static bool operator ==(PCIIdentifiers left, PCIIdentifiers right)
|
||||
{
|
||||
return left.Equals(right);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks for inequality between two objects of same type
|
||||
/// </summary>
|
||||
/// <param name="left">The first object</param>
|
||||
/// <param name="right">The second object</param>
|
||||
/// <returns>true, if both objects are not equal, otherwise false</returns>
|
||||
public static bool operator !=(PCIIdentifiers left, PCIIdentifiers right)
|
||||
{
|
||||
return !left.Equals(right);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (ReferenceEquals(null, obj))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return obj is PCIIdentifiers identifiers && Equals(identifiers);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override int GetHashCode()
|
||||
{
|
||||
unchecked
|
||||
{
|
||||
var hashCode = (int) DeviceId;
|
||||
hashCode = (hashCode * 397) ^ (int) SubSystemId;
|
||||
hashCode = (hashCode * 397) ^ (int) RevisionId;
|
||||
|
||||
return hashCode;
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string ToString()
|
||||
{
|
||||
return $"PCI\\VEN_{VendorId:X}&DEV_{ExternalDeviceId:X}&SUBSYS_{SubSystemId:X}&REV_{RevisionId:X}";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,67 +0,0 @@
|
||||
using NvAPIWrapper.Native.GPU;
|
||||
using NvAPIWrapper.Native.GPU.Structures;
|
||||
|
||||
namespace NvAPIWrapper.GPU
|
||||
{
|
||||
/// <summary>
|
||||
/// Contains information about the PCI-e connection
|
||||
/// </summary>
|
||||
public class PCIeInformation
|
||||
{
|
||||
internal PCIeInformation(PrivatePCIeInfoV2.PCIePerformanceStateInfo stateInfo)
|
||||
{
|
||||
TransferRateInMTps = stateInfo.TransferRateInMTps;
|
||||
Generation = stateInfo.Generation;
|
||||
Lanes = stateInfo.Lanes;
|
||||
Version = stateInfo.Version;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the PCI-e generation
|
||||
/// </summary>
|
||||
public PCIeGeneration Generation { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the PCI-e down stream lanes
|
||||
/// </summary>
|
||||
public uint Lanes { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the PCIe transfer rate in Mega Transfers per Second
|
||||
/// </summary>
|
||||
public uint TransferRateInMTps { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the PCI-e version
|
||||
/// </summary>
|
||||
public PCIeGeneration Version { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string ToString()
|
||||
{
|
||||
var v = "Unknown";
|
||||
|
||||
switch (Version)
|
||||
{
|
||||
case PCIeGeneration.PCIe1:
|
||||
v = "PCIe 1.0";
|
||||
|
||||
break;
|
||||
case PCIeGeneration.PCIe1Minor1:
|
||||
v = "PCIe 1.1";
|
||||
|
||||
break;
|
||||
case PCIeGeneration.PCIe2:
|
||||
v = "PCIe 2.0";
|
||||
|
||||
break;
|
||||
case PCIeGeneration.PCIe3:
|
||||
v = "PCIe 3.0";
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
return $"{v} x{Lanes} - {TransferRateInMTps} MTps";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,559 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using NvAPIWrapper.Display;
|
||||
using NvAPIWrapper.Native;
|
||||
using NvAPIWrapper.Native.Exceptions;
|
||||
using NvAPIWrapper.Native.General;
|
||||
using NvAPIWrapper.Native.GPU;
|
||||
using NvAPIWrapper.Native.GPU.Structures;
|
||||
using NvAPIWrapper.Native.Helpers;
|
||||
using NvAPIWrapper.Native.Interfaces.GPU;
|
||||
|
||||
namespace NvAPIWrapper.GPU
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a physical NVIDIA GPU
|
||||
/// </summary>
|
||||
public class PhysicalGPU : IEquatable<PhysicalGPU>
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates a new PhysicalGPU
|
||||
/// </summary>
|
||||
/// <param name="handle">Physical GPU handle</param>
|
||||
public PhysicalGPU(PhysicalGPUHandle handle)
|
||||
{
|
||||
Handle = handle;
|
||||
UsageInformation = new GPUUsageInformation(this);
|
||||
ThermalInformation = new GPUThermalInformation(this);
|
||||
BusInformation = new GPUBusInformation(this);
|
||||
ArchitectInformation = new GPUArchitectInformation(this);
|
||||
MemoryInformation = new GPUMemoryInformation(this);
|
||||
CoolerInformation = new GPUCoolerInformation(this);
|
||||
ECCMemoryInformation = new ECCMemoryInformation(this);
|
||||
PerformanceControl = new GPUPerformanceControl(this);
|
||||
PowerTopologyInformation = new GPUPowerTopologyInformation(this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets all active outputs of this GPU
|
||||
/// </summary>
|
||||
public GPUOutput[] ActiveOutputs
|
||||
{
|
||||
get
|
||||
{
|
||||
var outputs = new List<GPUOutput>();
|
||||
var allOutputs = GPUApi.GetActiveOutputs(Handle);
|
||||
|
||||
foreach (OutputId outputId in Enum.GetValues(typeof(OutputId)))
|
||||
{
|
||||
if (outputId != OutputId.Invalid && allOutputs.HasFlag(outputId))
|
||||
{
|
||||
outputs.Add(new GPUOutput(outputId, this));
|
||||
}
|
||||
}
|
||||
|
||||
return outputs.ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets GPU architect information
|
||||
/// </summary>
|
||||
public GPUArchitectInformation ArchitectInformation { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets GPU base clock frequencies
|
||||
/// </summary>
|
||||
public IClockFrequencies BaseClockFrequencies
|
||||
{
|
||||
get => GPUApi.GetAllClockFrequencies(Handle, new ClockFrequenciesV2(ClockType.BaseClock));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets GPU video BIOS information
|
||||
/// </summary>
|
||||
public VideoBIOS Bios
|
||||
{
|
||||
get => new VideoBIOS(
|
||||
GPUApi.GetVBIOSRevision(Handle),
|
||||
(int) GPUApi.GetVBIOSOEMRevision(Handle),
|
||||
GPUApi.GetVBIOSVersionString(Handle)
|
||||
);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the board information
|
||||
/// </summary>
|
||||
public BoardInfo Board
|
||||
{
|
||||
get
|
||||
{
|
||||
try
|
||||
{
|
||||
return GPUApi.GetBoardInfo(Handle);
|
||||
}
|
||||
catch (NVIDIAApiException ex)
|
||||
{
|
||||
if (ex.Status == Status.NotSupported)
|
||||
{
|
||||
return default;
|
||||
}
|
||||
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets GPU boost clock frequencies
|
||||
/// </summary>
|
||||
public IClockFrequencies BoostClockFrequencies
|
||||
{
|
||||
get => GPUApi.GetAllClockFrequencies(Handle, new ClockFrequenciesV2(ClockType.BoostClock));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets GPU bus information
|
||||
/// </summary>
|
||||
public GPUBusInformation BusInformation { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets GPU coolers information
|
||||
/// </summary>
|
||||
public GPUCoolerInformation CoolerInformation { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets corresponding logical GPU
|
||||
/// </summary>
|
||||
public LogicalGPU CorrespondingLogicalGPU
|
||||
{
|
||||
get => new LogicalGPU(GPUApi.GetLogicalGPUFromPhysicalGPU(Handle));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets GPU current clock frequencies
|
||||
/// </summary>
|
||||
public IClockFrequencies CurrentClockFrequencies
|
||||
{
|
||||
get => GPUApi.GetAllClockFrequencies(Handle, new ClockFrequenciesV2(ClockType.CurrentClock));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the driver model number for this GPU
|
||||
/// </summary>
|
||||
public uint DriverModel
|
||||
{
|
||||
get => GPUApi.GetDriverModel(Handle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets GPU ECC memory information
|
||||
/// </summary>
|
||||
public ECCMemoryInformation ECCMemoryInformation { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the chipset foundry
|
||||
/// </summary>
|
||||
public GPUFoundry Foundry
|
||||
{
|
||||
get => GPUApi.GetFoundry(Handle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets GPU full name
|
||||
/// </summary>
|
||||
public string FullName
|
||||
{
|
||||
get => GPUApi.GetFullName(Handle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the GPU identification number
|
||||
/// </summary>
|
||||
public uint GPUId
|
||||
{
|
||||
get => GPUApi.GetGPUIDFromPhysicalGPU(Handle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets GPU type
|
||||
/// </summary>
|
||||
public GPUType GPUType
|
||||
{
|
||||
get => GPUApi.GetGPUType(Handle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the physical GPU handle
|
||||
/// </summary>
|
||||
public PhysicalGPUHandle Handle { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a boolean value indicating the Quadro line of products
|
||||
/// </summary>
|
||||
public bool IsQuadro
|
||||
{
|
||||
get => GPUApi.GetQuadroStatus(Handle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets GPU memory and RAM information as well as frame-buffer information
|
||||
/// </summary>
|
||||
public GPUMemoryInformation MemoryInformation { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets GPU performance control status and configurations
|
||||
/// </summary>
|
||||
public GPUPerformanceControl PerformanceControl { get; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets the GPU performance states information and configurations
|
||||
/// </summary>
|
||||
public GPUPerformanceStatesInformation PerformanceStatesInfo
|
||||
{
|
||||
get
|
||||
{
|
||||
var performanceStates20Info = GPUApi.GetPerformanceStates20(Handle);
|
||||
var currentPerformanceState = GPUApi.GetCurrentPerformanceState(Handle);
|
||||
PrivatePCIeInfoV2? pcieInformation = null;
|
||||
|
||||
if (BusInformation.BusType == GPUBusType.PCIExpress)
|
||||
{
|
||||
try
|
||||
{
|
||||
pcieInformation = GPUApi.GetPCIEInfo(Handle);
|
||||
}
|
||||
catch
|
||||
{
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
|
||||
return new GPUPerformanceStatesInformation(performanceStates20Info, currentPerformanceState,
|
||||
pcieInformation);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets GPU coolers information
|
||||
/// </summary>
|
||||
public GPUPowerTopologyInformation PowerTopologyInformation { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets GPU system type
|
||||
/// </summary>
|
||||
public SystemType SystemType
|
||||
{
|
||||
get => GPUApi.GetSystemType(Handle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets GPU thermal sensors information
|
||||
/// </summary>
|
||||
public GPUThermalInformation ThermalInformation { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the GPU utilization domains and usages
|
||||
/// </summary>
|
||||
public GPUUsageInformation UsageInformation { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool Equals(PhysicalGPU other)
|
||||
{
|
||||
if (other == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ReferenceEquals(this, other))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return Handle.Equals(other.Handle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the corresponding <see cref="PhysicalGPU" /> instance from a GPU identification number.
|
||||
/// </summary>
|
||||
/// <param name="gpuId">The GPU identification number.</param>
|
||||
/// <returns>An instance of <see cref="PhysicalGPU" /> or <see langword="null" /> if operation failed.</returns>
|
||||
public static PhysicalGPU FromGPUId(uint gpuId)
|
||||
{
|
||||
var handle = GPUApi.GetPhysicalGPUFromGPUID(gpuId);
|
||||
|
||||
if (handle.IsNull)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return new PhysicalGPU(handle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets all physical GPUs
|
||||
/// </summary>
|
||||
/// <returns>An array of physical GPUs</returns>
|
||||
public static PhysicalGPU[] GetPhysicalGPUs()
|
||||
{
|
||||
return GPUApi.EnumPhysicalGPUs().Select(handle => new PhysicalGPU(handle)).ToArray();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets all physical GPUs in TCC state
|
||||
/// </summary>
|
||||
/// <returns>An array of physical GPUs</returns>
|
||||
public static PhysicalGPU[] GetTCCPhysicalGPUs()
|
||||
{
|
||||
return GPUApi.EnumTCCPhysicalGPUs().Select(handle => new PhysicalGPU(handle)).ToArray();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks for equality between two objects of same type
|
||||
/// </summary>
|
||||
/// <param name="left">The first object</param>
|
||||
/// <param name="right">The second object</param>
|
||||
/// <returns>true, if both objects are equal, otherwise false</returns>
|
||||
public static bool operator ==(PhysicalGPU left, PhysicalGPU right)
|
||||
{
|
||||
return Equals(left, right) || left?.Equals(right) == true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks for inequality between two objects of same type
|
||||
/// </summary>
|
||||
/// <param name="left">The first object</param>
|
||||
/// <param name="right">The second object</param>
|
||||
/// <returns>true, if both objects are not equal, otherwise false</returns>
|
||||
public static bool operator !=(PhysicalGPU left, PhysicalGPU right)
|
||||
{
|
||||
return !(left == right);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (obj == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ReferenceEquals(this, obj))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return Equals(obj as PhysicalGPU);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return Handle.GetHashCode();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string ToString()
|
||||
{
|
||||
return FullName;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get a list of all active applications for this GPU
|
||||
/// </summary>
|
||||
/// <returns>An array of processes</returns>
|
||||
public Process[] GetActiveApplications()
|
||||
{
|
||||
return GPUApi.QueryActiveApps(Handle).Select(app => Process.GetProcessById(app.ProcessId)).ToArray();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get a list of all connected display devices on this GPU
|
||||
/// </summary>
|
||||
/// <param name="flags">ConnectedIdsFlag flag</param>
|
||||
/// <returns>An array of display devices</returns>
|
||||
public DisplayDevice[] GetConnectedDisplayDevices(ConnectedIdsFlag flags)
|
||||
{
|
||||
return GPUApi.GetConnectedDisplayIds(Handle, flags).Select(display => new DisplayDevice(display)).ToArray();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the display device connected to a specific GPU output
|
||||
/// </summary>
|
||||
/// <param name="output">The GPU output to get connected display device for</param>
|
||||
/// <returns>DisplayDevice connected to the specified GPU output</returns>
|
||||
public DisplayDevice GetDisplayDeviceByOutput(GPUOutput output)
|
||||
{
|
||||
return new DisplayDevice(GPUApi.GetDisplayIdFromGPUAndOutputId(Handle, output.OutputId));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get a list of all display devices on any possible output
|
||||
/// </summary>
|
||||
/// <returns>An array of display devices</returns>
|
||||
public DisplayDevice[] GetDisplayDevices()
|
||||
{
|
||||
return GPUApi.GetAllDisplayIds(Handle).Select(display => new DisplayDevice(display)).ToArray();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads EDID data of an output
|
||||
/// </summary>
|
||||
/// <param name="output">The GPU output to read EDID information for</param>
|
||||
/// <returns>A byte array containing EDID data</returns>
|
||||
public byte[] ReadEDIDData(GPUOutput output)
|
||||
{
|
||||
try
|
||||
{
|
||||
var data = new byte[0];
|
||||
var identification = 0;
|
||||
var totalSize = EDIDV3.MaxDataSize;
|
||||
|
||||
for (var offset = 0; offset < totalSize; offset += EDIDV3.MaxDataSize)
|
||||
{
|
||||
var edid = GPUApi.GetEDID(Handle, output.OutputId, offset, identification);
|
||||
identification = edid.Identification;
|
||||
totalSize = edid.TotalSize;
|
||||
|
||||
var edidData = edid.Data;
|
||||
Array.Resize(ref data, data.Length + edidData.Length);
|
||||
Array.Copy(edidData, 0, data, data.Length - edidData.Length, edidData.Length);
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
catch (NVIDIAApiException ex)
|
||||
{
|
||||
if (ex.Status == Status.IncompatibleStructureVersion)
|
||||
{
|
||||
return GPUApi.GetEDID(Handle, output.OutputId).Data;
|
||||
}
|
||||
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads data from the I2C bus
|
||||
/// </summary>
|
||||
/// <param name="i2cInfo">Information required to read from the I2C bus.</param>
|
||||
/// <returns>The returned payload.</returns>
|
||||
// ReSharper disable once InconsistentNaming
|
||||
public byte[] ReadI2C(II2CInfo i2cInfo)
|
||||
{
|
||||
GPUApi.I2CRead(Handle, ref i2cInfo);
|
||||
|
||||
return i2cInfo.Data;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validates a set of GPU outputs to check if they can be active simultaneously
|
||||
/// </summary>
|
||||
/// <param name="outputs">GPU outputs to check</param>
|
||||
/// <returns>true if all specified outputs can be active simultaneously, otherwise false</returns>
|
||||
public bool ValidateOutputCombination(GPUOutput[] outputs)
|
||||
{
|
||||
var gpuOutpudIds =
|
||||
outputs.Aggregate(OutputId.Invalid, (current, gpuOutput) => current | gpuOutput.OutputId);
|
||||
|
||||
return GPUApi.ValidateOutputCombination(Handle, gpuOutpudIds);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes EDID data of an output
|
||||
/// </summary>
|
||||
/// <param name="output">The GPU output to write EDID information for</param>
|
||||
/// <param name="edidData">A byte array containing EDID data</param>
|
||||
public void WriteEDIDData(GPUOutput output, byte[] edidData)
|
||||
{
|
||||
WriteEDIDData((uint) output.OutputId, edidData);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes EDID data of an display
|
||||
/// </summary>
|
||||
/// <param name="display">The display device to write EDID information for</param>
|
||||
/// <param name="edidData">A byte array containing EDID data</param>
|
||||
public void WriteEDIDData(DisplayDevice display, byte[] edidData)
|
||||
{
|
||||
WriteEDIDData(display.DisplayId, edidData);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes data to the I2C bus
|
||||
/// </summary>
|
||||
/// <param name="i2cInfo">Information required to write to the I2C bus including data payload.</param>
|
||||
// ReSharper disable once InconsistentNaming
|
||||
public void WriteI2C(II2CInfo i2cInfo)
|
||||
{
|
||||
GPUApi.I2CWrite(Handle, i2cInfo);
|
||||
}
|
||||
|
||||
private void WriteEDIDData(uint displayOutputId, byte[] edidData)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (edidData.Length == 0)
|
||||
{
|
||||
var instance = typeof(EDIDV3).Instantiate<EDIDV3>();
|
||||
GPUApi.SetEDID(Handle, displayOutputId, instance);
|
||||
}
|
||||
|
||||
for (var offset = 0; offset < edidData.Length; offset += EDIDV3.MaxDataSize)
|
||||
{
|
||||
var array = new byte[Math.Min(EDIDV3.MaxDataSize, edidData.Length - offset)];
|
||||
Array.Copy(edidData, offset, array, 0, array.Length);
|
||||
var instance = EDIDV3.CreateWithData(0, (uint) offset, array, edidData.Length);
|
||||
GPUApi.SetEDID(Handle, displayOutputId, instance);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
catch (NVIDIAApiException ex)
|
||||
{
|
||||
if (ex.Status != Status.IncompatibleStructureVersion)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
catch (NVIDIANotSupportedException)
|
||||
{
|
||||
// ignore
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
if (edidData.Length == 0)
|
||||
{
|
||||
var instance = typeof(EDIDV2).Instantiate<EDIDV2>();
|
||||
GPUApi.SetEDID(Handle, displayOutputId, instance);
|
||||
}
|
||||
|
||||
for (var offset = 0; offset < edidData.Length; offset += EDIDV2.MaxDataSize)
|
||||
{
|
||||
var array = new byte[Math.Min(EDIDV2.MaxDataSize, edidData.Length - offset)];
|
||||
Array.Copy(edidData, offset, array, 0, array.Length);
|
||||
GPUApi.SetEDID(Handle, displayOutputId, EDIDV2.CreateWithData(array, edidData.Length));
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
catch (NVIDIAApiException ex)
|
||||
{
|
||||
if (ex.Status != Status.IncompatibleStructureVersion)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
catch (NVIDIANotSupportedException)
|
||||
{
|
||||
// ignore
|
||||
}
|
||||
|
||||
GPUApi.SetEDID(Handle, displayOutputId, EDIDV1.CreateWithData(edidData));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,52 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace NvAPIWrapper.GPU
|
||||
{
|
||||
/// <summary>
|
||||
/// Contains information about the GPU Video BIOS
|
||||
/// </summary>
|
||||
public class VideoBIOS
|
||||
{
|
||||
internal VideoBIOS(uint revision, int oemRevision, string versionString)
|
||||
{
|
||||
Revision = revision;
|
||||
OEMRevision = oemRevision;
|
||||
VersionString = versionString.ToUpper();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the the OEM revision of the video BIOS
|
||||
/// </summary>
|
||||
public int OEMRevision { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the revision of the video BIOS
|
||||
/// </summary>
|
||||
public uint Revision { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the full video BIOS version string
|
||||
/// </summary>
|
||||
public string VersionString { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string ToString()
|
||||
{
|
||||
return AsVersion().ToString();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the video BIOS version as a .Net Version object
|
||||
/// </summary>
|
||||
/// <returns>A Version object representing the video BIOS version</returns>
|
||||
public Version AsVersion()
|
||||
{
|
||||
return new Version(
|
||||
(int) ((Revision >> 28) + ((Revision << 4) >> 28) * 16), // 8 bit little endian
|
||||
(int) (((Revision << 8) >> 28) + ((Revision << 12) >> 28) * 16), // 8 bit little endian
|
||||
(int) ((Revision << 16) >> 16), // 16 bit big endian
|
||||
OEMRevision // 8 bit integer
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 25 KiB |
@@ -1,81 +0,0 @@
|
||||
using NvAPIWrapper.Native;
|
||||
using NvAPIWrapper.Native.General.Structures;
|
||||
using NvAPIWrapper.Native.Interfaces.General;
|
||||
|
||||
namespace NvAPIWrapper
|
||||
{
|
||||
/// <summary>
|
||||
/// .Net friendly version of system and general functions of NVAPI library
|
||||
/// </summary>
|
||||
public static class NVIDIA
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets information about the system's chipset.
|
||||
/// </summary>
|
||||
public static IChipsetInfo ChipsetInfo
|
||||
{
|
||||
get => GeneralApi.GetChipsetInfo();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets NVIDIA driver branch version as string
|
||||
/// </summary>
|
||||
public static string DriverBranchVersion
|
||||
{
|
||||
get
|
||||
{
|
||||
GeneralApi.GetDriverAndBranchVersion(out var branchVersion);
|
||||
|
||||
return branchVersion;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets NVIDIA driver version
|
||||
/// </summary>
|
||||
public static uint DriverVersion
|
||||
{
|
||||
get => GeneralApi.GetDriverAndBranchVersion(out _);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets NVAPI interface version as string
|
||||
/// </summary>
|
||||
public static string InterfaceVersionString
|
||||
{
|
||||
get => GeneralApi.GetInterfaceVersionString();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current lid and dock information.
|
||||
/// </summary>
|
||||
public static LidDockParameters LidAndDockParameters
|
||||
{
|
||||
get => GeneralApi.GetLidAndDockInfo();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes the NvAPI library (if not already initialized) but always increments the ref-counter.
|
||||
/// </summary>
|
||||
public static void Initialize()
|
||||
{
|
||||
GeneralApi.Initialize();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// PRIVATE - Requests to restart the display driver
|
||||
/// </summary>
|
||||
public static void RestartDisplayDriver()
|
||||
{
|
||||
GeneralApi.RestartDisplayDriver();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Decrements the ref-counter and when it reaches ZERO, unloads NVAPI library.
|
||||
/// </summary>
|
||||
public static void Unload()
|
||||
{
|
||||
GeneralApi.Unload();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace NvAPIWrapper.Native.Attributes
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Delegate)]
|
||||
internal class AcceptsAttribute : Attribute
|
||||
{
|
||||
public AcceptsAttribute(params Type[] types)
|
||||
{
|
||||
Types = types;
|
||||
}
|
||||
|
||||
public Type[] Types { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
using System;
|
||||
using NvAPIWrapper.Native.Helpers;
|
||||
|
||||
namespace NvAPIWrapper.Native.Attributes
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Delegate)]
|
||||
internal class FunctionIdAttribute : Attribute
|
||||
{
|
||||
public FunctionIdAttribute(FunctionId functionId)
|
||||
{
|
||||
FunctionId = functionId;
|
||||
}
|
||||
|
||||
public FunctionId FunctionId { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace NvAPIWrapper.Native.Attributes
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Struct)]
|
||||
internal class StructureVersionAttribute : Attribute
|
||||
{
|
||||
public StructureVersionAttribute()
|
||||
{
|
||||
}
|
||||
|
||||
public StructureVersionAttribute(int versionNumber)
|
||||
{
|
||||
VersionNumber = versionNumber;
|
||||
}
|
||||
|
||||
public int VersionNumber { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
namespace NvAPIWrapper.Native.Constants
|
||||
{
|
||||
internal static class Display
|
||||
{
|
||||
public const int AdvancedDisplayHeads = 4;
|
||||
public const int MaxDisplayHeads = 2;
|
||||
}
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
namespace NvAPIWrapper.Native.Constants
|
||||
{
|
||||
internal static class General
|
||||
{
|
||||
public const int BinaryDataMax = 4096;
|
||||
public const int UnicodeStringLength = 2048;
|
||||
}
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
namespace NvAPIWrapper.Native.DRS
|
||||
{
|
||||
/// <summary>
|
||||
/// Holds possible values for the setting location
|
||||
/// </summary>
|
||||
public enum DRSSettingLocation : uint
|
||||
{
|
||||
/// <summary>
|
||||
/// Setting is part of the current profile
|
||||
/// </summary>
|
||||
CurrentProfile = 0,
|
||||
|
||||
/// <summary>
|
||||
/// Setting is part of the global profile
|
||||
/// </summary>
|
||||
GlobalProfile,
|
||||
|
||||
/// <summary>
|
||||
/// Setting is part of the base profile
|
||||
/// </summary>
|
||||
BaseProfile,
|
||||
|
||||
/// <summary>
|
||||
/// Setting is part of the default profile
|
||||
/// </summary>
|
||||
DefaultProfile
|
||||
}
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
namespace NvAPIWrapper.Native.DRS
|
||||
{
|
||||
/// <summary>
|
||||
/// Holds a list of possible setting value types
|
||||
/// </summary>
|
||||
public enum DRSSettingType : uint
|
||||
{
|
||||
/// <summary>
|
||||
/// Integer value type
|
||||
/// </summary>
|
||||
Integer = 0,
|
||||
|
||||
/// <summary>
|
||||
/// Binary value type
|
||||
/// </summary>
|
||||
Binary,
|
||||
|
||||
/// <summary>
|
||||
/// ASCII string value type
|
||||
/// </summary>
|
||||
String,
|
||||
|
||||
/// <summary>
|
||||
/// Unicode string value type
|
||||
/// </summary>
|
||||
UnicodeString
|
||||
}
|
||||
}
|
||||
@@ -1,77 +0,0 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using NvAPIWrapper.Native.Attributes;
|
||||
using NvAPIWrapper.Native.General.Structures;
|
||||
using NvAPIWrapper.Native.Helpers;
|
||||
using NvAPIWrapper.Native.Interfaces;
|
||||
using NvAPIWrapper.Native.Interfaces.DRS;
|
||||
|
||||
namespace NvAPIWrapper.Native.DRS.Structures
|
||||
{
|
||||
/// <inheritdoc cref="IDRSApplication" />
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 8)]
|
||||
[StructureVersion(1)]
|
||||
public struct DRSApplicationV1 : IInitializable, IDRSApplication
|
||||
{
|
||||
internal StructureVersion _Version;
|
||||
internal uint _IsPredefined;
|
||||
internal UnicodeString _ApplicationName;
|
||||
internal UnicodeString _FriendlyName;
|
||||
internal UnicodeString _LauncherName;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of <see cref="DRSApplicationV1" />
|
||||
/// </summary>
|
||||
/// <param name="applicationName">The application file name.</param>
|
||||
/// <param name="friendlyName">The application friendly name.</param>
|
||||
/// <param name="launcherName">The application launcher name.</param>
|
||||
public DRSApplicationV1(
|
||||
string applicationName,
|
||||
string friendlyName = null,
|
||||
string launcherName = null
|
||||
)
|
||||
{
|
||||
this = typeof(DRSApplicationV1).Instantiate<DRSApplicationV1>();
|
||||
IsPredefined = false;
|
||||
ApplicationName = applicationName;
|
||||
FriendlyName = friendlyName ?? string.Empty;
|
||||
LauncherName = launcherName ?? string.Empty;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool IsPredefined
|
||||
{
|
||||
get => _IsPredefined > 0;
|
||||
private set => _IsPredefined = value ? 1u : 0u;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public string ApplicationName
|
||||
{
|
||||
get => _ApplicationName.Value;
|
||||
private set
|
||||
{
|
||||
if (string.IsNullOrEmpty(value))
|
||||
{
|
||||
throw new ArgumentException("Name can not be empty or null.");
|
||||
}
|
||||
|
||||
_ApplicationName = new UnicodeString(value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public string FriendlyName
|
||||
{
|
||||
get => _FriendlyName.Value;
|
||||
private set => _FriendlyName = new UnicodeString(value);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public string LauncherName
|
||||
{
|
||||
get => _LauncherName.Value;
|
||||
private set => _LauncherName = new UnicodeString(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,93 +0,0 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using NvAPIWrapper.Native.Attributes;
|
||||
using NvAPIWrapper.Native.General.Structures;
|
||||
using NvAPIWrapper.Native.Helpers;
|
||||
using NvAPIWrapper.Native.Interfaces;
|
||||
using NvAPIWrapper.Native.Interfaces.DRS;
|
||||
|
||||
namespace NvAPIWrapper.Native.DRS.Structures
|
||||
{
|
||||
/// <inheritdoc cref="IDRSApplication" />
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 8)]
|
||||
[StructureVersion(2)]
|
||||
public struct DRSApplicationV2 : IInitializable, IDRSApplication
|
||||
{
|
||||
internal const char FileInFolderSeparator = ':';
|
||||
internal StructureVersion _Version;
|
||||
internal uint _IsPredefined;
|
||||
internal UnicodeString _ApplicationName;
|
||||
internal UnicodeString _FriendlyName;
|
||||
internal UnicodeString _LauncherName;
|
||||
internal UnicodeString _FileInFolder;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of <see cref="DRSApplicationV2" />
|
||||
/// </summary>
|
||||
/// <param name="applicationName">The application file name.</param>
|
||||
/// <param name="friendlyName">The application friendly name.</param>
|
||||
/// <param name="launcherName">The application launcher name.</param>
|
||||
/// <param name="fileInFolders">The list of files that are necessary to be present in the application parent directory.</param>
|
||||
// ReSharper disable once TooManyDependencies
|
||||
public DRSApplicationV2(
|
||||
string applicationName,
|
||||
string friendlyName = null,
|
||||
string launcherName = null,
|
||||
string[] fileInFolders = null
|
||||
)
|
||||
{
|
||||
this = typeof(DRSApplicationV2).Instantiate<DRSApplicationV2>();
|
||||
IsPredefined = false;
|
||||
ApplicationName = applicationName;
|
||||
FriendlyName = friendlyName ?? string.Empty;
|
||||
LauncherName = launcherName ?? string.Empty;
|
||||
FilesInFolder = fileInFolders ?? new string[0];
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool IsPredefined
|
||||
{
|
||||
get => _IsPredefined > 0;
|
||||
private set => _IsPredefined = value ? 1u : 0u;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public string ApplicationName
|
||||
{
|
||||
get => _ApplicationName.Value;
|
||||
private set
|
||||
{
|
||||
if (string.IsNullOrEmpty(value))
|
||||
{
|
||||
throw new ArgumentException("Name can not be empty or null.");
|
||||
}
|
||||
|
||||
_ApplicationName = new UnicodeString(value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public string FriendlyName
|
||||
{
|
||||
get => _FriendlyName.Value;
|
||||
private set => _FriendlyName = new UnicodeString(value);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public string LauncherName
|
||||
{
|
||||
get => _LauncherName.Value;
|
||||
private set => _LauncherName = new UnicodeString(value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the list of files that are necessary to be present in the application parent directory.
|
||||
/// </summary>
|
||||
public string[] FilesInFolder
|
||||
{
|
||||
get => _FileInFolder.Value?.Split(new[] {FileInFolderSeparator}, StringSplitOptions.RemoveEmptyEntries) ??
|
||||
new string[0];
|
||||
private set => _FileInFolder = new UnicodeString(string.Join(FileInFolderSeparator.ToString(), value));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,114 +0,0 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using NvAPIWrapper.Native.Attributes;
|
||||
using NvAPIWrapper.Native.General.Structures;
|
||||
using NvAPIWrapper.Native.Helpers;
|
||||
using NvAPIWrapper.Native.Interfaces;
|
||||
using NvAPIWrapper.Native.Interfaces.DRS;
|
||||
|
||||
namespace NvAPIWrapper.Native.DRS.Structures
|
||||
{
|
||||
/// <inheritdoc cref="IDRSApplication" />
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 8)]
|
||||
[StructureVersion(3)]
|
||||
public struct DRSApplicationV3 : IInitializable, IDRSApplication
|
||||
{
|
||||
internal const char FileInFolderSeparator = DRSApplicationV2.FileInFolderSeparator;
|
||||
internal StructureVersion _Version;
|
||||
internal uint _IsPredefined;
|
||||
internal UnicodeString _ApplicationName;
|
||||
internal UnicodeString _FriendlyName;
|
||||
internal UnicodeString _LauncherName;
|
||||
internal UnicodeString _FileInFolder;
|
||||
internal uint _Flags;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of <see cref="DRSApplicationV3" />
|
||||
/// </summary>
|
||||
/// <param name="applicationName">The application file name.</param>
|
||||
/// <param name="friendlyName">The application friendly name.</param>
|
||||
/// <param name="launcherName">The application launcher name.</param>
|
||||
/// <param name="fileInFolders">The list of files that are necessary to be present in the application parent directory.</param>
|
||||
/// <param name="isMetro">A boolean value indicating if this application is a metro application.</param>
|
||||
// ReSharper disable once TooManyDependencies
|
||||
public DRSApplicationV3(
|
||||
string applicationName,
|
||||
string friendlyName = null,
|
||||
string launcherName = null,
|
||||
string[] fileInFolders = null,
|
||||
bool isMetro = false
|
||||
)
|
||||
{
|
||||
this = typeof(DRSApplicationV3).Instantiate<DRSApplicationV3>();
|
||||
IsPredefined = false;
|
||||
ApplicationName = applicationName;
|
||||
FriendlyName = friendlyName ?? string.Empty;
|
||||
LauncherName = launcherName ?? string.Empty;
|
||||
FilesInFolder = fileInFolders ?? new string[0];
|
||||
IsMetroApplication = isMetro;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool IsPredefined
|
||||
{
|
||||
get => _IsPredefined > 0;
|
||||
private set => _IsPredefined = value ? 1u : 0u;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a boolean value indicating if this application is a metro application
|
||||
/// </summary>
|
||||
public bool IsMetroApplication
|
||||
{
|
||||
get => _Flags.GetBit(0);
|
||||
private set => _Flags = _Flags.SetBit(0, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a boolean value indicating if this application has command line arguments
|
||||
/// </summary>
|
||||
public bool HasCommandLine
|
||||
{
|
||||
get => _Flags.GetBit(1);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public string ApplicationName
|
||||
{
|
||||
get => _ApplicationName.Value;
|
||||
private set
|
||||
{
|
||||
if (string.IsNullOrEmpty(value))
|
||||
{
|
||||
throw new ArgumentException("Name can not be empty or null.");
|
||||
}
|
||||
|
||||
_ApplicationName = new UnicodeString(value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public string FriendlyName
|
||||
{
|
||||
get => _FriendlyName.Value;
|
||||
private set => _FriendlyName = new UnicodeString(value);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public string LauncherName
|
||||
{
|
||||
get => _LauncherName.Value;
|
||||
private set => _LauncherName = new UnicodeString(value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the list of files that are necessary to be present in the application parent directory.
|
||||
/// </summary>
|
||||
public string[] FilesInFolder
|
||||
{
|
||||
get => _FileInFolder.Value?.Split(new[] {FileInFolderSeparator}, StringSplitOptions.RemoveEmptyEntries) ??
|
||||
new string[0];
|
||||
private set => _FileInFolder = new UnicodeString(string.Join(FileInFolderSeparator.ToString(), value));
|
||||
}
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user