mirror of
https://github.com/Maassoft/ColorControl.git
synced 2026-10-19 07:10:13 -05:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bc565abd38 | ||
|
|
db19a9ad68 | ||
|
|
9fd8e8f9bb | ||
|
|
6eae7db459 | ||
|
|
2c5b08af72 | ||
|
|
3c5c2b3e4e | ||
|
|
c6f9bedcd2 | ||
|
|
de3a1a6e72 | ||
|
|
966b8336de | ||
|
|
bc102334c8 | ||
|
|
4186d4add5 | ||
|
|
e0d1ba13f0 | ||
|
|
21bd8e2080 | ||
|
|
3086058ebe | ||
|
|
464da6ccb8 | ||
|
|
7e1eb8bfa8 | ||
|
|
04d447a48b | ||
|
|
3ef21278cd | ||
|
|
3d7abd991c | ||
|
|
97b931f433 | ||
|
|
7543cca15d | ||
|
|
58e03313e0 | ||
|
|
fa013b056f | ||
|
|
8c186679cf | ||
|
|
047ba98067 | ||
|
|
db23e67742 | ||
|
|
52fd635fda | ||
|
|
6318d37247 | ||
|
|
dd083a5e9f | ||
|
|
4b6d687e4c | ||
|
|
dbf5670bc3 | ||
|
|
dd64ba491b | ||
|
|
04c6be729f | ||
|
|
dc6da0e60d | ||
|
|
7fcf154601 | ||
|
|
1c5095777c | ||
|
|
0322e7243d | ||
|
|
57a6a36d9b | ||
|
|
db1ca339fe | ||
|
|
c85b33127b | ||
|
|
43f038e9ee | ||
|
|
cb09d5c540 | ||
|
|
d29f607ab0 | ||
|
|
dc2f7f493c | ||
|
|
452206729b | ||
|
|
a8d41f67c9 | ||
|
|
84cb7e6446 | ||
|
|
6c21245b98 | ||
|
|
a1121c165f | ||
|
|
5836f88ef0 | ||
|
|
41cf8ae3e2 | ||
|
|
c1ace0bdd5 | ||
|
|
66e682ba3d | ||
|
|
0de3deebf7 | ||
|
|
0c1859f848 | ||
|
|
b8910a3b64 | ||
|
|
b2e7c529a0 | ||
|
|
977060e927 | ||
|
|
f609471fd2 | ||
|
|
a1a94d27db | ||
|
|
e12faaba27 | ||
|
|
6f5f7c4dd3 | ||
|
|
e1800b8d50 | ||
|
|
7779533c1e | ||
|
|
74cefc00f7 | ||
|
|
a8d33b6a30 | ||
|
|
f83869da04 | ||
|
|
815710c081 | ||
|
|
805c516371 | ||
|
|
b85d929890 | ||
|
|
dd9ce932fc | ||
|
|
3667243fc7 | ||
|
|
92f4ab8ef5 | ||
|
|
90ca095954 | ||
|
|
fa63d8dc4f | ||
|
|
fc134b146a | ||
|
|
3abf106496 | ||
|
|
a17534abcb | ||
|
|
4614886954 | ||
|
|
26a91dc7e9 | ||
|
|
cac5180c76 | ||
|
|
0c877623c0 | ||
|
|
a33543acd5 | ||
|
|
7f6175f8ef | ||
|
|
fd51bcca99 | ||
|
|
5268e6679e | ||
|
|
91fd44d698 | ||
|
|
48b13b1c64 | ||
|
|
d2aacbb8e0 | ||
|
|
04d52d6062 | ||
|
|
13420d2855 | ||
|
|
43a4660cc5 | ||
|
|
8683cd5be0 | ||
|
|
038a70cc81 |
No files matched your search
+2
-1
@@ -337,4 +337,5 @@ ASALocalRun/
|
||||
.localhistory/
|
||||
|
||||
# BeatPulse healthcheck temp database
|
||||
healthchecksdb
|
||||
healthchecksdb
|
||||
*.clef
|
||||
+57
-7
@@ -1,9 +1,19 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 16
|
||||
VisualStudioVersion = 16.0.30128.74
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.0.32014.148
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ColorControl", "ColorControl\ColorControl.csproj", "{A6005D08-70F0-44CB-A384-9219EBA84F21}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ColorControl", "ColorControl\ColorControl.csproj", "{A6005D08-70F0-44CB-A384-9219EBA84F21}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Nspector", "Nspector\Nspector.csproj", "{76797290-48F5-4A82-86C3-FAD25DAE4500}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NvAPIWrapper", "NvAPIWrapper\NvAPIWrapper.csproj", "{42E2B4A6-6857-4427-AEF1-DF4C7EF8CC7C}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "novideo_srgb", "novideo_srgb\novideo_srgb.csproj", "{A6A97834-7BE1-474A-B92F-A512DB1D5186}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NLogViewer", "NLogViewer\NLogViewer.csproj", "{D5E4D314-CFCD-4859-98FC-68F660AC7FB4}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Shared", "Shared\Shared.csproj", "{8F38D6B0-82DA-4DD1-89EB-918D8A18AEB1}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
@@ -15,12 +25,52 @@ Global
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{A6005D08-70F0-44CB-A384-9219EBA84F21}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{A6005D08-70F0-44CB-A384-9219EBA84F21}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{A6005D08-70F0-44CB-A384-9219EBA84F21}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{A6005D08-70F0-44CB-A384-9219EBA84F21}.Debug|x64.Build.0 = Debug|x64
|
||||
{A6005D08-70F0-44CB-A384-9219EBA84F21}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{A6005D08-70F0-44CB-A384-9219EBA84F21}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{A6005D08-70F0-44CB-A384-9219EBA84F21}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{A6005D08-70F0-44CB-A384-9219EBA84F21}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{A6005D08-70F0-44CB-A384-9219EBA84F21}.Release|x64.ActiveCfg = Release|x64
|
||||
{A6005D08-70F0-44CB-A384-9219EBA84F21}.Release|x64.Build.0 = Release|x64
|
||||
{A6005D08-70F0-44CB-A384-9219EBA84F21}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{A6005D08-70F0-44CB-A384-9219EBA84F21}.Release|x64.Build.0 = Release|Any CPU
|
||||
{76797290-48F5-4A82-86C3-FAD25DAE4500}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{76797290-48F5-4A82-86C3-FAD25DAE4500}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{76797290-48F5-4A82-86C3-FAD25DAE4500}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{76797290-48F5-4A82-86C3-FAD25DAE4500}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{76797290-48F5-4A82-86C3-FAD25DAE4500}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{76797290-48F5-4A82-86C3-FAD25DAE4500}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{76797290-48F5-4A82-86C3-FAD25DAE4500}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{76797290-48F5-4A82-86C3-FAD25DAE4500}.Release|x64.Build.0 = Release|Any CPU
|
||||
{42E2B4A6-6857-4427-AEF1-DF4C7EF8CC7C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{42E2B4A6-6857-4427-AEF1-DF4C7EF8CC7C}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{42E2B4A6-6857-4427-AEF1-DF4C7EF8CC7C}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{42E2B4A6-6857-4427-AEF1-DF4C7EF8CC7C}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{42E2B4A6-6857-4427-AEF1-DF4C7EF8CC7C}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{42E2B4A6-6857-4427-AEF1-DF4C7EF8CC7C}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{42E2B4A6-6857-4427-AEF1-DF4C7EF8CC7C}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{42E2B4A6-6857-4427-AEF1-DF4C7EF8CC7C}.Release|x64.Build.0 = Release|Any CPU
|
||||
{A6A97834-7BE1-474A-B92F-A512DB1D5186}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{A6A97834-7BE1-474A-B92F-A512DB1D5186}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{A6A97834-7BE1-474A-B92F-A512DB1D5186}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{A6A97834-7BE1-474A-B92F-A512DB1D5186}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{A6A97834-7BE1-474A-B92F-A512DB1D5186}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{A6A97834-7BE1-474A-B92F-A512DB1D5186}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{A6A97834-7BE1-474A-B92F-A512DB1D5186}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{A6A97834-7BE1-474A-B92F-A512DB1D5186}.Release|x64.Build.0 = Release|Any CPU
|
||||
{D5E4D314-CFCD-4859-98FC-68F660AC7FB4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{D5E4D314-CFCD-4859-98FC-68F660AC7FB4}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{D5E4D314-CFCD-4859-98FC-68F660AC7FB4}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{D5E4D314-CFCD-4859-98FC-68F660AC7FB4}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{D5E4D314-CFCD-4859-98FC-68F660AC7FB4}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{D5E4D314-CFCD-4859-98FC-68F660AC7FB4}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{D5E4D314-CFCD-4859-98FC-68F660AC7FB4}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{D5E4D314-CFCD-4859-98FC-68F660AC7FB4}.Release|x64.Build.0 = Release|Any CPU
|
||||
{8F38D6B0-82DA-4DD1-89EB-918D8A18AEB1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{8F38D6B0-82DA-4DD1-89EB-918D8A18AEB1}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{8F38D6B0-82DA-4DD1-89EB-918D8A18AEB1}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{8F38D6B0-82DA-4DD1-89EB-918D8A18AEB1}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{8F38D6B0-82DA-4DD1-89EB-918D8A18AEB1}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{8F38D6B0-82DA-4DD1-89EB-918D8A18AEB1}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{8F38D6B0-82DA-4DD1-89EB-918D8A18AEB1}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{8F38D6B0-82DA-4DD1-89EB-918D8A18AEB1}.Release|x64.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
{"Build":"0.3.261602\u002Befb3cc30a24e699e6e4337f263a2b9478f04f618","CurrentProject":"ColorControl.csproj","EntryPoints":["ColorControl.csproj"],"Properties":{}}
|
||||
@@ -1,529 +0,0 @@
|
||||
#region Copyright
|
||||
|
||||
/*******************************************************************************
|
||||
Copyright(c) 2008 - 2009 Advanced Micro Devices, Inc. All Rights Reserved.
|
||||
Copyright (c) 2002 - 2006 ATI Technologies Inc. All Rights Reserved.
|
||||
|
||||
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
|
||||
ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDED BUT NOT LIMITED TO
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
|
||||
PARTICULAR PURPOSE.
|
||||
|
||||
File: ADL.cs
|
||||
|
||||
Purpose: Implements ADL interface
|
||||
|
||||
Description: Implements some of the methods defined in ADL interface.
|
||||
|
||||
********************************************************************************/
|
||||
|
||||
#endregion Copyright
|
||||
|
||||
#region Using
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Diagnostics;
|
||||
using System.Threading;
|
||||
using FARPROC = System.IntPtr;
|
||||
using HMODULE = System.IntPtr;
|
||||
|
||||
#endregion Using
|
||||
|
||||
#region ATI.ADL
|
||||
|
||||
namespace ATI.ADL
|
||||
{
|
||||
#region Export Delegates
|
||||
/// <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>
|
||||
internal delegate IntPtr 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>
|
||||
internal delegate int ADL_Main_Control_Create(ADL_Main_Memory_Alloc callback, int enumConnectedAdapters);
|
||||
|
||||
/// <summary> ADL Destroy Function to free up ADL Data</summary>
|
||||
/// <returns> retrun ADL Error Code</returns>
|
||||
internal delegate int ADL_Main_Control_Destroy ();
|
||||
|
||||
/// <summary> ADL Function to get the number of adapters</summary>
|
||||
/// <param name="numAdapters">return number of adapters</param>
|
||||
/// <returns> retrun ADL Error Code</returns>
|
||||
internal delegate int ADL_Adapter_NumberOfAdapters_Get (ref 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>
|
||||
internal delegate int ADL_Adapter_AdapterInfo_Get (IntPtr 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>
|
||||
/// <param name="adapterIndex"> Adapter Index.</param>
|
||||
/// <param name="status"> Status of the adapter. True: Active; False: Dsiabled</param>
|
||||
/// <returns>Non zero is successfull</returns>
|
||||
internal delegate int ADL_Adapter_Active_Get(int adapterIndex, ref int status);
|
||||
|
||||
/// <summary>Get display information based on adapter index</summary>
|
||||
/// <param name="adapterIndex">Adapter Index</param>
|
||||
/// <param name="numDisplays">return the total number of supported displays</param>
|
||||
/// <param name="displayInfoArray">return ADLDisplayInfo Array for supported displays' information</param>
|
||||
/// <param name="forceDetect">force detect or not</param>
|
||||
/// <returns>return ADL Error Code</returns>
|
||||
internal delegate int ADL_Display_DisplayInfo_Get(int adapterIndex, ref int numDisplays, out IntPtr displayInfoArray, int forceDetect);
|
||||
|
||||
internal delegate int ADL_Display_Size_Get(int adapterIndex, int displayIndex, ref int lpWidth, ref int lpHeight, ref int lpDefaultWidth, ref int lpDefaultHeight, ref int lpMinWidth, ref int lpMinHeight, ref int lpMaxWidth, ref int lpMaxHeight, ref int lpStepWidth, ref int lpStepHeight);
|
||||
|
||||
#endregion Export Delegates
|
||||
|
||||
#region Export Struct
|
||||
|
||||
#region ADLAdapterInfo
|
||||
/// <summary> ADLAdapterInfo Structure</summary>
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal struct ADLAdapterInfo
|
||||
{
|
||||
/// <summary>The size of the structure</summary>
|
||||
int Size;
|
||||
/// <summary> Adapter Index</summary>
|
||||
internal int AdapterIndex;
|
||||
/// <summary> Adapter UDID</summary>
|
||||
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = (int)ADL.ADL_MAX_PATH)]
|
||||
internal string UDID;
|
||||
/// <summary> Adapter Bus Number</summary>
|
||||
internal int BusNumber;
|
||||
/// <summary> Adapter Driver Number</summary>
|
||||
internal int DriverNumber;
|
||||
/// <summary> Adapter Function Number</summary>
|
||||
internal int FunctionNumber;
|
||||
/// <summary> Adapter Vendor ID</summary>
|
||||
internal int VendorID;
|
||||
/// <summary> Adapter Adapter name</summary>
|
||||
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = (int)ADL.ADL_MAX_PATH)]
|
||||
internal string AdapterName;
|
||||
/// <summary> Adapter Display name</summary>
|
||||
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = (int)ADL.ADL_MAX_PATH)]
|
||||
internal string DisplayName;
|
||||
/// <summary> Adapter Present status</summary>
|
||||
internal int Present;
|
||||
/// <summary> Adapter Exist status</summary>
|
||||
internal int Exist;
|
||||
/// <summary> Adapter Driver Path</summary>
|
||||
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = (int)ADL.ADL_MAX_PATH)]
|
||||
internal string DriverPath;
|
||||
/// <summary> Adapter Driver Ext Path</summary>
|
||||
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = (int)ADL.ADL_MAX_PATH)]
|
||||
internal string DriverPathExt;
|
||||
/// <summary> Adapter PNP String</summary>
|
||||
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = (int)ADL.ADL_MAX_PATH)]
|
||||
internal string PNPString;
|
||||
/// <summary> OS Display Index</summary>
|
||||
internal int OSDisplayIndex;
|
||||
}
|
||||
|
||||
|
||||
/// <summary> ADLAdapterInfo Array</summary>
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal struct ADLAdapterInfoArray
|
||||
{
|
||||
/// <summary> ADLAdapterInfo Array </summary>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = (int)ADL.ADL_MAX_ADAPTERS)]
|
||||
internal ADLAdapterInfo[] ADLAdapterInfo;
|
||||
}
|
||||
#endregion ADLAdapterInfo
|
||||
|
||||
|
||||
#region ADLDisplayInfo
|
||||
/// <summary> ADLDisplayID Structure</summary>
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal struct ADLDisplayID
|
||||
{
|
||||
/// <summary> Display Logical Index </summary>
|
||||
internal int DisplayLogicalIndex;
|
||||
/// <summary> Display Physical Index </summary>
|
||||
internal int DisplayPhysicalIndex;
|
||||
/// <summary> Adapter Logical Index </summary>
|
||||
internal int DisplayLogicalAdapterIndex;
|
||||
/// <summary> Adapter Physical Index </summary>
|
||||
internal int DisplayPhysicalAdapterIndex;
|
||||
}
|
||||
|
||||
/// <summary> ADLDisplayInfo Structure</summary>
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal struct ADLDisplayInfo
|
||||
{
|
||||
/// <summary> Display Index </summary>
|
||||
internal ADLDisplayID DisplayID;
|
||||
/// <summary> Display Controller Index </summary>
|
||||
internal int DisplayControllerIndex;
|
||||
/// <summary> Display Name </summary>
|
||||
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = (int)ADL.ADL_MAX_PATH)]
|
||||
internal string DisplayName;
|
||||
/// <summary> Display Manufacturer Name </summary>
|
||||
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = (int)ADL.ADL_MAX_PATH)]
|
||||
internal string DisplayManufacturerName;
|
||||
/// <summary> Display Type : < The Display type. CRT, TV,CV,DFP are some of display types,</summary>
|
||||
internal int DisplayType;
|
||||
/// <summary> Display output type </summary>
|
||||
internal int DisplayOutputType;
|
||||
/// <summary> Connector type</summary>
|
||||
internal int DisplayConnector;
|
||||
///<summary> Indicating the display info bits' mask.<summary>
|
||||
internal int DisplayInfoMask;
|
||||
///<summary> Indicating the display info value.<summary>
|
||||
internal int DisplayInfoValue;
|
||||
}
|
||||
#endregion ADLDisplayInfo
|
||||
|
||||
#endregion Export Struct
|
||||
|
||||
#region ADL Class
|
||||
/// <summary> ADL Class</summary>
|
||||
internal static class ADL
|
||||
{
|
||||
#region Internal Constant
|
||||
/// <summary> Define the maximum path</summary>
|
||||
internal const int ADL_MAX_PATH = 256;
|
||||
/// <summary> Define the maximum adapters</summary>
|
||||
internal const int ADL_MAX_ADAPTERS = 40 /* 150 */;
|
||||
/// <summary> Define the maximum displays</summary>
|
||||
internal const int ADL_MAX_DISPLAYS = 40 /* 150 */;
|
||||
/// <summary> Define the maximum device name length</summary>
|
||||
internal const int ADL_MAX_DEVICENAME = 32;
|
||||
/// <summary> Define the successful</summary>
|
||||
internal const int ADL_SUCCESS = 0;
|
||||
/// <summary> Define the failure</summary>
|
||||
internal const int ADL_FAIL = -1;
|
||||
/// <summary> Define the driver ok</summary>
|
||||
internal const int ADL_DRIVER_OK = 0;
|
||||
/// <summary> Maximum number of GL-Sync ports on the GL-Sync module </summary>
|
||||
internal const int ADL_MAX_GLSYNC_PORTS = 8;
|
||||
/// <summary> Maximum number of GL-Sync ports on the GL-Sync module </summary>
|
||||
internal const int ADL_MAX_GLSYNC_PORT_LEDS = 8;
|
||||
/// <summary> Maximum number of ADLMOdes for the adapter </summary>
|
||||
internal const int ADL_MAX_NUM_DISPLAYMODES = 1024;
|
||||
|
||||
#endregion Internal Constant
|
||||
|
||||
#region Class ADLImport
|
||||
/// <summary> ADLImport class</summary>
|
||||
private static class ADLImport
|
||||
{
|
||||
#region Internal Constant
|
||||
/// <summary> Atiadlxx_FileName </summary>
|
||||
internal const string Atiadlxx_FileName = "atiadlxx.dll";
|
||||
/// <summary> Kernel32_FileName </summary>
|
||||
internal const string Kernel32_FileName = "kernel32.dll";
|
||||
#endregion Internal Constant
|
||||
|
||||
#region DLLImport
|
||||
[DllImport(Kernel32_FileName)]
|
||||
internal static extern HMODULE GetModuleHandle (string moduleName);
|
||||
|
||||
[DllImport(Atiadlxx_FileName)]
|
||||
internal static extern int ADL_Main_Control_Create (ADL_Main_Memory_Alloc callback, int enumConnectedAdapters);
|
||||
|
||||
[DllImport(Atiadlxx_FileName)]
|
||||
internal static extern int ADL_Main_Control_Destroy ();
|
||||
|
||||
[DllImport(Atiadlxx_FileName)]
|
||||
internal static extern int ADL_Main_Control_IsFunctionValid (HMODULE module, string procName);
|
||||
|
||||
[DllImport(Atiadlxx_FileName)]
|
||||
internal static extern FARPROC ADL_Main_Control_GetProcAddress (HMODULE module, string procName);
|
||||
|
||||
[DllImport(Atiadlxx_FileName)]
|
||||
internal static extern int ADL_Adapter_NumberOfAdapters_Get (ref int numAdapters);
|
||||
|
||||
[DllImport(Atiadlxx_FileName)]
|
||||
internal static extern int ADL_Adapter_AdapterInfo_Get (IntPtr info, int inputSize);
|
||||
|
||||
[DllImport(Atiadlxx_FileName)]
|
||||
internal static extern int ADL_Adapter_Active_Get(int adapterIndex, ref int status);
|
||||
|
||||
[DllImport(Atiadlxx_FileName)]
|
||||
internal static extern int ADL_Display_DisplayInfo_Get(int adapterIndex, ref int numDisplays, out IntPtr displayInfoArray, int forceDetect);
|
||||
|
||||
[DllImport(Atiadlxx_FileName)]
|
||||
internal static extern int ADL_Display_Size_Get(int iAdapterIndex, int iDisplayIndex, ref int lpWidth, ref int lpHeight, ref int lpDefaultWidth, ref int lpDefaultHeight, ref int lpMinWidth, ref int lpMinHeight, ref int lpMaxWidth, ref int lpMaxHeight, ref int lpStepWidth, ref int lpStepHeight);
|
||||
|
||||
#endregion DLLImport
|
||||
}
|
||||
#endregion Class ADLImport
|
||||
|
||||
#region Class ADLCheckLibrary
|
||||
/// <summary> ADLCheckLibrary class</summary>
|
||||
private class ADLCheckLibrary
|
||||
{
|
||||
#region Private Members
|
||||
private HMODULE ADLLibrary = System.IntPtr.Zero;
|
||||
#endregion Private Members
|
||||
|
||||
#region Static Members
|
||||
/// <summary> new a private instance</summary>
|
||||
private static ADLCheckLibrary ADLCheckLibrary_ = new ADLCheckLibrary();
|
||||
#endregion Static Members
|
||||
|
||||
#region Constructor
|
||||
/// <summary> Constructor</summary>
|
||||
private ADLCheckLibrary ()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (1 == ADLImport.ADL_Main_Control_IsFunctionValid(IntPtr.Zero, "ADL_Main_Control_Create"))
|
||||
{
|
||||
ADLLibrary = ADLImport.GetModuleHandle(ADLImport.Atiadlxx_FileName);
|
||||
}
|
||||
}
|
||||
catch (DllNotFoundException) { }
|
||||
catch (EntryPointNotFoundException) { }
|
||||
catch (Exception) { }
|
||||
}
|
||||
#endregion Constructor
|
||||
|
||||
#region Destructor
|
||||
/// <summary> Destructor to force calling ADL Destroy function before free up the ADL library</summary>
|
||||
~ADLCheckLibrary ()
|
||||
{
|
||||
if (System.IntPtr.Zero != ADLCheckLibrary_.ADLLibrary)
|
||||
{
|
||||
ADLImport.ADL_Main_Control_Destroy();
|
||||
}
|
||||
}
|
||||
#endregion Destructor
|
||||
|
||||
#region Static IsFunctionValid
|
||||
/// <summary> Check the import function to see it exists or not</summary>
|
||||
/// <param name="functionName"> function name</param>
|
||||
/// <returns>return true, if function exists</returns>
|
||||
internal static bool IsFunctionValid (string functionName)
|
||||
{
|
||||
bool result = false;
|
||||
if (System.IntPtr.Zero != ADLCheckLibrary_.ADLLibrary)
|
||||
{
|
||||
if (1 == ADLImport.ADL_Main_Control_IsFunctionValid(ADLCheckLibrary_.ADLLibrary, functionName))
|
||||
{
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
#endregion Static IsFunctionValid
|
||||
|
||||
#region Static GetProcAddress
|
||||
/// <summary> Get the unmanaged function pointer </summary>
|
||||
/// <param name="functionName"> function name</param>
|
||||
/// <returns>return function pointer, if function exists</returns>
|
||||
internal static FARPROC GetProcAddress (string functionName)
|
||||
{
|
||||
FARPROC result = System.IntPtr.Zero;
|
||||
if (System.IntPtr.Zero != ADLCheckLibrary_.ADLLibrary)
|
||||
{
|
||||
result = ADLImport.ADL_Main_Control_GetProcAddress(ADLCheckLibrary_.ADLLibrary, functionName);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
#endregion Static GetProcAddress
|
||||
}
|
||||
#endregion Class ADLCheckLibrary
|
||||
|
||||
#region Export Functions
|
||||
|
||||
#region ADL_Main_Memory_Alloc
|
||||
/// <summary> Build in memory allocation function</summary>
|
||||
internal static ADL_Main_Memory_Alloc ADL_Main_Memory_Alloc = ADL_Main_Memory_Alloc_;
|
||||
/// <summary> Build in memory allocation function</summary>
|
||||
/// <param name="size">input size</param>
|
||||
/// <returns>return the memory buffer</returns>
|
||||
private static IntPtr ADL_Main_Memory_Alloc_ (int size)
|
||||
{
|
||||
IntPtr result = Marshal.AllocCoTaskMem(size);
|
||||
return result;
|
||||
}
|
||||
#endregion ADL_Main_Memory_Alloc
|
||||
|
||||
#region ADL_Main_Memory_Free
|
||||
/// <summary> Build in memory free function</summary>
|
||||
/// <param name="buffer">input buffer</param>
|
||||
internal static void ADL_Main_Memory_Free (IntPtr buffer)
|
||||
{
|
||||
if (IntPtr.Zero != buffer)
|
||||
{
|
||||
Marshal.FreeCoTaskMem(buffer);
|
||||
}
|
||||
}
|
||||
#endregion ADL_Main_Memory_Free
|
||||
|
||||
#region ADL_Main_Control_Create
|
||||
/// <summary> ADL_Main_Control_Create Delegates</summary>
|
||||
internal static ADL_Main_Control_Create ADL_Main_Control_Create
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!ADL_Main_Control_Create_Check && null == ADL_Main_Control_Create_)
|
||||
{
|
||||
ADL_Main_Control_Create_Check = true;
|
||||
if (ADLCheckLibrary.IsFunctionValid("ADL_Main_Control_Create"))
|
||||
{
|
||||
ADL_Main_Control_Create_ = ADLImport.ADL_Main_Control_Create;
|
||||
}
|
||||
}
|
||||
return ADL_Main_Control_Create_;
|
||||
}
|
||||
}
|
||||
/// <summary> Private Delegate</summary>
|
||||
private static ADL_Main_Control_Create ADL_Main_Control_Create_ = null;
|
||||
/// <summary> check flag to indicate the delegate has been checked</summary>
|
||||
private static bool ADL_Main_Control_Create_Check = false;
|
||||
#endregion ADL_Main_Control_Create
|
||||
|
||||
#region ADL_Main_Control_Destroy
|
||||
/// <summary> ADL_Main_Control_Destroy Delegates</summary>
|
||||
internal static ADL_Main_Control_Destroy ADL_Main_Control_Destroy
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!ADL_Main_Control_Destroy_Check && null == ADL_Main_Control_Destroy_)
|
||||
{
|
||||
ADL_Main_Control_Destroy_Check = true;
|
||||
if (ADLCheckLibrary.IsFunctionValid("ADL_Main_Control_Destroy"))
|
||||
{
|
||||
ADL_Main_Control_Destroy_ = ADLImport.ADL_Main_Control_Destroy;
|
||||
}
|
||||
}
|
||||
return ADL_Main_Control_Destroy_;
|
||||
}
|
||||
}
|
||||
/// <summary> Private Delegate</summary>
|
||||
private static ADL_Main_Control_Destroy ADL_Main_Control_Destroy_ = null;
|
||||
/// <summary> check flag to indicate the delegate has been checked</summary>
|
||||
private static bool ADL_Main_Control_Destroy_Check = false;
|
||||
#endregion ADL_Main_Control_Destroy
|
||||
|
||||
#region ADL_Adapter_NumberOfAdapters_Get
|
||||
/// <summary> ADL_Adapter_NumberOfAdapters_Get Delegates</summary>
|
||||
internal static ADL_Adapter_NumberOfAdapters_Get ADL_Adapter_NumberOfAdapters_Get
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!ADL_Adapter_NumberOfAdapters_Get_Check && null == ADL_Adapter_NumberOfAdapters_Get_)
|
||||
{
|
||||
ADL_Adapter_NumberOfAdapters_Get_Check = true;
|
||||
if (ADLCheckLibrary.IsFunctionValid("ADL_Adapter_NumberOfAdapters_Get"))
|
||||
{
|
||||
ADL_Adapter_NumberOfAdapters_Get_ = ADLImport.ADL_Adapter_NumberOfAdapters_Get;
|
||||
}
|
||||
}
|
||||
return ADL_Adapter_NumberOfAdapters_Get_;
|
||||
}
|
||||
}
|
||||
/// <summary> Private Delegate</summary>
|
||||
private static ADL_Adapter_NumberOfAdapters_Get ADL_Adapter_NumberOfAdapters_Get_ = null;
|
||||
/// <summary> check flag to indicate the delegate has been checked</summary>
|
||||
private static bool ADL_Adapter_NumberOfAdapters_Get_Check = false;
|
||||
#endregion ADL_Adapter_NumberOfAdapters_Get
|
||||
|
||||
#region ADL_Adapter_AdapterInfo_Get
|
||||
/// <summary> ADL_Adapter_AdapterInfo_Get Delegates</summary>
|
||||
internal static ADL_Adapter_AdapterInfo_Get ADL_Adapter_AdapterInfo_Get
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!ADL_Adapter_AdapterInfo_Get_Check && null == ADL_Adapter_AdapterInfo_Get_)
|
||||
{
|
||||
ADL_Adapter_AdapterInfo_Get_Check = true;
|
||||
if (ADLCheckLibrary.IsFunctionValid("ADL_Adapter_AdapterInfo_Get"))
|
||||
{
|
||||
ADL_Adapter_AdapterInfo_Get_ = ADLImport.ADL_Adapter_AdapterInfo_Get;
|
||||
}
|
||||
}
|
||||
return ADL_Adapter_AdapterInfo_Get_;
|
||||
}
|
||||
}
|
||||
/// <summary> Private Delegate</summary>
|
||||
private static ADL_Adapter_AdapterInfo_Get ADL_Adapter_AdapterInfo_Get_ = null;
|
||||
/// <summary> check flag to indicate the delegate has been checked</summary>
|
||||
private static bool ADL_Adapter_AdapterInfo_Get_Check = false;
|
||||
#endregion ADL_Adapter_AdapterInfo_Get
|
||||
|
||||
#region ADL_Adapter_Active_Get
|
||||
/// <summary> ADL_Adapter_Active_Get Delegates</summary>
|
||||
internal static ADL_Adapter_Active_Get ADL_Adapter_Active_Get
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!ADL_Adapter_Active_Get_Check && null == ADL_Adapter_Active_Get_)
|
||||
{
|
||||
ADL_Adapter_Active_Get_Check = true;
|
||||
if (ADLCheckLibrary.IsFunctionValid("ADL_Adapter_Active_Get"))
|
||||
{
|
||||
ADL_Adapter_Active_Get_ = ADLImport.ADL_Adapter_Active_Get;
|
||||
}
|
||||
}
|
||||
return ADL_Adapter_Active_Get_;
|
||||
}
|
||||
}
|
||||
/// <summary> Private Delegate</summary>
|
||||
private static ADL_Adapter_Active_Get ADL_Adapter_Active_Get_ = null;
|
||||
/// <summary> check flag to indicate the delegate has been checked</summary>
|
||||
private static bool ADL_Adapter_Active_Get_Check = false;
|
||||
#endregion ADL_Adapter_Active_Get
|
||||
|
||||
#region ADL_Display_DisplayInfo_Get
|
||||
/// <summary> ADL_Display_DisplayInfo_Get Delegates</summary>
|
||||
internal static ADL_Display_DisplayInfo_Get ADL_Display_DisplayInfo_Get
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!ADL_Display_DisplayInfo_Get_Check && null == ADL_Display_DisplayInfo_Get_)
|
||||
{
|
||||
ADL_Display_DisplayInfo_Get_Check = true;
|
||||
if (ADLCheckLibrary.IsFunctionValid("ADL_Display_DisplayInfo_Get"))
|
||||
{
|
||||
ADL_Display_DisplayInfo_Get_ = ADLImport.ADL_Display_DisplayInfo_Get;
|
||||
}
|
||||
}
|
||||
return ADL_Display_DisplayInfo_Get_;
|
||||
}
|
||||
}
|
||||
/// <summary> Private Delegate</summary>
|
||||
private static ADL_Display_DisplayInfo_Get ADL_Display_DisplayInfo_Get_ = null;
|
||||
/// <summary> check flag to indicate the delegate has been checked</summary>
|
||||
private static bool ADL_Display_DisplayInfo_Get_Check = false;
|
||||
#endregion ADL_Display_DisplayInfo_Get
|
||||
|
||||
#region ADL_Display_Size_Get
|
||||
/// <summary> ADL_Display_Size_Get Delegates</summary>
|
||||
internal static ADL_Display_Size_Get ADL_Display_Size_Get
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!ADL_Display_Size_Get_Check && null == ADL_Display_Size_Get)
|
||||
{
|
||||
ADL_Display_Size_Get_Check = true;
|
||||
if (ADLCheckLibrary.IsFunctionValid("ADL_Display_Size_Get"))
|
||||
{
|
||||
ADL_Display_Size_Get_ = ADLImport.ADL_Display_Size_Get;
|
||||
}
|
||||
}
|
||||
return ADL_Display_Size_Get_;
|
||||
}
|
||||
}
|
||||
/// <summary> Private Delegate</summary>
|
||||
private static ADL_Display_Size_Get ADL_Display_Size_Get_ = null;
|
||||
/// <summary> check flag to indicate the delegate has been checked</summary>
|
||||
private static bool ADL_Display_Size_Get_Check = false;
|
||||
#endregion ADL_Display_Size_Get
|
||||
|
||||
#endregion Export Functions
|
||||
}
|
||||
#endregion ADL Class
|
||||
}
|
||||
|
||||
#endregion ATI.ADL
|
||||
@@ -1,170 +0,0 @@
|
||||
using ATI.ADL;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace ColorControl
|
||||
{
|
||||
class ADLWrapper
|
||||
{
|
||||
public static bool Initialize()
|
||||
{
|
||||
int ADLRet = -1;
|
||||
|
||||
if (null != ADL.ADL_Main_Control_Create)
|
||||
{
|
||||
// Second parameter is 1: Get only the present adapters
|
||||
ADLRet = ADL.ADL_Main_Control_Create(ADL.ADL_Main_Memory_Alloc, 1);
|
||||
}
|
||||
return (ADL.ADL_SUCCESS == ADLRet);
|
||||
}
|
||||
|
||||
public static void Uninitialze()
|
||||
{
|
||||
if (null != ADL.ADL_Main_Control_Destroy)
|
||||
{
|
||||
ADL.ADL_Main_Control_Destroy();
|
||||
}
|
||||
}
|
||||
|
||||
public static ADLAdapterInfoArray? GetAdapters()
|
||||
{
|
||||
int ADLRet = -1;
|
||||
int NumberOfAdapters = 0;
|
||||
|
||||
if (null != ADL.ADL_Adapter_NumberOfAdapters_Get)
|
||||
{
|
||||
ADL.ADL_Adapter_NumberOfAdapters_Get(ref NumberOfAdapters);
|
||||
}
|
||||
Console.WriteLine("Number Of Adapters: " + NumberOfAdapters.ToString() + "\n");
|
||||
|
||||
if (NumberOfAdapters > 0)
|
||||
{
|
||||
// Get OS adpater info from ADL
|
||||
ADLAdapterInfoArray OSAdapterInfoData;
|
||||
OSAdapterInfoData = new ADLAdapterInfoArray();
|
||||
|
||||
if (null != ADL.ADL_Adapter_AdapterInfo_Get)
|
||||
{
|
||||
IntPtr AdapterBuffer = IntPtr.Zero;
|
||||
int size = Marshal.SizeOf(OSAdapterInfoData);
|
||||
AdapterBuffer = Marshal.AllocCoTaskMem((int)size);
|
||||
Marshal.StructureToPtr(OSAdapterInfoData, AdapterBuffer, false);
|
||||
|
||||
if (null != ADL.ADL_Adapter_AdapterInfo_Get)
|
||||
{
|
||||
ADLRet = ADL.ADL_Adapter_AdapterInfo_Get(AdapterBuffer, size);
|
||||
if (ADL.ADL_SUCCESS == ADLRet)
|
||||
{
|
||||
OSAdapterInfoData = (ADLAdapterInfoArray)Marshal.PtrToStructure(AdapterBuffer, OSAdapterInfoData.GetType());
|
||||
int IsActive = 0;
|
||||
|
||||
for (int i = 0; i < NumberOfAdapters; i++)
|
||||
{
|
||||
// Check if the adapter is active
|
||||
if (null != ADL.ADL_Adapter_Active_Get)
|
||||
ADLRet = ADL.ADL_Adapter_Active_Get(OSAdapterInfoData.ADLAdapterInfo[i].AdapterIndex, ref IsActive);
|
||||
|
||||
if (ADL.ADL_SUCCESS == ADLRet)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("ADL_Adapter_AdapterInfo_Get() returned error code " + ADLRet.ToString());
|
||||
}
|
||||
}
|
||||
// Release the memory for the AdapterInfo structure
|
||||
if (IntPtr.Zero != AdapterBuffer)
|
||||
{
|
||||
Marshal.FreeCoTaskMem(AdapterBuffer);
|
||||
}
|
||||
}
|
||||
return OSAdapterInfoData;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static List<ADLDisplayInfo> GetAllDisplays()
|
||||
{
|
||||
int ADLRet;
|
||||
int NumberOfDisplays = 0;
|
||||
|
||||
var DisplayInfoData = new List<ADLDisplayInfo>();
|
||||
|
||||
var OSAdapterInfoData = GetAdapters();
|
||||
if (OSAdapterInfoData == null || !OSAdapterInfoData.Value.ADLAdapterInfo.Any())
|
||||
{
|
||||
return DisplayInfoData;
|
||||
}
|
||||
var primaryAdapter = OSAdapterInfoData.Value.ADLAdapterInfo.First();
|
||||
|
||||
ADLDisplayInfo oneDisplayInfo = new ADLDisplayInfo();
|
||||
|
||||
if (null != ADL.ADL_Display_DisplayInfo_Get)
|
||||
{
|
||||
IntPtr DisplayBuffer = IntPtr.Zero;
|
||||
int j = 0;
|
||||
|
||||
// Force the display detection and get the Display Info. Use 0 as last parameter to NOT force detection
|
||||
ADLRet = ADL.ADL_Display_DisplayInfo_Get(primaryAdapter.AdapterIndex, ref NumberOfDisplays, out DisplayBuffer, 1);
|
||||
if (ADL.ADL_SUCCESS == ADLRet)
|
||||
{
|
||||
for (j = 0; j < NumberOfDisplays; j++)
|
||||
{
|
||||
oneDisplayInfo = (ADLDisplayInfo)Marshal.PtrToStructure(new IntPtr(DisplayBuffer.ToInt32() + j * Marshal.SizeOf(oneDisplayInfo)), oneDisplayInfo.GetType());
|
||||
DisplayInfoData.Add(oneDisplayInfo);
|
||||
}
|
||||
Console.WriteLine("\nTotal Number of Displays supported: " + NumberOfDisplays.ToString());
|
||||
Console.WriteLine("\nDispID AdpID Type OutType CnctType Connected Mapped InfoValue DisplayName ");
|
||||
|
||||
for (j = 0; j < NumberOfDisplays; j++)
|
||||
{
|
||||
int InfoValue = DisplayInfoData[j].DisplayInfoValue;
|
||||
string StrConnected = (1 == (InfoValue & 1)) ? "Yes" : "No ";
|
||||
string StrMapped = (2 == (InfoValue & 2)) ? "Yes" : "No ";
|
||||
int AdpID = DisplayInfoData[j].DisplayID.DisplayLogicalAdapterIndex;
|
||||
string StrAdpID = (AdpID < 0) ? "--" : AdpID.ToString("d2");
|
||||
|
||||
Console.WriteLine(DisplayInfoData[j].DisplayID.DisplayLogicalIndex.ToString() + " " +
|
||||
StrAdpID + " " +
|
||||
DisplayInfoData[j].DisplayType.ToString() + " " +
|
||||
DisplayInfoData[j].DisplayOutputType.ToString() + " " +
|
||||
DisplayInfoData[j].DisplayConnector.ToString() + " " +
|
||||
StrConnected + " " +
|
||||
StrMapped + " " +
|
||||
InfoValue.ToString("x4") + " " +
|
||||
DisplayInfoData[j].DisplayName.ToString());
|
||||
}
|
||||
Console.WriteLine();
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("ADL_Display_DisplayInfo_Get() returned error code " + ADLRet.ToString());
|
||||
}
|
||||
// Release the memory for the DisplayInfo structure
|
||||
if (IntPtr.Zero != DisplayBuffer)
|
||||
Marshal.FreeCoTaskMem(DisplayBuffer);
|
||||
}
|
||||
return DisplayInfoData;
|
||||
}
|
||||
|
||||
public static bool GetDisplayResolution(string displayName, ref int horizontal, ref int vertical)
|
||||
{
|
||||
var displays = GetAllDisplays();
|
||||
var display = displays.FirstOrDefault(d => d.DisplayName.Equals(displayName, StringComparison.OrdinalIgnoreCase));
|
||||
if (display.DisplayID.DisplayPhysicalIndex >= 0 && ADL.ADL_Display_Size_Get != null)
|
||||
{
|
||||
int lpDefaultWidth, lpDefaultHeight, lpMinWidth, lpMinHeight, lpMaxWidth, lpMaxHeight, lpStepWidth, lpStepHeight;
|
||||
lpDefaultWidth = lpDefaultHeight = lpMinWidth = lpMinHeight = lpMaxWidth = lpMaxHeight = lpStepWidth = lpStepHeight = 0;
|
||||
var ADLRet = ADL.ADL_Display_Size_Get(display.DisplayID.DisplayPhysicalAdapterIndex, display.DisplayID.DisplayPhysicalIndex, ref horizontal, ref vertical, ref lpDefaultWidth, ref lpDefaultHeight, ref lpMinWidth, ref lpMinHeight, ref lpMaxWidth, ref lpMaxHeight, ref lpStepWidth, ref lpStepHeight);
|
||||
|
||||
return ADLRet == ADL.ADL_SUCCESS;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,186 +0,0 @@
|
||||
using NvAPIWrapper.Display;
|
||||
using NvAPIWrapper.Native.Display;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace ColorControl
|
||||
{
|
||||
class AmdPreset : PresetBase
|
||||
{
|
||||
public bool applyColorData { get; set; }
|
||||
public ColorData colorData { get; set; }
|
||||
public bool applyHDR { get; set; }
|
||||
public bool HDREnabled { get; set; }
|
||||
public bool toggleHDR { get; set; }
|
||||
public bool applyDithering { get; set; }
|
||||
public bool ditheringEnabled { get; set; }
|
||||
public bool applyRefreshRate { get; set; }
|
||||
public uint refreshRate { get; set; }
|
||||
public bool primaryDisplay { get; set; }
|
||||
public string displayName { get; set; }
|
||||
|
||||
public AmdPreset()
|
||||
{
|
||||
applyColorData = true;
|
||||
applyDithering = false;
|
||||
ditheringEnabled = true;
|
||||
applyHDR = false;
|
||||
HDREnabled = false;
|
||||
toggleHDR = false;
|
||||
applyRefreshRate = false;
|
||||
refreshRate = 60;
|
||||
primaryDisplay = true;
|
||||
}
|
||||
|
||||
public AmdPreset(ColorData colorData) : this()
|
||||
{
|
||||
id = GetNewId();
|
||||
this.colorData = colorData;
|
||||
}
|
||||
|
||||
public AmdPreset(AmdPreset preset): this()
|
||||
{
|
||||
id = GetNewId();
|
||||
|
||||
primaryDisplay = preset.primaryDisplay;
|
||||
displayName = preset.displayName;
|
||||
|
||||
var colorData = preset.colorData;
|
||||
this.colorData = new ColorData(colorData.ColorFormat, dynamicRange: colorData.DynamicRange, colorDepth: colorData.ColorDepth, colorSelectionPolicy: colorData.SelectionPolicy);
|
||||
applyColorData = preset.applyColorData;
|
||||
|
||||
applyHDR = preset.applyHDR;
|
||||
HDREnabled = preset.HDREnabled;
|
||||
toggleHDR = preset.toggleHDR;
|
||||
applyDithering = preset.applyDithering;
|
||||
ditheringEnabled = preset.ditheringEnabled;
|
||||
applyRefreshRate = preset.applyRefreshRate;
|
||||
refreshRate = preset.refreshRate;
|
||||
}
|
||||
|
||||
public AmdPreset Clone()
|
||||
{
|
||||
var preset = new AmdPreset(this);
|
||||
|
||||
return preset;
|
||||
}
|
||||
|
||||
public static string[] GetColumnNames()
|
||||
{
|
||||
//return new[] { "BPC", "Format", "Dynamic range", "Toggle HDR", "Shortcut" };
|
||||
return new[] { "Display|140", "Color settings (BPC, format, dyn. range, color space)|260", "Refresh rate|100", "Dithering", "HDR", "Shortcut" };
|
||||
}
|
||||
|
||||
public List<string> GetDisplayValues()
|
||||
{
|
||||
var values = new List<string>();
|
||||
|
||||
var display = string.Format("{0}", primaryDisplay ? "Primary" : displayName);
|
||||
values.Add(display);
|
||||
|
||||
var colorSettings = string.Format("{0}: {1}, {2}, {3}, {4}", applyColorData ? "Included" : "Excluded", colorData.ColorDepth, colorData.ColorFormat, colorData.DynamicRange, colorData.Colorimetry);
|
||||
|
||||
values.Add(colorSettings);
|
||||
values.Add(string.Format("{0}: {1}Hz", applyRefreshRate ? "Included" : "Excluded", refreshRate));
|
||||
values.Add(string.Format("{0}: {1}", applyDithering ? "Included" : "Excluded", ditheringEnabled ? "Enabled" : "Disabled"));
|
||||
values.Add(string.Format("{0}: {1}", applyHDR ? "Included" : "Excluded", toggleHDR ? "Toggle" : HDREnabled ? "Enabled" : "Disabled"));
|
||||
|
||||
//values.Add(colorData.ColorDepth.ToString());
|
||||
//values.Add(colorData.ColorFormat.ToString());
|
||||
//values.Add(colorData.DynamicRange.ToString());
|
||||
//values.Add(toggleHDR.ToString());
|
||||
values.Add(shortcut);
|
||||
|
||||
return values;
|
||||
}
|
||||
|
||||
public static List<AmdPreset> GetDefaultPresets()
|
||||
{
|
||||
var presets = new List<AmdPreset>();
|
||||
|
||||
presets.Add(new AmdPreset(new ColorData(ColorDataFormat.Auto, dynamicRange: ColorDataDynamicRange.Auto, colorDepth: ColorDataDepth.Default, colorSelectionPolicy: ColorDataSelectionPolicy.BestQuality)));
|
||||
|
||||
for (var dynamicRange = ColorDataDynamicRange.VESA; dynamicRange <= ColorDataDynamicRange.CEA; dynamicRange++)
|
||||
{
|
||||
presets.Add(new AmdPreset(new ColorData(ColorDataFormat.RGB, dynamicRange: dynamicRange, colorDepth: ColorDataDepth.BPC8, colorSelectionPolicy: ColorDataSelectionPolicy.User)));
|
||||
presets.Add(new AmdPreset(new ColorData(ColorDataFormat.RGB, dynamicRange: dynamicRange, colorDepth: ColorDataDepth.BPC10, colorSelectionPolicy: ColorDataSelectionPolicy.User)));
|
||||
presets.Add(new AmdPreset(new ColorData(ColorDataFormat.RGB, dynamicRange: dynamicRange, colorDepth: ColorDataDepth.BPC12, colorSelectionPolicy: ColorDataSelectionPolicy.User)));
|
||||
}
|
||||
|
||||
for (var format = ColorDataFormat.YUV422; format <= ColorDataFormat.YUV420; format++)
|
||||
{
|
||||
presets.Add(new AmdPreset(new ColorData(format, dynamicRange: ColorDataDynamicRange.Auto, colorDepth: ColorDataDepth.BPC8, colorSelectionPolicy: ColorDataSelectionPolicy.User)));
|
||||
presets.Add(new AmdPreset(new ColorData(format, dynamicRange: ColorDataDynamicRange.Auto, colorDepth: ColorDataDepth.BPC10, colorSelectionPolicy: ColorDataSelectionPolicy.User)));
|
||||
presets.Add(new AmdPreset(new ColorData(format, dynamicRange: ColorDataDynamicRange.Auto, colorDepth: ColorDataDepth.BPC12, colorSelectionPolicy: ColorDataSelectionPolicy.User)));
|
||||
}
|
||||
|
||||
return presets;
|
||||
}
|
||||
|
||||
public string GetTextForMenuItem()
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
if (displayName != null)
|
||||
{
|
||||
sb.AppendFormat("Display: {0} / ", displayName);
|
||||
}
|
||||
if (applyColorData)
|
||||
{
|
||||
var colorSettings = string.Format("Format: {0}, {1}, {2}", colorData.ColorDepth, colorData.ColorFormat, colorData.DynamicRange);
|
||||
sb.Append(colorSettings);
|
||||
sb.Append(" / ");
|
||||
}
|
||||
if (applyRefreshRate)
|
||||
{
|
||||
sb.AppendFormat("{0}Hz", refreshRate);
|
||||
sb.Append(" / ");
|
||||
}
|
||||
if (applyDithering)
|
||||
{
|
||||
sb.AppendFormat("Dithering: {0}", ditheringEnabled ? "Yes" : "No");
|
||||
sb.Append(" / ");
|
||||
}
|
||||
if (applyHDR)
|
||||
{
|
||||
sb.AppendFormat("HDR: {0}", toggleHDR ? "Toggle" : HDREnabled ? "Enabled" : "Disabled");
|
||||
sb.Append(" / ");
|
||||
}
|
||||
|
||||
return sb.ToString(0, Math.Max(0, sb.Length - 3));
|
||||
}
|
||||
|
||||
public static ColorData GenerateColorData(IDictionary<string, object> dictionary)
|
||||
{
|
||||
var format = ColorDataFormat.RGB;
|
||||
var dynamicRange = ColorDataDynamicRange.VESA;
|
||||
var colorDepth = ColorDataDepth.BPC8;
|
||||
var colorimetry = ColorDataColorimetry.Auto;
|
||||
var selectionPolicy = ColorDataSelectionPolicy.User;
|
||||
object value;
|
||||
if (dictionary.TryGetValue("ColorFormat", out value))
|
||||
{
|
||||
format = (ColorDataFormat)Enum.ToObject(typeof(ColorDataFormat), value);
|
||||
}
|
||||
if (dictionary.TryGetValue("ColorDepth", out value))
|
||||
{
|
||||
colorDepth = (ColorDataDepth)Enum.ToObject(typeof(ColorDataDepth), value);
|
||||
}
|
||||
if (dictionary.TryGetValue("Colorimetry", out value))
|
||||
{
|
||||
colorimetry = (ColorDataColorimetry)Enum.ToObject(typeof(ColorDataColorimetry), value);
|
||||
}
|
||||
if (dictionary.TryGetValue("DynamicRange", out value))
|
||||
{
|
||||
dynamicRange = (ColorDataDynamicRange)Enum.ToObject(typeof(ColorDataDynamicRange), value);
|
||||
}
|
||||
if (dictionary.TryGetValue("SelectionPolicy", out value))
|
||||
{
|
||||
selectionPolicy = (ColorDataSelectionPolicy)Enum.ToObject(typeof(ColorDataSelectionPolicy), value);
|
||||
}
|
||||
return new ColorData(format, dynamicRange: dynamicRange, colorimetry: colorimetry, colorDepth: colorDepth, colorSelectionPolicy: selectionPolicy);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,132 +0,0 @@
|
||||
//using ATI.ADL;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace ColorControl
|
||||
{
|
||||
class AmdService : GraphicsService
|
||||
{
|
||||
private string CurrentDisplay;
|
||||
|
||||
public AmdService()
|
||||
{
|
||||
}
|
||||
|
||||
public void SetCurrentDisplay(AmdPreset preset)
|
||||
{
|
||||
CurrentDisplay = preset.displayName;
|
||||
}
|
||||
|
||||
public string GetCurrentDisplay()
|
||||
{
|
||||
return CurrentDisplay;
|
||||
}
|
||||
|
||||
public bool ApplyPreset(AmdPreset preset, Config config)
|
||||
{
|
||||
SetCurrentDisplay(preset);
|
||||
|
||||
if (preset.applyHDR)
|
||||
{
|
||||
if (preset.toggleHDR || preset.HDREnabled != IsHDREnabled())
|
||||
{
|
||||
ToggleHDR(config.DisplaySettingsDelay);
|
||||
}
|
||||
}
|
||||
|
||||
if (preset.applyRefreshRate)
|
||||
{
|
||||
SetRefreshRate(preset.refreshRate);
|
||||
}
|
||||
|
||||
if (preset.applyColorData)
|
||||
{
|
||||
var display = GetCurrentDisplay();
|
||||
// TODO: ADL call to set color format, depth, space
|
||||
// ADL_Display_PixelFormat_Set
|
||||
// ADL_Display_ColorDepth_Set
|
||||
|
||||
//var data = new ColorData(ColorDataFormat.YUV444, ColorDataColorimetry.YCC709, ColorDataDynamicRange.Auto, ColorDataDepth.BPC8, preset.colorData.SelectionPolicy, ColorDataDesktopDepth.Default);
|
||||
//display.DisplayDevice.SetColorData(preset.colorData);
|
||||
}
|
||||
|
||||
if (preset.applyDithering)
|
||||
{
|
||||
SetDithering(preset.ditheringEnabled);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void SetDithering(bool enabled)
|
||||
{
|
||||
// TODO: ADL call to set dithering state
|
||||
// ADL_Display_DitherState_Get
|
||||
}
|
||||
|
||||
public bool GetDithering()
|
||||
{
|
||||
// TODO: ADL call to get dithering state
|
||||
// ADL_Display_DitherState_Set
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool SetRefreshRate(uint refreshRate)
|
||||
{
|
||||
var portrait = false;
|
||||
var horizontal = 3840;
|
||||
var vertical = 2160;
|
||||
var display = GetCurrentDisplay();
|
||||
|
||||
//ADLWrapper.GetDisplayResolution(display, ref horizontal, ref vertical);
|
||||
|
||||
return SetRefreshRateInternal(display, refreshRate, portrait, horizontal, vertical);
|
||||
}
|
||||
|
||||
public List<uint> GetAvailableRefreshRates(AmdPreset preset = null)
|
||||
{
|
||||
if (preset != null)
|
||||
{
|
||||
SetCurrentDisplay(preset);
|
||||
}
|
||||
|
||||
var portrait = false;
|
||||
var horizontal = 3840;
|
||||
var vertical = 2160;
|
||||
var display = GetCurrentDisplay();
|
||||
|
||||
//ADLWrapper.GetDisplayResolution(display, ref horizontal, ref vertical);
|
||||
|
||||
return GetAvailableRefreshRatesInternal(display, portrait, horizontal, vertical);
|
||||
}
|
||||
|
||||
public bool IsHDREnabled()
|
||||
{
|
||||
// TODO: ADL call to get HDR state
|
||||
//var displayDevice = GetCurrentDisplay().DisplayDevice;
|
||||
//var hdr = displayDevice.HDRColorData;
|
||||
//return hdr?.HDRMode == ColorDataHDRMode.UHDA;
|
||||
return false;
|
||||
}
|
||||
|
||||
public List<string> GetDisplays()
|
||||
{
|
||||
//return ADLWrapper.GetAllDisplays();
|
||||
return null;
|
||||
}
|
||||
|
||||
protected override void Initialize()
|
||||
{
|
||||
//if (!ADLWrapper.Initialize())
|
||||
//{
|
||||
// throw new InvalidOperationException("Cannot load AMD API");
|
||||
//}
|
||||
throw new InvalidOperationException("Cannot load AMD API");
|
||||
}
|
||||
|
||||
protected override void Uninitialize()
|
||||
{
|
||||
//ADLWrapper.Uninitialze();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,317 @@
|
||||
{
|
||||
"$schema": "https://schemastore.azurewebsites.net/schemas/json/sarif-2.1.0-rtm.5.json",
|
||||
"version": "2.1.0",
|
||||
"runs": [
|
||||
{
|
||||
"tool": {
|
||||
"driver": {
|
||||
"name": "Dependency Analysis",
|
||||
"semanticVersion": "0.3.261602",
|
||||
"informationUri": "https://docs.microsoft.com/en-us/dotnet/core/porting/upgrade-assistant-overview",
|
||||
"rules": [
|
||||
{
|
||||
"id": "UA103",
|
||||
"name": "ReferenceToBeDeleted",
|
||||
"fullDescription": {
|
||||
"text": "References that need to be deleted in order to upgrade the project to chosen TFM"
|
||||
},
|
||||
"helpUri": "https://docs.microsoft.com/en-us/dotnet/core/porting/upgrade-assistant-overview"
|
||||
},
|
||||
{
|
||||
"id": "UA106",
|
||||
"name": "PackageToBeAdded",
|
||||
"fullDescription": {
|
||||
"text": "Packages that need to be added in order to upgrade the project to chosen TFM"
|
||||
},
|
||||
"helpUri": "https://docs.microsoft.com/en-us/dotnet/core/porting/upgrade-assistant-overview"
|
||||
},
|
||||
{
|
||||
"id": "UA108",
|
||||
"name": "FrameworkReferenceToBeAdded",
|
||||
"fullDescription": {
|
||||
"text": "Framework Reference that need to be added in order to upgrade the project to chosen TFM"
|
||||
},
|
||||
"helpUri": "https://docs.microsoft.com/en-us/dotnet/core/porting/upgrade-assistant-overview"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"results": [
|
||||
{
|
||||
"ruleId": "UA103",
|
||||
"message": {
|
||||
"text": "Reference to System.Configuration needs to be deleted."
|
||||
},
|
||||
"locations": [
|
||||
{
|
||||
"physicalLocation": {
|
||||
"artifactLocation": {
|
||||
"uri": "file:///C:/Users/vinni/source/repos/ColorControl/ColorControl/ColorControl.csproj"
|
||||
},
|
||||
"region": {}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"ruleId": "UA103",
|
||||
"message": {
|
||||
"text": "Reference to System.ServiceModel needs to be deleted."
|
||||
},
|
||||
"locations": [
|
||||
{
|
||||
"physicalLocation": {
|
||||
"artifactLocation": {
|
||||
"uri": "file:///C:/Users/vinni/source/repos/ColorControl/ColorControl/ColorControl.csproj"
|
||||
},
|
||||
"region": {}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"ruleId": "UA103",
|
||||
"message": {
|
||||
"text": "Reference to System.Web needs to be deleted."
|
||||
},
|
||||
"locations": [
|
||||
{
|
||||
"physicalLocation": {
|
||||
"artifactLocation": {
|
||||
"uri": "file:///C:/Users/vinni/source/repos/ColorControl/ColorControl/ColorControl.csproj"
|
||||
},
|
||||
"region": {}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"ruleId": "UA103",
|
||||
"message": {
|
||||
"text": "Reference to System.Web.Extensions needs to be deleted."
|
||||
},
|
||||
"locations": [
|
||||
{
|
||||
"physicalLocation": {
|
||||
"artifactLocation": {
|
||||
"uri": "file:///C:/Users/vinni/source/repos/ColorControl/ColorControl/ColorControl.csproj"
|
||||
},
|
||||
"region": {}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"ruleId": "UA106",
|
||||
"message": {
|
||||
"text": "Package System.Configuration.ConfigurationManager, Version=5.0.0 needs to be added."
|
||||
},
|
||||
"locations": [
|
||||
{
|
||||
"physicalLocation": {
|
||||
"artifactLocation": {
|
||||
"uri": "file:///C:/Users/vinni/source/repos/ColorControl/ColorControl/ColorControl.csproj"
|
||||
},
|
||||
"region": {}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"ruleId": "UA106",
|
||||
"message": {
|
||||
"text": "Package System.ServiceModel.Primitives, Version=4.8.1 needs to be added."
|
||||
},
|
||||
"locations": [
|
||||
{
|
||||
"physicalLocation": {
|
||||
"artifactLocation": {
|
||||
"uri": "file:///C:/Users/vinni/source/repos/ColorControl/ColorControl/ColorControl.csproj"
|
||||
},
|
||||
"region": {}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"ruleId": "UA106",
|
||||
"message": {
|
||||
"text": "Package System.ServiceModel.Http, Version=4.8.1 needs to be added."
|
||||
},
|
||||
"locations": [
|
||||
{
|
||||
"physicalLocation": {
|
||||
"artifactLocation": {
|
||||
"uri": "file:///C:/Users/vinni/source/repos/ColorControl/ColorControl/ColorControl.csproj"
|
||||
},
|
||||
"region": {}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"ruleId": "UA106",
|
||||
"message": {
|
||||
"text": "Package System.ServiceModel.Duplex, Version=4.8.1 needs to be added."
|
||||
},
|
||||
"locations": [
|
||||
{
|
||||
"physicalLocation": {
|
||||
"artifactLocation": {
|
||||
"uri": "file:///C:/Users/vinni/source/repos/ColorControl/ColorControl/ColorControl.csproj"
|
||||
},
|
||||
"region": {}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"ruleId": "UA106",
|
||||
"message": {
|
||||
"text": "Package System.ServiceModel.NetTcp, Version=4.8.1 needs to be added."
|
||||
},
|
||||
"locations": [
|
||||
{
|
||||
"physicalLocation": {
|
||||
"artifactLocation": {
|
||||
"uri": "file:///C:/Users/vinni/source/repos/ColorControl/ColorControl/ColorControl.csproj"
|
||||
},
|
||||
"region": {}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"ruleId": "UA106",
|
||||
"message": {
|
||||
"text": "Package System.ServiceModel.Security, Version=4.8.1 needs to be added."
|
||||
},
|
||||
"locations": [
|
||||
{
|
||||
"physicalLocation": {
|
||||
"artifactLocation": {
|
||||
"uri": "file:///C:/Users/vinni/source/repos/ColorControl/ColorControl/ColorControl.csproj"
|
||||
},
|
||||
"region": {}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"ruleId": "UA106",
|
||||
"message": {
|
||||
"text": "Package System.ServiceModel.Federation, Version=4.8.1 needs to be added."
|
||||
},
|
||||
"locations": [
|
||||
{
|
||||
"physicalLocation": {
|
||||
"artifactLocation": {
|
||||
"uri": "file:///C:/Users/vinni/source/repos/ColorControl/ColorControl/ColorControl.csproj"
|
||||
},
|
||||
"region": {}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"ruleId": "UA106",
|
||||
"message": {
|
||||
"text": "Package Microsoft.DotNet.UpgradeAssistant.Extensions.Default.Analyzers, Version=0.3.261602 needs to be added."
|
||||
},
|
||||
"locations": [
|
||||
{
|
||||
"physicalLocation": {
|
||||
"artifactLocation": {
|
||||
"uri": "file:///C:/Users/vinni/source/repos/ColorControl/ColorControl/ColorControl.csproj"
|
||||
},
|
||||
"region": {}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"ruleId": "UA106",
|
||||
"message": {
|
||||
"text": "Package Microsoft.Windows.Compatibility, Version=6.0.0 needs to be added."
|
||||
},
|
||||
"locations": [
|
||||
{
|
||||
"physicalLocation": {
|
||||
"artifactLocation": {
|
||||
"uri": "file:///C:/Users/vinni/source/repos/ColorControl/ColorControl/ColorControl.csproj"
|
||||
},
|
||||
"region": {}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"ruleId": "UA108",
|
||||
"message": {
|
||||
"text": "Framework Reference to Microsoft.AspNetCore.App needs to be added."
|
||||
},
|
||||
"locations": [
|
||||
{
|
||||
"physicalLocation": {
|
||||
"artifactLocation": {
|
||||
"uri": "file:///C:/Users/vinni/source/repos/ColorControl/ColorControl/ColorControl.csproj"
|
||||
},
|
||||
"region": {}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"columnKind": "utf16CodeUnits"
|
||||
},
|
||||
{
|
||||
"tool": {
|
||||
"driver": {
|
||||
"name": "API Upgradability",
|
||||
"semanticVersion": "0.3.261602",
|
||||
"informationUri": "https://docs.microsoft.com/en-us/dotnet/core/porting/upgrade-assistant-overview"
|
||||
}
|
||||
},
|
||||
"results": [],
|
||||
"columnKind": "utf16CodeUnits"
|
||||
},
|
||||
{
|
||||
"tool": {
|
||||
"driver": {
|
||||
"name": "Component Analysis",
|
||||
"semanticVersion": "0.3.261602",
|
||||
"informationUri": "https://docs.microsoft.com/en-us/dotnet/core/porting/upgrade-assistant-overview",
|
||||
"rules": [
|
||||
{
|
||||
"id": "UA202",
|
||||
"name": "Microsoft.DotNet.UpgradeAssistant.Extensions.Windows.WinformsDpiSettingUpdater",
|
||||
"fullDescription": {
|
||||
"text": "Winforms Source Updater"
|
||||
},
|
||||
"helpUri": "about:blank"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"results": [
|
||||
{
|
||||
"ruleId": "UA202",
|
||||
"message": {
|
||||
"text": "HighDpiMode needs to set in Main() instead of app.config or app.manifest - Application.SetHighDpiMode(HighDpiMode.<setting>). It is recommended to use SystemAware as the HighDpiMode option for better results."
|
||||
},
|
||||
"locations": [
|
||||
{
|
||||
"physicalLocation": {
|
||||
"artifactLocation": {
|
||||
"uri": "file:///C:/Users/vinni/source/repos/ColorControl/ColorControl/Program.cs"
|
||||
},
|
||||
"region": {}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"columnKind": "utf16CodeUnits"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
<startup>
|
||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" />
|
||||
</startup>
|
||||
<runtime>
|
||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-10.0.0.0" newVersion="10.0.0.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Numerics.Vectors" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.1.4.0" newVersion="4.1.4.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Runtime.CompilerServices.Unsafe" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.0.6.0" newVersion="4.0.6.0" />
|
||||
</dependentAssembly>
|
||||
</assemblyBinding>
|
||||
</runtime>
|
||||
<System.Windows.Forms.ApplicationConfigurationSection>
|
||||
<add key="DpiAwareness" value="PerMonitorV2" />
|
||||
</System.Windows.Forms.ApplicationConfigurationSection>
|
||||
</configuration>
|
||||
+128
-275
@@ -1,276 +1,129 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{A6005D08-70F0-44CB-A384-9219EBA84F21}</ProjectGuid>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<RootNamespace>ColorControl</RootNamespace>
|
||||
<AssemblyName>ColorControl</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
|
||||
<Deterministic>true</Deterministic>
|
||||
<IsWebBootstrapper>false</IsWebBootstrapper>
|
||||
<PublishUrl>publish\</PublishUrl>
|
||||
<Install>true</Install>
|
||||
<InstallFrom>Disk</InstallFrom>
|
||||
<UpdateEnabled>false</UpdateEnabled>
|
||||
<UpdateMode>Foreground</UpdateMode>
|
||||
<UpdateInterval>7</UpdateInterval>
|
||||
<UpdateIntervalUnits>Days</UpdateIntervalUnits>
|
||||
<UpdatePeriodically>false</UpdatePeriodically>
|
||||
<UpdateRequired>false</UpdateRequired>
|
||||
<MapFileExtensions>false</MapFileExtensions>
|
||||
<UpdateUrl>https://www.maassoft.com/downloads/ColorControl/</UpdateUrl>
|
||||
<ProductName>ColorControl</ProductName>
|
||||
<PublisherName>Maassoft</PublisherName>
|
||||
<ApplicationRevision>0</ApplicationRevision>
|
||||
<ApplicationVersion>1.3.6.0</ApplicationVersion>
|
||||
<UseApplicationTrust>false</UseApplicationTrust>
|
||||
<PublishWizardCompleted>true</PublishWizardCompleted>
|
||||
<BootstrapperEnabled>true</BootstrapperEnabled>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<OutputPath>bin\x64\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<DebugType>full</DebugType>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<LangVersion>7.3</LangVersion>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
<Prefer32Bit>true</Prefer32Bit>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
|
||||
<OutputPath>bin\x64\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<Optimize>true</Optimize>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<LangVersion>7.3</LangVersion>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
<Prefer32Bit>true</Prefer32Bit>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<ManifestCertificateThumbprint>482C987E8C69872608C9D44751E004C5784E8540</ManifestCertificateThumbprint>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<ManifestKeyFile>ColorControl_TemporaryKey.pfx</ManifestKeyFile>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<GenerateManifests>true</GenerateManifests>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<TargetZone>LocalIntranet</TargetZone>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<ApplicationManifest>Properties\app.manifest</ApplicationManifest>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<SignManifests>true</SignManifests>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<SignAssembly>false</SignAssembly>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<AssemblyOriginatorKeyFile>ColorControl_TemporaryKey.pfx</AssemblyOriginatorKeyFile>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<ApplicationIcon>pngbarn.ico</ApplicationIcon>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Microsoft.Win32.TaskScheduler, Version=2.8.20.0, Culture=neutral, PublicKeyToken=c416bc1b32d97233, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\TaskScheduler.2.8.20\lib\net452\Microsoft.Win32.TaskScheduler.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Native, Version=0.1.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Native.0.1.0\lib\net35\Native.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Newtonsoft.Json, Version=12.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Newtonsoft.Json.12.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="NLog, Version=4.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\NLog.4.7.2\lib\net45\NLog.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="NStandard, Version=0.4.3.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\NStandard.0.4.3\lib\net46\NStandard.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="NvAPIWrapper, Version=0.8.0.98, Culture=neutral, PublicKeyToken=310fd07b25df79b3, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\NvAPIWrapper.Net.0.8.0.98\lib\net45\NvAPIWrapper.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="NWin32, Version=1.0.6.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\NWin32.1.0.6\lib\net46\NWin32.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="PacketDotNet, Version=1.0.5.0, Culture=neutral, PublicKeyToken=451414c7667b2a58, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\PacketDotNet.1.0.5\lib\net45\PacketDotNet.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="PresentationCore" />
|
||||
<Reference Include="SharpPcap, Version=5.2.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\SharpPcap.5.2.0\lib\netstandard2.0\SharpPcap.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Buffers, Version=4.0.3.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Buffers.4.5.1\lib\net461\System.Buffers.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Configuration" />
|
||||
<Reference Include="System.Configuration.Install" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.IO.Compression" />
|
||||
<Reference Include="System.Memory, Version=4.0.1.1, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Memory.4.5.4\lib\net461\System.Memory.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Numerics" />
|
||||
<Reference Include="System.Numerics.Vectors, Version=4.1.4.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Numerics.Vectors.4.5.0\lib\net46\System.Numerics.Vectors.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Runtime.CompilerServices.Unsafe, Version=4.0.6.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Runtime.CompilerServices.Unsafe.4.7.0\lib\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Runtime.Serialization" />
|
||||
<Reference Include="System.Runtime.WindowsRuntime, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\..\..\..\..\..\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETCore\v4.5\System.Runtime.WindowsRuntime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.ServiceModel" />
|
||||
<Reference Include="System.ServiceProcess" />
|
||||
<Reference Include="System.Transactions" />
|
||||
<Reference Include="System.Web" />
|
||||
<Reference Include="System.Web.Extensions" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Deployment" />
|
||||
<Reference Include="System.Drawing" />
|
||||
<Reference Include="System.Net.Http" />
|
||||
<Reference Include="System.Windows.Forms" />
|
||||
<Reference Include="System.Xml" />
|
||||
<Reference Include="Windows">
|
||||
<HintPath>..\..\..\..\..\..\Program Files (x86)\Windows Kits\10\UnionMetadata\10.0.18362.0\Windows.winmd</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="WindowsBase" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="GraphicsService.cs" />
|
||||
<Compile Include="AmdService.cs" />
|
||||
<Compile Include="AmdPreset.cs" />
|
||||
<Compile Include="StartUpParams.cs" />
|
||||
<Compile Include="LgServiceConfig.cs" />
|
||||
<Compile Include="WOL.cs" />
|
||||
<Compile Include="RestartDetector.cs" />
|
||||
<Compile Include="ExceptionExtensions.cs" />
|
||||
<Compile Include="lgtv\App.cs" />
|
||||
<Compile Include="lgtv\Channel.cs" />
|
||||
<Compile Include="lgtv\ClientKeyStore.cs" />
|
||||
<Compile Include="lgtv\ExternalInput.cs" />
|
||||
<Compile Include="lgtv\IsConnectedDelegate.cs" />
|
||||
<Compile Include="lgtv\LgTvApi.cs" />
|
||||
<Compile Include="lgtv\LgTvConnection.cs" />
|
||||
<Compile Include="lgtv\LgWebOsMouseService.cs" />
|
||||
<Compile Include="lgtv\MessageType.cs" />
|
||||
<Compile Include="lgtv\RawRequestMessage.cs" />
|
||||
<Compile Include="lgtv\RequestMessage.cs" />
|
||||
<Compile Include="PnpDev.cs" />
|
||||
<Compile Include="TreeNodeBuilder.cs" />
|
||||
<Compile Include="ColorDataConverter.cs" />
|
||||
<Compile Include="Config.cs" />
|
||||
<Compile Include="lgtv\LgApp.cs" />
|
||||
<Compile Include="PresetBase.cs" />
|
||||
<Compile Include="LgPreset.cs" />
|
||||
<Compile Include="NvPreset.cs" />
|
||||
<Compile Include="LgService.cs" />
|
||||
<Compile Include="NvService.cs" />
|
||||
<Compile Include="ScreenInterrogatory.cs" />
|
||||
<Compile Include="Utils.cs" />
|
||||
<Compile Include="MainForm.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="MainForm.Designer.cs">
|
||||
<DependentUpon>MainForm.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Program.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<EmbeddedResource Include="MainForm.resx">
|
||||
<DependentUpon>MainForm.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Properties\Resources.resx">
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
|
||||
<SubType>Designer</SubType>
|
||||
</EmbeddedResource>
|
||||
<Compile Include="Properties\Resources.Designer.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>Resources.resx</DependentUpon>
|
||||
</Compile>
|
||||
<None Include="ColorControl_TemporaryKey.pfx" />
|
||||
<Content Include="LgPresets.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<None Include="lgtv\README.md" />
|
||||
<None Include="packages.config" />
|
||||
<None Include="Properties\app.manifest" />
|
||||
<None Include="Properties\Settings.settings">
|
||||
<Generator>SettingsSingleFileGenerator</Generator>
|
||||
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
|
||||
</None>
|
||||
<Compile Include="Properties\Settings.Designer.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>Settings.settings</DependentUpon>
|
||||
<DesignTimeSharedInput>True</DesignTimeSharedInput>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="App.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<BootstrapperPackage Include=".NETFramework,Version=v4.7.2">
|
||||
<Visible>False</Visible>
|
||||
<ProductName>Microsoft .NET Framework 4.7.2 %28x86 and x64%29</ProductName>
|
||||
<Install>true</Install>
|
||||
</BootstrapperPackage>
|
||||
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
|
||||
<Visible>False</Visible>
|
||||
<ProductName>.NET Framework 3.5 SP1</ProductName>
|
||||
<Install>false</Install>
|
||||
</BootstrapperPackage>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="pngbarn.ico" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Folder Include="bin\x64\Debug\" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<COMReference Include="IWshRuntimeLibrary">
|
||||
<Guid>{F935DC20-1CF0-11D0-ADB9-00C04FD58A0B}</Guid>
|
||||
<VersionMajor>1</VersionMajor>
|
||||
<VersionMinor>0</VersionMinor>
|
||||
<Lcid>0</Lcid>
|
||||
<WrapperTool>tlbimp</WrapperTool>
|
||||
<Isolated>False</Isolated>
|
||||
<EmbedInteropTypes>True</EmbedInteropTypes>
|
||||
</COMReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net7.0-windows10.0.20348.0</TargetFramework>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<IsWebBootstrapper>false</IsWebBootstrapper>
|
||||
<PublishUrl>publish\</PublishUrl>
|
||||
<Install>true</Install>
|
||||
<InstallFrom>Disk</InstallFrom>
|
||||
<UpdateEnabled>false</UpdateEnabled>
|
||||
<UpdateMode>Foreground</UpdateMode>
|
||||
<UpdateInterval>7</UpdateInterval>
|
||||
<UpdateIntervalUnits>Days</UpdateIntervalUnits>
|
||||
<UpdatePeriodically>false</UpdatePeriodically>
|
||||
<UpdateRequired>false</UpdateRequired>
|
||||
<MapFileExtensions>false</MapFileExtensions>
|
||||
<UpdateUrl>https://www.maassoft.com/downloads/ColorControl/</UpdateUrl>
|
||||
<ProductName>ColorControl</ProductName>
|
||||
<PublisherName>Maassoft</PublisherName>
|
||||
<Company>Maassoft</Company>
|
||||
<ApplicationRevision>0</ApplicationRevision>
|
||||
<ApplicationVersion>9.7.1.0</ApplicationVersion>
|
||||
<Version>9.7.1.0</Version>
|
||||
<UseApplicationTrust>false</UseApplicationTrust>
|
||||
<PublishWizardCompleted>true</PublishWizardCompleted>
|
||||
<BootstrapperEnabled>false</BootstrapperEnabled>
|
||||
<GenerateAssemblyInfo>true</GenerateAssemblyInfo>
|
||||
<UseWindowsForms>true</UseWindowsForms>
|
||||
<UseWPF>false</UseWPF>
|
||||
<ImportWindowsDesktopTargets>true</ImportWindowsDesktopTargets>
|
||||
<ApplicationIcon>pngbarn.ico</ApplicationIcon>
|
||||
<SupportedOSPlatformVersion>10.0.20348.0</SupportedOSPlatformVersion>
|
||||
<Copyright>2020-2023 Maassoft</Copyright>
|
||||
<Authors>Maassoft</Authors>
|
||||
<ManifestCertificateThumbprint>CF0BC153EA664CD97AC6F234B91F45D34630958F</ManifestCertificateThumbprint>
|
||||
<ManifestKeyFile>ColorControl_1_TemporaryKey.pfx</ManifestKeyFile>
|
||||
<GenerateManifests>true</GenerateManifests>
|
||||
<TargetZone>LocalIntranet</TargetZone>
|
||||
<ApplicationManifest>Properties\app.manifest</ApplicationManifest>
|
||||
<SignManifests>true</SignManifests>
|
||||
<AssemblyOriginatorKeyFile>ColorControl_TemporaryKey.pfx</AssemblyOriginatorKeyFile>
|
||||
<IncludeSourceRevisionInInformationalVersion>false</IncludeSourceRevisionInInformationalVersion>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
|
||||
<OutputPath>bin\x64\Debug\</OutputPath>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
|
||||
<OutputPath>bin\x64\Release\</OutputPath>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<PathMap Condition="'$(Configuration)' == 'Release'">$(MSBuildThisFileDirectory)=.\</PathMap>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<None Remove="XForms\LogWindow.xaml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Update="Forms\ElevatedForm.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Update="Services\Common\QuickAccessForm.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Update="services\lg\RemoteControlPanel.cs">
|
||||
<SubType>UserControl</SubType>
|
||||
</Compile>
|
||||
<Compile Update="Services\NVIDIA\NvInfoPanel.cs">
|
||||
<SubType>UserControl</SubType>
|
||||
</Compile>
|
||||
<Compile Update="Services\NVIDIA\NvPanel.cs" />
|
||||
<Compile Update="Services\Samsung\SamsungPanel.cs">
|
||||
<SubType>UserControl</SubType>
|
||||
</Compile>
|
||||
<EmbeddedResource Include="Resources\LG_register.json" />
|
||||
<EmbeddedResource Include="Resources\RC_coords.txt" />
|
||||
<EmbeddedResource Include="Resources\LG_remote.jpg" />
|
||||
<Content Include="LgPresets.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="pngbarn.ico" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Folder Include="bin\x64\Debug\" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<COMReference Include="IWshRuntimeLibrary">
|
||||
<Guid>{F935DC20-1CF0-11D0-ADB9-00C04FD58A0B}</Guid>
|
||||
<VersionMajor>1</VersionMajor>
|
||||
<VersionMinor>0</VersionMinor>
|
||||
<Lcid>0</Lcid>
|
||||
<WrapperTool>tlbimp</WrapperTool>
|
||||
<Isolated>False</Isolated>
|
||||
<EmbedInteropTypes>True</EmbedInteropTypes>
|
||||
</COMReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.CSharp" Version="4.7.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Hosting.WindowsServices" Version="7.0.0" />
|
||||
<PackageReference Include="Microsoft.Web.WebView2" Version="1.0.2088.41" />
|
||||
<PackageReference Include="System.Configuration.ConfigurationManager" Version="7.0.0" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||
<PackageReference Include="NLog" Version="5.1.2" />
|
||||
<PackageReference Include="NStandard" Version="0.24.0" />
|
||||
<PackageReference Include="NWin32" Version="1.2.6" />
|
||||
<PackageReference Include="System.Management" Version="7.0.0" />
|
||||
<PackageReference Include="TaskScheduler" Version="2.10.1" />
|
||||
<PackageReference Include="Vanara.PInvoke.IpHlpApi" Version="3.4.13" />
|
||||
<PackageReference Include="RawInput.Sharp" Version="0.1.1" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Page Include="XForms\LogWindow.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\NLogViewer\NLogViewer.csproj" />
|
||||
<ProjectReference Include="..\novideo_srgb\novideo_srgb.csproj" />
|
||||
<ProjectReference Include="..\Nspector\Nspector.csproj" />
|
||||
<ProjectReference Include="..\NvAPIWrapper\NvAPIWrapper.csproj" />
|
||||
<ProjectReference Include="..\Shared\Shared.csproj" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Update="Services\Samsung\SamsungPanel.resx">
|
||||
<SubType>Designer</SubType>
|
||||
</EmbeddedResource>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -1,54 +0,0 @@
|
||||
using NvAPIWrapper.Display;
|
||||
using NvAPIWrapper.Native.Display;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Web.Script.Serialization;
|
||||
|
||||
namespace ColorControl
|
||||
{
|
||||
public class ColorDataConverter : JavaScriptConverter
|
||||
{
|
||||
public override IEnumerable<Type> SupportedTypes
|
||||
{
|
||||
get { return new List<Type>() { typeof(ColorData) }; }
|
||||
}
|
||||
|
||||
public override IDictionary<string, object> Serialize(object obj, JavaScriptSerializer serializer)
|
||||
{
|
||||
Dictionary<string, object> result = new Dictionary<string, object>();
|
||||
if (obj == null) return result;
|
||||
return result;
|
||||
}
|
||||
|
||||
public override object Deserialize(IDictionary<string, object> dictionary, Type type, JavaScriptSerializer serializer)
|
||||
{
|
||||
var format = ColorDataFormat.RGB;
|
||||
var dynamicRange = ColorDataDynamicRange.VESA;
|
||||
var colorDepth = ColorDataDepth.BPC8;
|
||||
var colorimetry = ColorDataColorimetry.Auto;
|
||||
var selectionPolicy = ColorDataSelectionPolicy.User;
|
||||
object value;
|
||||
if (dictionary.TryGetValue("ColorFormat", out value))
|
||||
{
|
||||
format = (ColorDataFormat)Enum.ToObject(typeof(ColorDataFormat), value);
|
||||
}
|
||||
if (dictionary.TryGetValue("ColorDepth", out value))
|
||||
{
|
||||
colorDepth = (ColorDataDepth)Enum.ToObject(typeof(ColorDataDepth), value);
|
||||
}
|
||||
if (dictionary.TryGetValue("Colorimetry", out value))
|
||||
{
|
||||
colorimetry = (ColorDataColorimetry)Enum.ToObject(typeof(ColorDataColorimetry), value);
|
||||
}
|
||||
if (dictionary.TryGetValue("DynamicRange", out value))
|
||||
{
|
||||
dynamicRange = (ColorDataDynamicRange)Enum.ToObject(typeof(ColorDataDynamicRange), value);
|
||||
}
|
||||
if (dictionary.TryGetValue("SelectionPolicy", out value))
|
||||
{
|
||||
selectionPolicy = (ColorDataSelectionPolicy)Enum.ToObject(typeof(ColorDataSelectionPolicy), value);
|
||||
}
|
||||
return new ColorData(format, dynamicRange: dynamicRange, colorimetry: colorimetry, colorDepth: colorDepth, colorSelectionPolicy: selectionPolicy, desktopColorDepth: ColorDataDesktopDepth.Default);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,122 @@
|
||||
using ColorControl.Forms;
|
||||
using ColorControl.Services.AMD;
|
||||
using ColorControl.Services.LG;
|
||||
using ColorControl.Services.NVIDIA;
|
||||
using ColorControl.Services.Samsung;
|
||||
using ColorControl.Shared.Common;
|
||||
using ColorControl.Shared.Contracts;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace ColorControl
|
||||
{
|
||||
public static class CommandLineHandler
|
||||
{
|
||||
public static async Task<bool> HandleStartupParams(StartUpParams startUpParams, Process existingProcess)
|
||||
{
|
||||
if (startUpParams.StartElevated)
|
||||
{
|
||||
StartElevated();
|
||||
return true;
|
||||
}
|
||||
|
||||
var useConsole = startUpParams.NoGui || existingProcess != null;
|
||||
|
||||
if (!useConsole)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
startUpParams.NoGui = true;
|
||||
|
||||
var result = false;
|
||||
|
||||
if (startUpParams.ExecuteHelp)
|
||||
{
|
||||
Utils.OpenConsole();
|
||||
|
||||
Console.WriteLine();
|
||||
Console.WriteLine($@"ColorControl CLI {Application.ProductVersion}
|
||||
Syntax : ColorControl command options
|
||||
Commands:
|
||||
--nvpreset <preset name or id>: execute NVIDIA-preset
|
||||
--amdpreset <preset name or id>: execute AMD-preset
|
||||
--lgpreset <preset name> : execute LG-preset
|
||||
--sampreset <preset name> : execute Samsung-preset
|
||||
--help : displays this help info
|
||||
Options:
|
||||
--nogui : starts command from the command line and will not open GUI (is forced when GUI is already running)
|
||||
--no-refresh: when using LG or Samsung-preset: skip refreshing devices (speeds up executing preset)");
|
||||
|
||||
result = true;
|
||||
}
|
||||
|
||||
if (startUpParams.ExecuteLgPreset)
|
||||
{
|
||||
Utils.OpenConsole();
|
||||
|
||||
Console.WriteLine($"Executing LG-preset '{startUpParams.LgPresetName}'...");
|
||||
await LgService.ExecutePresetAsync(startUpParams.LgPresetName);
|
||||
|
||||
Console.WriteLine("Done.");
|
||||
|
||||
result = true;
|
||||
}
|
||||
|
||||
if (startUpParams.ExecuteSamsungPreset)
|
||||
{
|
||||
Utils.OpenConsole();
|
||||
|
||||
Console.WriteLine($"Executing Samsung-preset '{startUpParams.SamsungPresetName}'...");
|
||||
await SamsungService.ExecutePresetAsync(startUpParams.SamsungPresetName);
|
||||
|
||||
Console.WriteLine("Done.");
|
||||
|
||||
result = true;
|
||||
}
|
||||
|
||||
if (startUpParams.ExecuteNvidiaPreset)
|
||||
{
|
||||
Utils.OpenConsole();
|
||||
|
||||
Console.WriteLine($"Executing NVIDIA-preset '{startUpParams.NvidiaPresetIdOrName}'...");
|
||||
await NvService.ExecutePresetAsync(startUpParams.NvidiaPresetIdOrName);
|
||||
|
||||
Console.WriteLine("Done.");
|
||||
|
||||
result = true;
|
||||
}
|
||||
|
||||
if (startUpParams.ExecuteAmdPreset)
|
||||
{
|
||||
Utils.OpenConsole();
|
||||
|
||||
Console.WriteLine($"Executing AMD-preset '{startUpParams.AmdPresetIdOrName}'...");
|
||||
await AmdService.ExecutePresetAsync(startUpParams.AmdPresetIdOrName);
|
||||
|
||||
Console.WriteLine("Done.");
|
||||
|
||||
result = true;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static void StartElevated()
|
||||
{
|
||||
try
|
||||
{
|
||||
var elevatedForm = Program.ServiceProvider.GetRequiredService<ElevatedForm>();
|
||||
|
||||
Application.Run(elevatedForm);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MessageBox.Show("Error while initializing elevated application: " + ex.ToLogString(Environment.StackTrace), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
namespace ColorControl
|
||||
{
|
||||
class Config
|
||||
{
|
||||
public bool StartMinimized { get; set; }
|
||||
|
||||
public bool MinimizeOnClose { get; set; }
|
||||
|
||||
public int DisplaySettingsDelay { get; set; }
|
||||
|
||||
public string ScreenSaverShortcut { get; set; }
|
||||
|
||||
public int FormWidth { get; set; }
|
||||
public int FormHeight { get; set; }
|
||||
|
||||
public Config()
|
||||
{
|
||||
DisplaySettingsDelay = 1000;
|
||||
ScreenSaverShortcut = string.Empty;
|
||||
FormWidth = 900;
|
||||
FormHeight = 600;
|
||||
}
|
||||
}
|
||||
}
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
namespace ColorControl.Forms
|
||||
{
|
||||
partial class ElevatedForm
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Windows Form Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// ElevatedForm
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.ClientSize = new System.Drawing.Size(251, 124);
|
||||
this.Name = "ElevatedForm";
|
||||
this.Text = "ElevatedForm";
|
||||
this.ResumeLayout(false);
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
using ColorControl.Svc;
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace ColorControl.Forms;
|
||||
|
||||
public partial class ElevatedForm : Form
|
||||
{
|
||||
private ColorControlBackgroundService _backgroundService;
|
||||
|
||||
public ElevatedForm(ColorControlBackgroundService backgroundService)
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
FormBorderStyle = FormBorderStyle.None;
|
||||
ShowInTaskbar = false;
|
||||
Load += ElevatedForm_Load;
|
||||
Shown += ElevatedForm_Shown;
|
||||
|
||||
Task.Run(CheckMutexAsync);
|
||||
|
||||
_backgroundService = backgroundService;
|
||||
_backgroundService.PipeName = "elevatedpipe";
|
||||
|
||||
Task.Run(async () => await _backgroundService.StartAsync(CancellationToken.None));
|
||||
}
|
||||
|
||||
private void ElevatedForm_Shown(object sender, EventArgs e)
|
||||
{
|
||||
Hide();
|
||||
}
|
||||
|
||||
protected void ElevatedForm_Load(object sender, EventArgs e)
|
||||
{
|
||||
Size = new Size(0, 0);
|
||||
}
|
||||
|
||||
private void CheckMutexAsync()
|
||||
{
|
||||
var mutex = new Mutex(false, Shared.Common.GlobalContext.CurrentContext.MutexId, out var created);
|
||||
try
|
||||
{
|
||||
mutex.WaitOne();
|
||||
}
|
||||
catch (AbandonedMutexException)
|
||||
{
|
||||
}
|
||||
BeginInvoke(Application.Exit);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
<root>
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
</root>
|
||||
@@ -0,0 +1,7 @@
|
||||
namespace ColorControl
|
||||
{
|
||||
internal interface IModulePanel
|
||||
{
|
||||
public void UpdateInfo();
|
||||
}
|
||||
}
|
||||
@@ -1,70 +0,0 @@
|
||||
using LgTv;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace ColorControl
|
||||
{
|
||||
class LgPreset : PresetBase
|
||||
{
|
||||
public string name { get; set; }
|
||||
public string appId { get; set; }
|
||||
public List<string> steps { get; set; }
|
||||
|
||||
public static List<LgApp> LgApps { get; set; }
|
||||
|
||||
public LgPreset()
|
||||
{
|
||||
steps = new List<string>();
|
||||
}
|
||||
|
||||
public LgPreset(LgPreset preset) : this()
|
||||
{
|
||||
id = GetNewId();
|
||||
name = preset.name + " (copy)";
|
||||
appId = preset.appId;
|
||||
|
||||
foreach (var step in preset.steps)
|
||||
{
|
||||
steps.Add(step);
|
||||
}
|
||||
}
|
||||
|
||||
public LgPreset Clone()
|
||||
{
|
||||
var preset = new LgPreset(this);
|
||||
|
||||
return preset;
|
||||
}
|
||||
|
||||
public static List<string> GetColumnNames()
|
||||
{
|
||||
return new List<string>() { "Name", "App|200", "Steps|400", "Shortcut" };
|
||||
}
|
||||
|
||||
public List<string> GetDisplayValues()
|
||||
{
|
||||
var values = new List<string>();
|
||||
|
||||
values.Add(name);
|
||||
var app = appId;
|
||||
if (LgApps != null)
|
||||
{
|
||||
var item = LgApps.FirstOrDefault(x => x.appId.Equals(appId));
|
||||
if (item != null)
|
||||
{
|
||||
app = item.title + " (" + appId + ")";
|
||||
}
|
||||
}
|
||||
values.Add(app);
|
||||
values.Add(GetStepsDisplay());
|
||||
values.Add(shortcut);
|
||||
|
||||
return values;
|
||||
}
|
||||
|
||||
public string GetStepsDisplay()
|
||||
{
|
||||
return steps.Aggregate("", (a, b) => (string.IsNullOrEmpty(a) ? "" : a + ", ") + b);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,337 +0,0 @@
|
||||
using LgTv;
|
||||
using Newtonsoft.Json;
|
||||
using NLog.Config;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
using Windows.Data.Json;
|
||||
|
||||
namespace ColorControl
|
||||
{
|
||||
class LgService
|
||||
{
|
||||
public static string LgListAppsJson = "listApps.json";
|
||||
|
||||
private static readonly NLog.Logger Logger = NLog.LogManager.GetCurrentClassLogger();
|
||||
|
||||
public string FriendlyScreenName { get; private set; }
|
||||
|
||||
public List<PnpDev> Devices { get; private set; }
|
||||
public PnpDev SelectedDevice
|
||||
{
|
||||
get { return _selectedDevice; }
|
||||
set
|
||||
{
|
||||
_selectedDevice = value;
|
||||
Config.PreferredMacAddress = _selectedDevice != null ? _selectedDevice.MacAddress : null;
|
||||
}
|
||||
}
|
||||
|
||||
public LgServiceConfig Config { get; private set; }
|
||||
|
||||
private LgTvApi _lgTvApi;
|
||||
private string _dataDir;
|
||||
private string _configFilename;
|
||||
private bool _allowPowerOn;
|
||||
private bool _justWokeUp;
|
||||
private PnpDev _selectedDevice;
|
||||
|
||||
public LgService(string dataDir, bool allowPowerOn)
|
||||
{
|
||||
_dataDir = dataDir;
|
||||
_allowPowerOn = allowPowerOn;
|
||||
LoadConfig();
|
||||
|
||||
foreach (var screen in Screen.AllScreens)
|
||||
{
|
||||
var name = screen.DeviceFriendlyName();
|
||||
if (name.Contains("LG"))
|
||||
{
|
||||
FriendlyScreenName = name;
|
||||
}
|
||||
}
|
||||
|
||||
RefreshDevices();
|
||||
}
|
||||
|
||||
~LgService()
|
||||
{
|
||||
SaveConfig();
|
||||
}
|
||||
|
||||
private void LoadConfig()
|
||||
{
|
||||
_configFilename = Path.Combine(_dataDir, "LgConfig.json");
|
||||
if (File.Exists(_configFilename))
|
||||
{
|
||||
Config = JsonConvert.DeserializeObject<LgServiceConfig>(File.ReadAllText(_configFilename));
|
||||
}
|
||||
else
|
||||
{
|
||||
Config = new LgServiceConfig();
|
||||
}
|
||||
}
|
||||
|
||||
public void SaveConfig()
|
||||
{
|
||||
var json = JsonConvert.SerializeObject(Config);
|
||||
File.WriteAllText(_configFilename, json);
|
||||
}
|
||||
|
||||
public async Task RefreshDevices(bool connect = true)
|
||||
{
|
||||
var devices = await Utils.GetPnpDevices(Config.DeviceSearchKey);
|
||||
SetDevices(devices);
|
||||
if (connect && SelectedDevice != null)
|
||||
{
|
||||
if (Config.PowerOnAfterStartup && _allowPowerOn)
|
||||
{
|
||||
WakeAndConnectToSelectedDevice(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
ConnectToSelectedDevice();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void SetDevices(List<PnpDev> devices)
|
||||
{
|
||||
Devices = devices;
|
||||
if (Devices?.Count > 0)
|
||||
{
|
||||
var preferredDevice = Devices.FirstOrDefault(x => x.MacAddress != null && x.MacAddress.Equals(Config.PreferredMacAddress)) ?? Devices[0];
|
||||
|
||||
SelectedDevice = preferredDevice;
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<bool> ConnectToSelectedDevice(int retries = 3)
|
||||
{
|
||||
try
|
||||
{
|
||||
DisposeConnection();
|
||||
_lgTvApi = await LgTvApi.CreateLgTvApi(SelectedDevice.IpAddress, retries);
|
||||
return _lgTvApi != null;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
string logMessage = ex.ToLogString(Environment.StackTrace);
|
||||
Logger.Error($"Error while connecting to {SelectedDevice.IpAddress}: {logMessage}");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<bool> Connected(bool reconnect = false)
|
||||
{
|
||||
if (SelectedDevice == null)
|
||||
{
|
||||
Logger.Debug("Cannot apply LG-preset: no device has been selected");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (reconnect || _lgTvApi == null || _lgTvApi.ConnectionClosed || !string.Equals(_lgTvApi.GetIpAddress(), SelectedDevice.IpAddress))
|
||||
{
|
||||
if (!await ConnectToSelectedDevice())
|
||||
{
|
||||
Logger.Debug("Cannot apply LG-preset: no connection could be made");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
public async Task<bool> ApplyPreset(LgPreset preset, bool reconnect = false)
|
||||
{
|
||||
var hasApp = !string.IsNullOrEmpty(preset.appId);
|
||||
|
||||
for (var tries = 0; tries <= 1; tries++)
|
||||
{
|
||||
if (!await Connected(reconnect || tries == 1))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (hasApp)
|
||||
{
|
||||
try
|
||||
{
|
||||
await _lgTvApi.LaunchApp(preset.appId);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
string logMessage = ex.ToLogString(Environment.StackTrace);
|
||||
Logger.Error("Error while launching app: " + logMessage);
|
||||
|
||||
if (tries == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (_justWokeUp)
|
||||
{
|
||||
_justWokeUp = false;
|
||||
await Task.Delay(1000);
|
||||
}
|
||||
}
|
||||
|
||||
if (preset.steps.Any())
|
||||
{
|
||||
if (hasApp)
|
||||
{
|
||||
await Task.Delay(1500);
|
||||
}
|
||||
try
|
||||
{
|
||||
await ExecuteSteps(_lgTvApi, preset);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
string logMessage = ex.ToLogString(Environment.StackTrace);
|
||||
Logger.Error("Error while executing steps: " + logMessage);
|
||||
|
||||
if (tries == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public async Task PowerOn()
|
||||
{
|
||||
var mouse = await _lgTvApi.GetMouse();
|
||||
mouse.SendButton(ButtonType.POWER);
|
||||
}
|
||||
|
||||
private async Task ExecuteSteps(LgTvApi api, LgPreset preset)
|
||||
{
|
||||
var mouse = await api.GetMouse();
|
||||
foreach (var step in preset.steps)
|
||||
{
|
||||
var keySpec = step.Split(':');
|
||||
if (keySpec.Length == 2)
|
||||
{
|
||||
SendKey(mouse, keySpec[0], int.Parse(keySpec[1]));
|
||||
}
|
||||
else
|
||||
{
|
||||
SendKey(mouse, keySpec[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void SendKey(LgWebOsMouseService mouse, string key, int delay = 180)
|
||||
{
|
||||
if (key.Length == 1 && int.TryParse(key, out _))
|
||||
{
|
||||
key = "_" + key;
|
||||
}
|
||||
var button = (ButtonType)Enum.Parse(typeof(ButtonType), key);
|
||||
mouse.SendButton(button);
|
||||
Thread.Sleep(delay);
|
||||
}
|
||||
|
||||
public async Task<List<LgApp>> RefreshApps(bool force = false)
|
||||
{
|
||||
if (SelectedDevice == null)
|
||||
{
|
||||
Logger.Debug("Cannot refresh apps: no device has been selected");
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!await Connected(force))
|
||||
{
|
||||
Logger.Debug("Cannot refresh apps: no connection could be made");
|
||||
return null;
|
||||
}
|
||||
|
||||
var list = await _lgTvApi.GetApps(force);
|
||||
|
||||
return list.ToList();
|
||||
}
|
||||
|
||||
internal void DisposeConnection()
|
||||
{
|
||||
if (_lgTvApi != null)
|
||||
{
|
||||
_lgTvApi.Dispose();
|
||||
_lgTvApi = null;
|
||||
}
|
||||
}
|
||||
|
||||
internal async Task<bool> PowerOff()
|
||||
{
|
||||
if (!await Connected(true))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
await _lgTvApi.TurnOff();
|
||||
return true;
|
||||
}
|
||||
|
||||
internal void WakeSelectedDevice()
|
||||
{
|
||||
if (SelectedDevice != null)
|
||||
{
|
||||
WOL.WakeFunction(SelectedDevice.MacAddress);
|
||||
_justWokeUp = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger.Debug("Cannot wake device: no device has been selected");
|
||||
}
|
||||
}
|
||||
|
||||
internal void WakeAfterResume()
|
||||
{
|
||||
if (Config.PowerOnAfterResume)
|
||||
{
|
||||
WakeAndConnectToSelectedDevice(Config.PowerOnDelayAfterResume);
|
||||
}
|
||||
}
|
||||
|
||||
private void WakeAndConnectToSelectedDevice(int wakeDelay = 5000, int connectDelay = 1000)
|
||||
{
|
||||
Task.Run(async () =>
|
||||
{
|
||||
try
|
||||
{
|
||||
//if (wakeDelay == 0)
|
||||
//{
|
||||
// if (await ConnectToSelectedDevice())
|
||||
// {
|
||||
// Logger.Debug("Already connected, no wake needed?");
|
||||
// return;
|
||||
// };
|
||||
//}
|
||||
|
||||
await Task.Delay(wakeDelay);
|
||||
WakeSelectedDevice();
|
||||
await Task.Delay(connectDelay);
|
||||
await ConnectToSelectedDevice();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.Error("WakeAndConnectToSelectedDevice: " + e.ToLogString());
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
namespace ColorControl
|
||||
{
|
||||
class LgServiceConfig
|
||||
{
|
||||
public bool PowerOnAfterStartup { get; set; }
|
||||
|
||||
public bool PowerOnAfterResume { get; set; }
|
||||
|
||||
public bool PowerOffOnShutdown { get; set; }
|
||||
|
||||
public bool PowerOffOnStandby { get; set; }
|
||||
|
||||
public int PowerOnDelayAfterResume { get; set; }
|
||||
|
||||
public string PreferredMacAddress { get; set; }
|
||||
|
||||
public string DeviceSearchKey { get; set; }
|
||||
|
||||
public LgServiceConfig()
|
||||
{
|
||||
PowerOnDelayAfterResume = 5000;
|
||||
DeviceSearchKey = "[LG]";
|
||||
}
|
||||
}
|
||||
}
|
||||
Generated
+494
-1110
File diff suppressed because it is too large.
Load diff
+1100
-1576
File diff suppressed because it is too large.
Load diff
+25
-31
@@ -1,17 +1,17 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
|
||||
Example:
|
||||
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
@@ -26,36 +26,36 @@
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
@@ -117,12 +117,6 @@
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<metadata name="mnuNvPresets.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>17, 17</value>
|
||||
</metadata>
|
||||
<metadata name="mnuLgButtons.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>147, 17</value>
|
||||
</metadata>
|
||||
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
|
||||
<data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
|
||||
@@ -1,186 +0,0 @@
|
||||
using NvAPIWrapper.Display;
|
||||
using NvAPIWrapper.Native.Display;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace ColorControl
|
||||
{
|
||||
class NvPreset : PresetBase
|
||||
{
|
||||
public bool applyColorData { get; set; }
|
||||
public ColorData colorData { get; set; }
|
||||
public bool applyHDR { get; set; }
|
||||
public bool HDREnabled { get; set; }
|
||||
public bool toggleHDR { get; set; }
|
||||
public bool applyDithering { get; set; }
|
||||
public bool ditheringEnabled { get; set; }
|
||||
public bool applyRefreshRate { get; set; }
|
||||
public uint refreshRate { get; set; }
|
||||
public bool primaryDisplay { get; set; }
|
||||
public string displayName { get; set; }
|
||||
|
||||
public NvPreset()
|
||||
{
|
||||
applyColorData = true;
|
||||
applyDithering = false;
|
||||
ditheringEnabled = true;
|
||||
applyHDR = false;
|
||||
HDREnabled = false;
|
||||
toggleHDR = false;
|
||||
applyRefreshRate = false;
|
||||
refreshRate = 60;
|
||||
primaryDisplay = true;
|
||||
}
|
||||
|
||||
public NvPreset(ColorData colorData) : this()
|
||||
{
|
||||
id = GetNewId();
|
||||
this.colorData = colorData;
|
||||
}
|
||||
|
||||
public NvPreset(NvPreset preset): this()
|
||||
{
|
||||
id = GetNewId();
|
||||
|
||||
primaryDisplay = preset.primaryDisplay;
|
||||
displayName = preset.displayName;
|
||||
|
||||
var colorData = preset.colorData;
|
||||
this.colorData = new ColorData(colorData.ColorFormat, dynamicRange: colorData.DynamicRange, colorDepth: colorData.ColorDepth, colorSelectionPolicy: colorData.SelectionPolicy);
|
||||
applyColorData = preset.applyColorData;
|
||||
|
||||
applyHDR = preset.applyHDR;
|
||||
HDREnabled = preset.HDREnabled;
|
||||
toggleHDR = preset.toggleHDR;
|
||||
applyDithering = preset.applyDithering;
|
||||
ditheringEnabled = preset.ditheringEnabled;
|
||||
applyRefreshRate = preset.applyRefreshRate;
|
||||
refreshRate = preset.refreshRate;
|
||||
}
|
||||
|
||||
public NvPreset Clone()
|
||||
{
|
||||
var preset = new NvPreset(this);
|
||||
|
||||
return preset;
|
||||
}
|
||||
|
||||
public static string[] GetColumnNames()
|
||||
{
|
||||
//return new[] { "BPC", "Format", "Dynamic range", "Toggle HDR", "Shortcut" };
|
||||
return new[] { "Display|140", "Color settings (BPC, format, dyn. range, color space)|260", "Refresh rate|100", "Dithering", "HDR", "Shortcut" };
|
||||
}
|
||||
|
||||
public List<string> GetDisplayValues()
|
||||
{
|
||||
var values = new List<string>();
|
||||
|
||||
var display = string.Format("{0}", primaryDisplay ? "Primary" : displayName);
|
||||
values.Add(display);
|
||||
|
||||
var colorSettings = string.Format("{0}: {1}, {2}, {3}, {4}", applyColorData ? "Included" : "Excluded", colorData.ColorDepth, colorData.ColorFormat, colorData.DynamicRange, colorData.Colorimetry);
|
||||
|
||||
values.Add(colorSettings);
|
||||
values.Add(string.Format("{0}: {1}Hz", applyRefreshRate ? "Included" : "Excluded", refreshRate));
|
||||
values.Add(string.Format("{0}: {1}", applyDithering ? "Included" : "Excluded", ditheringEnabled ? "Enabled" : "Disabled"));
|
||||
values.Add(string.Format("{0}: {1}", applyHDR ? "Included" : "Excluded", toggleHDR ? "Toggle" : HDREnabled ? "Enabled" : "Disabled"));
|
||||
|
||||
//values.Add(colorData.ColorDepth.ToString());
|
||||
//values.Add(colorData.ColorFormat.ToString());
|
||||
//values.Add(colorData.DynamicRange.ToString());
|
||||
//values.Add(toggleHDR.ToString());
|
||||
values.Add(shortcut);
|
||||
|
||||
return values;
|
||||
}
|
||||
|
||||
public static List<NvPreset> GetDefaultPresets()
|
||||
{
|
||||
var presets = new List<NvPreset>();
|
||||
|
||||
presets.Add(new NvPreset(new ColorData(ColorDataFormat.Auto, dynamicRange: ColorDataDynamicRange.Auto, colorDepth: ColorDataDepth.Default, colorSelectionPolicy: ColorDataSelectionPolicy.BestQuality)));
|
||||
|
||||
for (var dynamicRange = ColorDataDynamicRange.VESA; dynamicRange <= ColorDataDynamicRange.CEA; dynamicRange++)
|
||||
{
|
||||
presets.Add(new NvPreset(new ColorData(ColorDataFormat.RGB, dynamicRange: dynamicRange, colorDepth: ColorDataDepth.BPC8, colorSelectionPolicy: ColorDataSelectionPolicy.User)));
|
||||
presets.Add(new NvPreset(new ColorData(ColorDataFormat.RGB, dynamicRange: dynamicRange, colorDepth: ColorDataDepth.BPC10, colorSelectionPolicy: ColorDataSelectionPolicy.User)));
|
||||
presets.Add(new NvPreset(new ColorData(ColorDataFormat.RGB, dynamicRange: dynamicRange, colorDepth: ColorDataDepth.BPC12, colorSelectionPolicy: ColorDataSelectionPolicy.User)));
|
||||
}
|
||||
|
||||
for (var format = ColorDataFormat.YUV422; format <= ColorDataFormat.YUV420; format++)
|
||||
{
|
||||
presets.Add(new NvPreset(new ColorData(format, dynamicRange: ColorDataDynamicRange.Auto, colorDepth: ColorDataDepth.BPC8, colorSelectionPolicy: ColorDataSelectionPolicy.User)));
|
||||
presets.Add(new NvPreset(new ColorData(format, dynamicRange: ColorDataDynamicRange.Auto, colorDepth: ColorDataDepth.BPC10, colorSelectionPolicy: ColorDataSelectionPolicy.User)));
|
||||
presets.Add(new NvPreset(new ColorData(format, dynamicRange: ColorDataDynamicRange.Auto, colorDepth: ColorDataDepth.BPC12, colorSelectionPolicy: ColorDataSelectionPolicy.User)));
|
||||
}
|
||||
|
||||
return presets;
|
||||
}
|
||||
|
||||
public string GetTextForMenuItem()
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
if (displayName != null)
|
||||
{
|
||||
sb.AppendFormat("Display: {0} / ", displayName);
|
||||
}
|
||||
if (applyColorData)
|
||||
{
|
||||
var colorSettings = string.Format("Format: {0}, {1}, {2}", colorData.ColorDepth, colorData.ColorFormat, colorData.DynamicRange);
|
||||
sb.Append(colorSettings);
|
||||
sb.Append(" / ");
|
||||
}
|
||||
if (applyRefreshRate)
|
||||
{
|
||||
sb.AppendFormat("{0}Hz", refreshRate);
|
||||
sb.Append(" / ");
|
||||
}
|
||||
if (applyDithering)
|
||||
{
|
||||
sb.AppendFormat("Dithering: {0}", ditheringEnabled ? "Yes" : "No");
|
||||
sb.Append(" / ");
|
||||
}
|
||||
if (applyHDR)
|
||||
{
|
||||
sb.AppendFormat("HDR: {0}", toggleHDR ? "Toggle" : HDREnabled ? "Enabled" : "Disabled");
|
||||
sb.Append(" / ");
|
||||
}
|
||||
|
||||
return sb.ToString(0, Math.Max(0, sb.Length - 3));
|
||||
}
|
||||
|
||||
public static ColorData GenerateColorData(IDictionary<string, object> dictionary)
|
||||
{
|
||||
var format = ColorDataFormat.RGB;
|
||||
var dynamicRange = ColorDataDynamicRange.VESA;
|
||||
var colorDepth = ColorDataDepth.BPC8;
|
||||
var colorimetry = ColorDataColorimetry.Auto;
|
||||
var selectionPolicy = ColorDataSelectionPolicy.User;
|
||||
object value;
|
||||
if (dictionary.TryGetValue("ColorFormat", out value))
|
||||
{
|
||||
format = (ColorDataFormat)Enum.ToObject(typeof(ColorDataFormat), value);
|
||||
}
|
||||
if (dictionary.TryGetValue("ColorDepth", out value))
|
||||
{
|
||||
colorDepth = (ColorDataDepth)Enum.ToObject(typeof(ColorDataDepth), value);
|
||||
}
|
||||
if (dictionary.TryGetValue("Colorimetry", out value))
|
||||
{
|
||||
colorimetry = (ColorDataColorimetry)Enum.ToObject(typeof(ColorDataColorimetry), value);
|
||||
}
|
||||
if (dictionary.TryGetValue("DynamicRange", out value))
|
||||
{
|
||||
dynamicRange = (ColorDataDynamicRange)Enum.ToObject(typeof(ColorDataDynamicRange), value);
|
||||
}
|
||||
if (dictionary.TryGetValue("SelectionPolicy", out value))
|
||||
{
|
||||
selectionPolicy = (ColorDataSelectionPolicy)Enum.ToObject(typeof(ColorDataSelectionPolicy), value);
|
||||
}
|
||||
return new ColorData(format, dynamicRange: dynamicRange, colorimetry: colorimetry, colorDepth: colorDepth, colorSelectionPolicy: selectionPolicy);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,214 +0,0 @@
|
||||
using NvAPIWrapper;
|
||||
using NvAPIWrapper.Display;
|
||||
using NvAPIWrapper.Native.Display;
|
||||
using NvAPIWrapper.Native.GPU.Structures;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace ColorControl
|
||||
{
|
||||
class NvService : GraphicsService
|
||||
{
|
||||
[DllImport(@"nvapi64", EntryPoint = @"nvapi_QueryInterface", CallingConvention = CallingConvention.Cdecl,
|
||||
PreserveSig = true)]
|
||||
private static extern IntPtr NvAPI64_QueryInterface(uint interfaceId);
|
||||
|
||||
public delegate long NvAPI_Disp_SetDitherControl(
|
||||
[In] PhysicalGPUHandle physicalGpu,
|
||||
[In] uint OutputId,
|
||||
[In] uint state,
|
||||
[In] uint bits,
|
||||
[In] uint mode
|
||||
);
|
||||
|
||||
public delegate long NvAPI_Disp_GetDitherControl(
|
||||
[In] PhysicalGPUHandle physicalGpu,
|
||||
[In] uint OutputId,
|
||||
[In][Out] IntPtr ditherControl);
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 8)]
|
||||
public struct NV_GPU_DITHER_CONTROL_V1
|
||||
{
|
||||
public int version;
|
||||
public uint state;
|
||||
public uint bits;
|
||||
public uint mode;
|
||||
};
|
||||
|
||||
private Display _currentDisplay;
|
||||
private bool _initialized = false;
|
||||
|
||||
public NvService()
|
||||
{
|
||||
}
|
||||
|
||||
public Display GetCurrentDisplay()
|
||||
{
|
||||
if (_currentDisplay == null)
|
||||
{
|
||||
_currentDisplay = Display.GetDisplays()[0];
|
||||
}
|
||||
|
||||
return _currentDisplay;
|
||||
}
|
||||
|
||||
private void SetCurrentDisplay(NvPreset preset)
|
||||
{
|
||||
if (preset.primaryDisplay)
|
||||
{
|
||||
var displayId = DisplayDevice.GetGDIPrimaryDisplayDevice().DisplayId;
|
||||
_currentDisplay = Display.GetDisplays().FirstOrDefault(x => x.DisplayDevice.DisplayId == displayId);
|
||||
}
|
||||
else
|
||||
{
|
||||
_currentDisplay = Display.GetDisplays().FirstOrDefault(x => x.Name.Equals(preset.displayName));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public bool ApplyPreset(NvPreset preset, Config config)
|
||||
{
|
||||
SetCurrentDisplay(preset);
|
||||
|
||||
if (preset.applyHDR)
|
||||
{
|
||||
if (preset.toggleHDR || preset.HDREnabled != IsHDREnabled())
|
||||
{
|
||||
ToggleHDR(config.DisplaySettingsDelay);
|
||||
}
|
||||
}
|
||||
|
||||
if (preset.applyRefreshRate)
|
||||
{
|
||||
SetRefreshRate(preset.refreshRate);
|
||||
}
|
||||
|
||||
if (preset.applyColorData)
|
||||
{
|
||||
var display = GetCurrentDisplay();
|
||||
//var data = new ColorData(ColorDataFormat.YUV444, ColorDataColorimetry.Auto, ColorDataDynamicRange.Auto, ColorDataDepth.BPC10, preset.colorData.SelectionPolicy, ColorDataDesktopDepth.Default);
|
||||
try
|
||||
{
|
||||
display.DisplayDevice.SetColorData(preset.colorData);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
}
|
||||
|
||||
//var master = display.DisplayDevice.HDRColorData.MasteringDisplayData;
|
||||
//var newMaster = new MasteringDisplayColorData(master.FirstColorCoordinate, master.SecondColorCoordinate, master.ThirdColorCoordinate, new ColorDataColorCoordinate(0.25f, 0.25f), 50, 0, 50, 50);
|
||||
//var hdr = new HDRColorData(ColorDataHDRMode.UHDA, newMaster, ColorDataFormat.YUV444, ColorDataDynamicRange.Auto, ColorDataDepth.BPC8);
|
||||
//display.DisplayDevice.SetHDRColorData(hdr);
|
||||
}
|
||||
|
||||
if (preset.applyDithering)
|
||||
{
|
||||
SetDithering(preset.ditheringEnabled);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void SetDithering(bool enabled)
|
||||
{
|
||||
var ptr = NvAPI64_QueryInterface(0xDF0DFCDD);
|
||||
if (ptr != IntPtr.Zero)
|
||||
{
|
||||
var delegateValue = Marshal.GetDelegateForFunctionPointer(ptr, typeof(NvAPI_Disp_SetDitherControl)) as NvAPI_Disp_SetDitherControl;
|
||||
|
||||
var displayDevice = GetCurrentDisplay().DisplayDevice;
|
||||
|
||||
var gpuHandle = displayDevice.PhysicalGPU.Handle;
|
||||
var displayId = displayDevice.DisplayId;
|
||||
|
||||
var result = delegateValue(gpuHandle, displayId, (uint)(enabled ? 1 : 2), 1, 4);
|
||||
if (result != 0)
|
||||
{
|
||||
Logger.Error($"Could not set dithering because NvAPI_Disp_SetDitherControl returned a non-zero return code: {result}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool GetDithering()
|
||||
{
|
||||
var ptr = NvAPI64_QueryInterface(0x932AC8FB);
|
||||
if (ptr != IntPtr.Zero)
|
||||
{
|
||||
var delegateValue = Marshal.GetDelegateForFunctionPointer(ptr, typeof(NvAPI_Disp_GetDitherControl)) as NvAPI_Disp_GetDitherControl;
|
||||
|
||||
var displayDevice = GetCurrentDisplay().DisplayDevice;
|
||||
|
||||
var gpuHandle = displayDevice.PhysicalGPU.Handle;
|
||||
var displayId = displayDevice.DisplayId;
|
||||
|
||||
NV_GPU_DITHER_CONTROL_V1 info = new NV_GPU_DITHER_CONTROL_V1();
|
||||
info.version = 1;
|
||||
IntPtr bla = Marshal.AllocHGlobal(Marshal.SizeOf(info.GetType()));
|
||||
Marshal.StructureToPtr(info, bla, false);
|
||||
|
||||
// Does not work yet...What is the exact interface of NvAPI_Disp_GetDitherControl?
|
||||
|
||||
var result = delegateValue(gpuHandle, displayId, bla);
|
||||
if (result != 0)
|
||||
{
|
||||
Logger.Error($"Could not get dithering because NvAPI_Disp_GetDitherControl returned a non-zero return code: {result}");
|
||||
}
|
||||
|
||||
return info.state == 1;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool SetRefreshRate(uint refreshRate)
|
||||
{
|
||||
var display = GetCurrentDisplay();
|
||||
var portrait = new[] { Rotate.Degree90, Rotate.Degree270 }.Contains(display.DisplayDevice.ScanOutInformation.SourceToTargetRotation);
|
||||
var timing = display.DisplayDevice.CurrentTiming;
|
||||
|
||||
return SetRefreshRateInternal(display.Name, refreshRate, portrait, timing.HorizontalVisible, timing.VerticalVisible);
|
||||
}
|
||||
|
||||
public List<uint> GetAvailableRefreshRates(NvPreset preset = null)
|
||||
{
|
||||
if (preset != null)
|
||||
{
|
||||
SetCurrentDisplay(preset);
|
||||
}
|
||||
|
||||
var display = GetCurrentDisplay();
|
||||
var portrait = new[] { Rotate.Degree90, Rotate.Degree270 }.Contains(display.DisplayDevice.ScanOutInformation.SourceToTargetRotation);
|
||||
var timing = display.DisplayDevice.CurrentTiming;
|
||||
|
||||
return GetAvailableRefreshRatesInternal(display.Name, portrait, timing.HorizontalVisible, timing.VerticalVisible);
|
||||
}
|
||||
|
||||
public bool IsHDREnabled()
|
||||
{
|
||||
var displayDevice = GetCurrentDisplay().DisplayDevice;
|
||||
var hdr = displayDevice.HDRColorData;
|
||||
return hdr?.HDRMode == ColorDataHDRMode.UHDA;
|
||||
}
|
||||
|
||||
public Display[] GetDisplays()
|
||||
{
|
||||
return Display.GetDisplays();
|
||||
}
|
||||
|
||||
protected override void Initialize()
|
||||
{
|
||||
NVIDIA.Initialize();
|
||||
_initialized = true;
|
||||
}
|
||||
|
||||
protected override void Uninitialize()
|
||||
{
|
||||
if (_initialized)
|
||||
{
|
||||
NVIDIA.Unload();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace ColorControl
|
||||
{
|
||||
internal abstract class PresetBase
|
||||
{
|
||||
public string shortcut { get; set; }
|
||||
|
||||
private int _id;
|
||||
|
||||
public int id
|
||||
{
|
||||
get
|
||||
{
|
||||
return _id;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value == 0 || ids.Contains(value))
|
||||
{
|
||||
value = GetNewId();
|
||||
}
|
||||
else
|
||||
{
|
||||
ids.Add(value);
|
||||
}
|
||||
_id = value;
|
||||
}
|
||||
}
|
||||
|
||||
public static List<int> ids = new List<int>();
|
||||
|
||||
public static int GetNewId()
|
||||
{
|
||||
int id;
|
||||
do
|
||||
{
|
||||
id = new Random().Next();
|
||||
}
|
||||
while (ids.Contains(id));
|
||||
|
||||
ids.Add(id);
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
+283
-17
@@ -1,47 +1,171 @@
|
||||
using System;
|
||||
using ColorControl.Forms;
|
||||
using ColorControl.Services.Common;
|
||||
using ColorControl.Services.EventDispatcher;
|
||||
using ColorControl.Services.GameLauncher;
|
||||
using ColorControl.Services.LG;
|
||||
using ColorControl.Services.NVIDIA;
|
||||
using ColorControl.Services.Samsung;
|
||||
using ColorControl.Shared.Common;
|
||||
using ColorControl.Shared.Contracts;
|
||||
using ColorControl.Shared.Native;
|
||||
using ColorControl.Shared.Services;
|
||||
using ColorControl.Svc;
|
||||
using ColorControl.XForms;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Newtonsoft.Json;
|
||||
using NLog;
|
||||
using NLog.Config;
|
||||
using NWin32;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace ColorControl
|
||||
{
|
||||
static class Program
|
||||
{
|
||||
public const string TS_TASKNAME = "ColorControl";
|
||||
public static string DataDir { get; private set; }
|
||||
public static string ConfigFilename { get; private set; }
|
||||
public static string LogFilename { get; private set; }
|
||||
public static Config Config { get; private set; }
|
||||
public static GlobalContext AppContext { get; private set; }
|
||||
|
||||
public static bool IsRestarting { get; private set; }
|
||||
public static bool UserExit = false;
|
||||
|
||||
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
|
||||
private static Mutex _mutex;
|
||||
private static MainForm _mainForm;
|
||||
private static LoggingRule _loggingRule;
|
||||
|
||||
[STAThread] // autogenerated
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
// STA
|
||||
MainAsync(args).GetAwaiter().GetResult();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The main entry point for the application.
|
||||
/// </summary>
|
||||
[STAThread]
|
||||
static void Main(string[] args)
|
||||
//[STAThread]
|
||||
static async Task MainAsync(string[] args)
|
||||
{
|
||||
DataDir = Utils.GetDataPath();
|
||||
|
||||
//Utils.UpdateFiles(@"H:\temp\ColorControl\ColorControl", @"C:\Users\vinni\source\repos\ColorControl\ColorControl\bin\Debug\net6.0-windows10.0.20348.0");
|
||||
//Utils.UnZipFile(@"H:\temp\ColorControl\ColorControl.zip", @"H:\temp\ColorControl\temp");
|
||||
|
||||
var runAsService = args.Contains("--service") || WinApiService.IsAdministratorStatic() && Process.GetCurrentProcess().Parent()?.ProcessName?.Equals("services", StringComparison.InvariantCultureIgnoreCase) == true;
|
||||
var runElevated = args.Contains("--elevated");
|
||||
|
||||
InitLogger(runAsService, runElevated);
|
||||
|
||||
Logger.Debug($"Using data path: {DataDir}");
|
||||
//Logger.Debug("Parent process: " + Process.GetCurrentProcess().Parent()?.ProcessName);
|
||||
|
||||
if (runAsService)
|
||||
{
|
||||
await RunService(args);
|
||||
return;
|
||||
}
|
||||
|
||||
var host = CreateHostBuilder().Build();
|
||||
ServiceProvider = host.Services;
|
||||
|
||||
var mutexId = $"Global\\{typeof(MainForm).GUID}";
|
||||
|
||||
var currentDomain = AppDomain.CurrentDomain;
|
||||
// Handler for unhandled exceptions.
|
||||
currentDomain.UnhandledException += GlobalUnhandledExceptionHandler;
|
||||
// Handler for exceptions in threads behind forms.
|
||||
Application.ThreadException += GlobalThreadExceptionHandler;
|
||||
|
||||
LoadConfig();
|
||||
|
||||
var appContextProvider = ServiceProvider.GetRequiredService<AppContextProvider>();
|
||||
var startUpParams = StartUpParams.Parse(args);
|
||||
|
||||
if (startUpParams.ActivateChromeFontFix || startUpParams.DeactivateChromeFontFix)
|
||||
AppContext = new GlobalContext(Config, startUpParams, DataDir, _loggingRule, mutexId);
|
||||
appContextProvider.SetAppContext(AppContext);
|
||||
|
||||
if (Config.UseGdiScaling)
|
||||
{
|
||||
Utils.InstallChromeFix(startUpParams.ActivateChromeFontFix);
|
||||
return;
|
||||
Application.SetHighDpiMode(HighDpiMode.DpiUnawareGdiScaled);
|
||||
}
|
||||
|
||||
string mutexId = $"Global\\{typeof(MainForm).GUID}";
|
||||
bool mutexCreated;
|
||||
var mutex = new Mutex(true, mutexId, out mutexCreated);
|
||||
var existingProcess = Utils.GetProcessByName("ColorControl");
|
||||
|
||||
try
|
||||
{
|
||||
if (await CommandLineHandler.HandleStartupParams(startUpParams, existingProcess))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
Utils.CloseConsole();
|
||||
}
|
||||
|
||||
_mutex = new Mutex(true, AppContext.MutexId, out var mutexCreated);
|
||||
try
|
||||
{
|
||||
if (!mutexCreated)
|
||||
{
|
||||
if (existingProcess != null && existingProcess.Threads.Count > 0)
|
||||
{
|
||||
var thread = existingProcess.Threads[0];
|
||||
NativeMethods.EnumThreadWindows((uint)thread.Id, EnumThreadWindows, IntPtr.Zero);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
MessageBox.Show("Only one instance of this program can be active.", "ColorControl");
|
||||
}
|
||||
else
|
||||
{
|
||||
_mutex.WaitOne();
|
||||
try
|
||||
{
|
||||
//if (Debugger.IsAttached)
|
||||
//{
|
||||
// Utils.StartService();
|
||||
//}
|
||||
|
||||
//var result = WinApi.SetPreferredAppMode(1);
|
||||
//result = WinApi.RefreshImmersiveColorPolicyState();
|
||||
|
||||
Application.EnableVisualStyles();
|
||||
Application.SetCompatibleTextRenderingDefault(false);
|
||||
Application.Run(new MainForm(startUpParams));
|
||||
|
||||
if (Debugger.IsAttached)
|
||||
{
|
||||
var winApiService = ServiceProvider.GetRequiredService<WinApiService>();
|
||||
|
||||
if (winApiService.IsAdministrator())
|
||||
{
|
||||
var backgroundService = ServiceProvider.GetRequiredService<ColorControlBackgroundService>();
|
||||
backgroundService.PipeName = PipeUtils.ElevatedPipe;
|
||||
|
||||
Task.Run(async () => await backgroundService.StartAsync(CancellationToken.None));
|
||||
}
|
||||
}
|
||||
|
||||
_mainForm = ServiceProvider.GetRequiredService<MainForm>();
|
||||
Application.Run(_mainForm);
|
||||
|
||||
if (Debugger.IsAttached && !IsRestarting)
|
||||
{
|
||||
var winApiAdminService = ServiceProvider.GetRequiredService<WinApiAdminService>();
|
||||
winApiAdminService.StopService();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -53,21 +177,163 @@ namespace ColorControl
|
||||
{
|
||||
if (mutexCreated)
|
||||
{
|
||||
mutex.Dispose();
|
||||
_mutex?.Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void GlobalUnhandledExceptionHandler(object sender, UnhandledExceptionEventArgs e)
|
||||
public static void Restart()
|
||||
{
|
||||
var ex = (Exception)e.ExceptionObject;
|
||||
MessageBox.Show("Unhandled exception: " + ex.ToLogString(Environment.StackTrace), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
IsRestarting = true;
|
||||
|
||||
_mainForm?.CloseForRestart();
|
||||
|
||||
_mutex?.Close();
|
||||
_mutex = null;
|
||||
|
||||
Application.Restart();
|
||||
Environment.Exit(0);
|
||||
}
|
||||
|
||||
private static void GlobalThreadExceptionHandler(object sender, System.Threading.ThreadExceptionEventArgs e)
|
||||
private static void InitLogger(bool runAsService, bool runElevated)
|
||||
{
|
||||
var ex = e.Exception;
|
||||
MessageBox.Show("Exception in thread: " + ex.ToLogString(Environment.StackTrace), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
var config = new LoggingConfiguration();
|
||||
|
||||
// Targets where to log to: File and Console
|
||||
var logFileAppendix = runAsService ? "_svc" : runElevated ? "_elevated" : "";
|
||||
|
||||
LogFilename = Path.Combine(DataDir, $"LogFile{logFileAppendix}.txt");
|
||||
|
||||
var logfile = new NLog.Targets.FileTarget("logfile") { FileName = LogFilename };
|
||||
|
||||
_loggingRule = new LoggingRule("*", LogLevel.Trace, LogLevel.Fatal, logfile);
|
||||
_loggingRule.RuleName = "ColorControl";
|
||||
|
||||
// Rules for mapping loggers to targets
|
||||
config.AddRule(_loggingRule);
|
||||
|
||||
// Apply config
|
||||
LogManager.Configuration = config;
|
||||
}
|
||||
|
||||
private static void LoadConfig()
|
||||
{
|
||||
ConfigFilename = Path.Combine(DataDir, "Settings.json");
|
||||
|
||||
try
|
||||
{
|
||||
if (File.Exists(ConfigFilename))
|
||||
{
|
||||
var data = File.ReadAllText(ConfigFilename);
|
||||
Config = JsonConvert.DeserializeObject<Config>(data);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Error($"LoadConfig: {ex.Message}");
|
||||
}
|
||||
Config ??= new Config();
|
||||
|
||||
var minLogLevel = LogLevel.FromString(Config.LogLevel);
|
||||
|
||||
if (minLogLevel != LogLevel.Trace)
|
||||
{
|
||||
_loggingRule.SetLoggingLevels(minLogLevel, LogLevel.Fatal);
|
||||
LogManager.ReconfigExistingLoggers();
|
||||
}
|
||||
}
|
||||
|
||||
public static IServiceProvider ServiceProvider { get; private set; }
|
||||
private static IHostBuilder CreateHostBuilder()
|
||||
{
|
||||
return Host.CreateDefaultBuilder()
|
||||
.ConfigureServices((context, services) =>
|
||||
{
|
||||
//services.AddSingleton<NvService>();
|
||||
services.RegisterSharedServices();
|
||||
services.AddSingleton<LgService>();
|
||||
services.AddSingleton<GameService>();
|
||||
services.AddSingleton<SamsungService>();
|
||||
services.AddSingleton<PowerEventDispatcher>();
|
||||
services.AddSingleton<ProcessEventDispatcher>();
|
||||
services.AddSingleton<MainForm>();
|
||||
services.AddSingleton<ElevatedForm>();
|
||||
services.AddSingleton<LogWindow>();
|
||||
services.AddSingleton<RestartDetector>();
|
||||
});
|
||||
}
|
||||
private static async Task RunService(string[] args)
|
||||
{
|
||||
Logger.Debug("RUNNING SERVICE");
|
||||
|
||||
using IHost host = Host.CreateDefaultBuilder(args)
|
||||
.UseWindowsService(options =>
|
||||
{
|
||||
options.ServiceName = "ColorControl Service";
|
||||
})
|
||||
.ConfigureServices(services =>
|
||||
{
|
||||
services.RegisterSharedServices();
|
||||
services.AddHostedService<ColorControlBackgroundService>();
|
||||
})
|
||||
.Build();
|
||||
|
||||
ServiceProvider = host.Services;
|
||||
|
||||
var appContextProvider = ServiceProvider.GetRequiredService<AppContextProvider>();
|
||||
AppContext = new GlobalContext(null, new StartUpParams(), DataDir, _loggingRule);
|
||||
appContextProvider.SetAppContext(AppContext);
|
||||
|
||||
await host.RunAsync();
|
||||
}
|
||||
|
||||
private static void RegisterSharedServices(this IServiceCollection services)
|
||||
{
|
||||
services.AddSingleton<AppContextProvider>();
|
||||
services.AddSingleton<SessionSwitchDispatcher>();
|
||||
services.AddSingleton<WinApiAdminService>();
|
||||
services.AddSingleton<WinApiService>();
|
||||
services.AddSingleton<WinElevatedProcessManager>();
|
||||
services.AddTransient<RpcClientService>();
|
||||
services.AddTransient<RpcServerService>();
|
||||
services.AddSingleton<NvService>();
|
||||
services.AddSingleton<WolService>();
|
||||
services.AddSingleton<ColorControlBackgroundService>();
|
||||
services.AddSingleton<ServiceManager>();
|
||||
|
||||
RpcServerService.ServiceTypes.Add(typeof(NvService));
|
||||
}
|
||||
|
||||
public static int EnumThreadWindows(IntPtr handle, IntPtr param)
|
||||
{
|
||||
NativeMethods.SendMessageW(handle, Utils.WM_BRINGTOFRONT, UIntPtr.Zero, IntPtr.Zero);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
private static void GlobalUnhandledExceptionHandler(object sender, UnhandledExceptionEventArgs e)
|
||||
{
|
||||
GlobalHandleException((Exception)e.ExceptionObject, "Unhandled exception");
|
||||
}
|
||||
|
||||
private static void GlobalThreadExceptionHandler(object sender, ThreadExceptionEventArgs e)
|
||||
{
|
||||
GlobalHandleException(e.Exception, "Exception in thread");
|
||||
}
|
||||
|
||||
private static void GlobalHandleException(Exception exception, string type)
|
||||
{
|
||||
if (UserExit)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var trace = exception.ToLogString(Environment.StackTrace);
|
||||
var message = $"{type}: {trace}";
|
||||
|
||||
Logger.Error(message);
|
||||
|
||||
MessageBox.Show(message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("ColorControl")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("Maassoft")]
|
||||
[assembly: AssemblyProduct("ColorControl")]
|
||||
[assembly: AssemblyCopyright("Copyright © Maassoft 2020")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("a6005d08-70f0-44cb-a384-9219eba84f21")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.3.6.0")]
|
||||
[assembly: AssemblyFileVersion("1.3.6.0")]
|
||||
+72
-26
@@ -8,10 +8,10 @@
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace ColorControl.Properties
|
||||
{
|
||||
|
||||
|
||||
namespace ColorControl.Properties {
|
||||
using System;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// A strongly-typed resource class, for looking up localized strings, etc.
|
||||
/// </summary>
|
||||
@@ -19,53 +19,99 @@ namespace ColorControl.Properties
|
||||
// class via a tool like ResGen or Visual Studio.
|
||||
// To add or remove a member, edit your .ResX file then rerun ResGen
|
||||
// with the /str option, or rebuild your VS project.
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
internal class Resources
|
||||
{
|
||||
|
||||
internal class Resources {
|
||||
|
||||
private static global::System.Resources.ResourceManager resourceMan;
|
||||
|
||||
|
||||
private static global::System.Globalization.CultureInfo resourceCulture;
|
||||
|
||||
|
||||
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
|
||||
internal Resources()
|
||||
{
|
||||
internal Resources() {
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Returns the cached ResourceManager instance used by this class.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Resources.ResourceManager ResourceManager
|
||||
{
|
||||
get
|
||||
{
|
||||
if ((resourceMan == null))
|
||||
{
|
||||
internal static global::System.Resources.ResourceManager ResourceManager {
|
||||
get {
|
||||
if (object.ReferenceEquals(resourceMan, null)) {
|
||||
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("ColorControl.Properties.Resources", typeof(Resources).Assembly);
|
||||
resourceMan = temp;
|
||||
}
|
||||
return resourceMan;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Overrides the current thread's CurrentUICulture property for all
|
||||
/// resource lookups using this strongly typed resource class.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Globalization.CultureInfo Culture
|
||||
{
|
||||
get
|
||||
{
|
||||
internal static global::System.Globalization.CultureInfo Culture {
|
||||
get {
|
||||
return resourceCulture;
|
||||
}
|
||||
set
|
||||
{
|
||||
set {
|
||||
resourceCulture = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized resource of type System.Drawing.Bitmap.
|
||||
/// </summary>
|
||||
internal static System.Drawing.Bitmap LG_remote {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("LG_remote", resourceCulture);
|
||||
return ((System.Drawing.Bitmap)(obj));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Power;120;136
|
||||
///1;106;228
|
||||
///2;196;228
|
||||
///3;286;228
|
||||
///4;106;296
|
||||
///5;196;296
|
||||
///6;286;296
|
||||
///7;106;362
|
||||
///8;196;362
|
||||
///9;286;362
|
||||
///List;106;425
|
||||
///0;196;425
|
||||
///SAP;286;425
|
||||
///Vol +;98;513
|
||||
///Mute;198;513
|
||||
///Channel +;298;513
|
||||
///Vol -;98;622
|
||||
///Channel -;298;622
|
||||
///Home;78;695
|
||||
///Settings;318;695
|
||||
///Up;200;748
|
||||
///Left;98;852
|
||||
///Enter;200;852
|
||||
///Right;304;852
|
||||
///Down;200;952
|
||||
///Back;80;1000
|
||||
///TV Guide;320;1000
|
||||
///Netflix;92;1076
|
||||
///Inputs;200;1066
|
||||
///Amazon Prime;312;1076
|
||||
///Red;90;1150
|
||||
///Green;164;1150
|
||||
///Yellow;240;1150
|
||||
///Blue;316;1150
|
||||
///Rakuten TV;116;1218
|
||||
///Play;202 [rest of string was truncated]";.
|
||||
/// </summary>
|
||||
internal static string RC_coords {
|
||||
get {
|
||||
return ResourceManager.GetString("RC_coords", resourceCulture);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -46,7 +46,7 @@
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
@@ -60,6 +60,7 @@
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
@@ -68,9 +69,10 @@
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
@@ -85,9 +87,10 @@
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
@@ -109,9 +112,16 @@
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
||||
<data name="LG_remote" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\LG_remote.jpg;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="RC_coords" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\RC_coords.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252</value>
|
||||
</data>
|
||||
</root>
|
||||
@@ -1,7 +0,0 @@
|
||||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)">
|
||||
<Profiles>
|
||||
<Profile Name="(Default)" />
|
||||
</Profiles>
|
||||
<Settings />
|
||||
</SettingsFile>
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"profiles": {
|
||||
"ColorControl": {
|
||||
"commandName": "Project"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
{
|
||||
"type":"register",
|
||||
"id":"register_0",
|
||||
"payload":{
|
||||
"forcePairing":false,
|
||||
"pairingType":"PROMPT",
|
||||
"client-key":"CLIENTKEYGOESHERE",
|
||||
"manifest":{
|
||||
"manifestVersion":1,
|
||||
"appVersion":"1.1",
|
||||
"signed":{
|
||||
"created":"20140509",
|
||||
"appId":"com.lge.test",
|
||||
"vendorId":"com.lge",
|
||||
"localizedAppNames":{
|
||||
"":"LG Remote App",
|
||||
"ko-KR":"리모컨 앱",
|
||||
"zxx-XX":"ЛГ Rэмotэ AПП"
|
||||
},
|
||||
"localizedVendorNames":{
|
||||
"":"LG Electronics"
|
||||
},
|
||||
"permissions":[
|
||||
"TEST_SECURE",
|
||||
"CONTROL_INPUT_TEXT",
|
||||
"CONTROL_MOUSE_AND_KEYBOARD",
|
||||
"READ_INSTALLED_APPS",
|
||||
"READ_LGE_SDX",
|
||||
"READ_NOTIFICATIONS",
|
||||
"SEARCH",
|
||||
"WRITE_SETTINGS",
|
||||
"WRITE_NOTIFICATION_ALERT",
|
||||
"CONTROL_POWER",
|
||||
"READ_CURRENT_CHANNEL",
|
||||
"READ_RUNNING_APPS",
|
||||
"READ_UPDATE_INFO",
|
||||
"UPDATE_FROM_REMOTE_APP",
|
||||
"READ_LGE_TV_INPUT_EVENTS",
|
||||
"READ_TV_CURRENT_TIME"
|
||||
],
|
||||
"serial":"2f930e2d2cfe083771f68e4fe7bb07"
|
||||
},
|
||||
"permissions":[
|
||||
"LAUNCH",
|
||||
"LAUNCH_WEBAPP",
|
||||
"APP_TO_APP",
|
||||
"CLOSE",
|
||||
"TEST_OPEN",
|
||||
"TEST_PROTECTED",
|
||||
"CONTROL_AUDIO",
|
||||
"CONTROL_DISPLAY",
|
||||
"CONTROL_INPUT_JOYSTICK",
|
||||
"CONTROL_INPUT_MEDIA_RECORDING",
|
||||
"CONTROL_INPUT_MEDIA_PLAYBACK",
|
||||
"CONTROL_INPUT_TV",
|
||||
"CONTROL_POWER",
|
||||
"CONTROL_TV_SCREEN",
|
||||
"READ_APP_STATUS",
|
||||
"READ_CURRENT_CHANNEL",
|
||||
"READ_INPUT_DEVICE_LIST",
|
||||
"READ_NETWORK_STATE",
|
||||
"READ_RUNNING_APPS",
|
||||
"READ_TV_CHANNEL_LIST",
|
||||
"WRITE_NOTIFICATION_TOAST",
|
||||
"READ_POWER_STATE",
|
||||
"READ_COUNTRY_INFO",
|
||||
"READ_SETTINGS"
|
||||
],
|
||||
"signatures":[
|
||||
{
|
||||
"signatureVersion":1,
|
||||
"signature":"eyJhbGdvcml0aG0iOiJSU0EtU0hBMjU2Iiwia2V5SWQiOiJ0ZXN0LXNpZ25pbmctY2VydCIsInNpZ25hdHVyZVZlcnNpb24iOjF9.hrVRgjCwXVvE2OOSpDZ58hR+59aFNwYDyjQgKk3auukd7pcegmE2CzPCa0bJ0ZsRAcKkCTJrWo5iDzNhMBWRyaMOv5zWSrthlf7G128qvIlpMT0YNY+n/FaOHE73uLrS/g7swl3/qH/BGFG2Hu4RlL48eb3lLKqTt2xKHdCs6Cd4RMfJPYnzgvI4BNrFUKsjkcu+WD4OO2A27Pq1n50cMchmcaXadJhGrOqH5YmHdOCj5NSHzJYrsW0HPlpuAx/ECMeIZYDh6RMqaFM2DXzdKX9NmmyqzJ3o/0lkk/N97gfVRLW5hA29yeAwaCViZNCP8iC9aO0q9fQojoa7NQnAtw=="
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 93 KiB |
@@ -0,0 +1,37 @@
|
||||
Power;120;136
|
||||
1;106;228
|
||||
2;196;228
|
||||
3;286;228
|
||||
4;106;296
|
||||
5;196;296
|
||||
6;286;296
|
||||
7;106;362
|
||||
8;196;362
|
||||
9;286;362
|
||||
List;106;425
|
||||
0;196;425
|
||||
SAP;286;425
|
||||
Vol +;98;513
|
||||
Mute;198;513
|
||||
Channel +;298;513
|
||||
Vol -;98;622
|
||||
Channel -;298;622
|
||||
Home;78;695
|
||||
Settings;318;695
|
||||
Up;200;748
|
||||
Left;98;852
|
||||
Enter;200;852
|
||||
Right;304;852
|
||||
Down;200;952
|
||||
Back;80;1000
|
||||
TV Guide;320;1000
|
||||
Netflix;92;1076
|
||||
Inputs;200;1066
|
||||
Amazon Prime;312;1076
|
||||
Red;90;1150
|
||||
Green;164;1150
|
||||
Yellow;240;1150
|
||||
Blue;316;1150
|
||||
Rakuten TV;116;1218
|
||||
Play;202;1218
|
||||
Pause;291;1218
|
||||
@@ -0,0 +1,396 @@
|
||||
#region Copyright
|
||||
|
||||
/*******************************************************************************
|
||||
Copyright(c) 2008 - 2009 Advanced Micro Devices, Inc. All Rights Reserved.
|
||||
Copyright (c) 2002 - 2006 ATI Technologies Inc. All Rights Reserved.
|
||||
|
||||
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
|
||||
ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDED BUT NOT LIMITED TO
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
|
||||
PARTICULAR PURPOSE.
|
||||
|
||||
File: ADL.cs
|
||||
|
||||
Purpose: Implements ADL interface
|
||||
|
||||
Description: Implements some of the methods defined in ADL interface.
|
||||
|
||||
********************************************************************************/
|
||||
|
||||
#endregion Copyright
|
||||
|
||||
#region Using
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
using ADL_CONTEXT_HANDLE = System.IntPtr;
|
||||
using FARPROC = System.IntPtr;
|
||||
using HMODULE = System.IntPtr;
|
||||
|
||||
#endregion Using
|
||||
|
||||
#region ATI.ADL
|
||||
|
||||
namespace ATI.ADL
|
||||
{
|
||||
#region Export Struct
|
||||
|
||||
#region ADLAdapterInfo
|
||||
/// <summary> ADLAdapterInfo Structure</summary>
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal struct ADLAdapterInfo
|
||||
{
|
||||
/// <summary>The size of the structure</summary>
|
||||
int Size;
|
||||
/// <summary> Adapter Index</summary>
|
||||
internal int AdapterIndex;
|
||||
/// <summary> Adapter UDID</summary>
|
||||
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = (int)ADL.ADL_MAX_PATH)]
|
||||
internal string UDID;
|
||||
/// <summary> Adapter Bus Number</summary>
|
||||
internal int BusNumber;
|
||||
/// <summary> Adapter Driver Number</summary>
|
||||
internal int DriverNumber;
|
||||
/// <summary> Adapter Function Number</summary>
|
||||
internal int FunctionNumber;
|
||||
/// <summary> Adapter Vendor ID</summary>
|
||||
internal int VendorID;
|
||||
/// <summary> Adapter Adapter name</summary>
|
||||
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = (int)ADL.ADL_MAX_PATH)]
|
||||
internal string AdapterName;
|
||||
/// <summary> Adapter Display name</summary>
|
||||
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = (int)ADL.ADL_MAX_PATH)]
|
||||
internal string DisplayName;
|
||||
/// <summary> Adapter Present status</summary>
|
||||
internal int Present;
|
||||
/// <summary> Adapter Exist status</summary>
|
||||
internal int Exist;
|
||||
/// <summary> Adapter Driver Path</summary>
|
||||
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = (int)ADL.ADL_MAX_PATH)]
|
||||
internal string DriverPath;
|
||||
/// <summary> Adapter Driver Ext Path</summary>
|
||||
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = (int)ADL.ADL_MAX_PATH)]
|
||||
internal string DriverPathExt;
|
||||
/// <summary> Adapter PNP String</summary>
|
||||
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = (int)ADL.ADL_MAX_PATH)]
|
||||
internal string PNPString;
|
||||
/// <summary> OS Display Index</summary>
|
||||
internal int OSDisplayIndex;
|
||||
}
|
||||
|
||||
|
||||
/// <summary> ADLAdapterInfo Array</summary>
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal struct ADLAdapterInfoArray
|
||||
{
|
||||
/// <summary> ADLAdapterInfo Array </summary>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = (int)ADL.ADL_MAX_ADAPTERS)]
|
||||
internal ADLAdapterInfo[] ADLAdapterInfo;
|
||||
}
|
||||
#endregion ADLAdapterInfo
|
||||
|
||||
|
||||
#region ADLDisplayInfo
|
||||
/// <summary> ADLDisplayID Structure</summary>
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal struct ADLDisplayID
|
||||
{
|
||||
/// <summary> Display Logical Index </summary>
|
||||
internal int DisplayLogicalIndex;
|
||||
/// <summary> Display Physical Index </summary>
|
||||
internal int DisplayPhysicalIndex;
|
||||
/// <summary> Adapter Logical Index </summary>
|
||||
internal int DisplayLogicalAdapterIndex;
|
||||
/// <summary> Adapter Physical Index </summary>
|
||||
internal int DisplayPhysicalAdapterIndex;
|
||||
}
|
||||
|
||||
/// <summary> ADLDisplayInfo Structure</summary>
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal struct ADLDisplayInfo
|
||||
{
|
||||
/// <summary> Display Index </summary>
|
||||
internal ADLDisplayID DisplayID;
|
||||
/// <summary> Display Controller Index </summary>
|
||||
internal int DisplayControllerIndex;
|
||||
/// <summary> Display Name </summary>
|
||||
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = (int)ADL.ADL_MAX_PATH)]
|
||||
internal string DisplayName;
|
||||
/// <summary> Display Manufacturer Name </summary>
|
||||
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = (int)ADL.ADL_MAX_PATH)]
|
||||
internal string DisplayManufacturerName;
|
||||
/// <summary> Display Type : < The Display type. CRT, TV,CV,DFP are some of display types,</summary>
|
||||
internal int DisplayType;
|
||||
/// <summary> Display output type </summary>
|
||||
internal int DisplayOutputType;
|
||||
/// <summary> Connector type</summary>
|
||||
internal int DisplayConnector;
|
||||
///<summary> Indicating the display info bits' mask.<summary>
|
||||
internal int DisplayInfoMask;
|
||||
///<summary> Indicating the display info value.<summary>
|
||||
internal int DisplayInfoValue;
|
||||
}
|
||||
#endregion ADLDisplayInfo
|
||||
|
||||
#endregion Export Struct
|
||||
|
||||
#region ADL Class
|
||||
/// <summary> ADL Class</summary>
|
||||
internal static class ADL
|
||||
{
|
||||
private static readonly NLog.Logger Logger = NLog.LogManager.GetCurrentClassLogger();
|
||||
|
||||
#region Internal Constant
|
||||
/// <summary> Define the maximum path</summary>
|
||||
internal const int ADL_MAX_PATH = 256;
|
||||
/// <summary> Define the maximum adapters</summary>
|
||||
internal const int ADL_MAX_ADAPTERS = 40 /* 150 */;
|
||||
/// <summary> Define the maximum displays</summary>
|
||||
internal const int ADL_MAX_DISPLAYS = 40 /* 150 */;
|
||||
/// <summary> Define the maximum device name length</summary>
|
||||
internal const int ADL_MAX_DEVICENAME = 32;
|
||||
/// <summary> Define the successful</summary>
|
||||
internal const int ADL_SUCCESS = 0;
|
||||
/// <summary> Define the failure</summary>
|
||||
internal const int ADL_FAIL = -1;
|
||||
/// <summary> Define the driver ok</summary>
|
||||
internal const int ADL_DRIVER_OK = 0;
|
||||
/// <summary> Maximum number of GL-Sync ports on the GL-Sync module </summary>
|
||||
internal const int ADL_MAX_GLSYNC_PORTS = 8;
|
||||
/// <summary> Maximum number of GL-Sync ports on the GL-Sync module </summary>
|
||||
internal const int ADL_MAX_GLSYNC_PORT_LEDS = 8;
|
||||
/// <summary> Maximum number of ADLMOdes for the adapter </summary>
|
||||
internal const int ADL_MAX_NUM_DISPLAYMODES = 1024;
|
||||
|
||||
internal static Dictionary<Type, object> ADLDelegates = new Dictionary<Type, object>();
|
||||
|
||||
#endregion Internal Constant
|
||||
|
||||
#region Export Delegates
|
||||
/// <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>
|
||||
internal delegate IntPtr 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>
|
||||
internal delegate int ADL_Main_Control_Create(ADL_Main_Memory_Alloc callback, int enumConnectedAdapters);
|
||||
|
||||
internal delegate int ADL2_Main_Control_Create(ADL_Main_Memory_Alloc callback, int enumConnectedAdapters, ref ADL_CONTEXT_HANDLE context);
|
||||
|
||||
/// <summary> ADL Destroy Function to free up ADL Data</summary>
|
||||
/// <returns> retrun ADL Error Code</returns>
|
||||
internal delegate int ADL_Main_Control_Destroy();
|
||||
|
||||
internal delegate int ADL2_Main_Control_Destroy(ADL_CONTEXT_HANDLE context);
|
||||
|
||||
/// <summary> ADL Function to get the number of adapters</summary>
|
||||
/// <param name="numAdapters">return number of adapters</param>
|
||||
/// <returns> retrun ADL Error Code</returns>
|
||||
internal delegate int ADL2_Adapter_NumberOfAdapters_Get(ADL_CONTEXT_HANDLE context, ref 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>
|
||||
internal delegate int ADL2_Adapter_AdapterInfo_Get(ADL_CONTEXT_HANDLE context, IntPtr 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>
|
||||
/// <param name="adapterIndex"> Adapter Index.</param>
|
||||
/// <param name="status"> Status of the adapter. True: Active; False: Dsiabled</param>
|
||||
/// <returns>Non zero is successfull</returns>
|
||||
internal delegate int ADL2_Adapter_Active_Get(ADL_CONTEXT_HANDLE context, int adapterIndex, ref int status);
|
||||
|
||||
/// <summary>Get display information based on adapter index</summary>
|
||||
/// <param name="adapterIndex">Adapter Index</param>
|
||||
/// <param name="numDisplays">return the total number of supported displays</param>
|
||||
/// <param name="displayInfoArray">return ADLDisplayInfo Array for supported displays' information</param>
|
||||
/// <param name="forceDetect">force detect or not</param>
|
||||
/// <returns>return ADL Error Code</returns>
|
||||
internal delegate int ADL2_Display_DisplayInfo_Get(ADL_CONTEXT_HANDLE context, int adapterIndex, ref int numDisplays, out IntPtr displayInfoArray, int forceDetect);
|
||||
|
||||
internal delegate int ADL2_Display_Size_Get(ADL_CONTEXT_HANDLE context, int adapterIndex, int displayIndex, ref int lpWidth, ref int lpHeight, ref int lpDefaultWidth, ref int lpDefaultHeight, ref int lpMinWidth, ref int lpMinHeight, ref int lpMaxWidth, ref int lpMaxHeight, ref int lpStepWidth, ref int lpStepHeight);
|
||||
|
||||
internal delegate int ADL2_Display_PixelFormat_Get(ADL_CONTEXT_HANDLE context, int adapterIndex, int displayIndex, ref int pixelFormat);
|
||||
internal delegate int ADL2_Display_PixelFormat_Set(ADL_CONTEXT_HANDLE context, int adapterIndex, int displayIndex, int pixelFormat);
|
||||
|
||||
internal delegate int ADL2_Display_ColorDepth_Get(ADL_CONTEXT_HANDLE context, int adapterIndex, int displayIndex, ref int colorDepth);
|
||||
internal delegate int ADL2_Display_ColorDepth_Set(ADL_CONTEXT_HANDLE context, int adapterIndex, int displayIndex, int colorDepth);
|
||||
|
||||
internal delegate int ADL2_Display_DitherState_Get(ADL_CONTEXT_HANDLE context, int adapterIndex, int displayIndex, ref int ditherState);
|
||||
internal delegate int ADL2_Display_DitherState_Set(ADL_CONTEXT_HANDLE context, int adapterIndex, int displayIndex, int ditherState);
|
||||
|
||||
internal delegate int ADL2_Display_HDRState_Get(ADL_CONTEXT_HANDLE context, int adapterIndex, ADLDisplayID displayID, ref int support, ref int enable);
|
||||
internal delegate int ADL2_Display_HDRState_Set(ADL_CONTEXT_HANDLE context, int adapterIndex, ADLDisplayID displayID, int enable);
|
||||
|
||||
#endregion Export Delegates
|
||||
|
||||
#region Class ADLImport
|
||||
/// <summary> ADLImport class</summary>
|
||||
private static class ADLImport
|
||||
{
|
||||
#region Internal Constant
|
||||
/// <summary> Atiadlxx_FileName </summary>
|
||||
internal const string Atiadlxx_FileName = "atiadlxx.dll";
|
||||
/// <summary> Kernel32_FileName </summary>
|
||||
internal const string Kernel32_FileName = "kernel32.dll";
|
||||
#endregion Internal Constant
|
||||
|
||||
#region DLLImport
|
||||
[DllImport(Kernel32_FileName)]
|
||||
internal static extern HMODULE GetModuleHandle(string moduleName);
|
||||
|
||||
[DllImport(Atiadlxx_FileName)]
|
||||
internal static extern int ADL_Main_Control_IsFunctionValid(HMODULE module, string procName);
|
||||
|
||||
[DllImport(Atiadlxx_FileName)]
|
||||
internal static extern FARPROC ADL_Main_Control_GetProcAddress(HMODULE module, string procName);
|
||||
|
||||
#endregion DLLImport
|
||||
}
|
||||
#endregion Class ADLImport
|
||||
|
||||
#region Class ADLCheckLibrary
|
||||
/// <summary> ADLCheckLibrary class</summary>
|
||||
private class ADLCheckLibrary
|
||||
{
|
||||
#region Private Members
|
||||
private HMODULE ADLLibrary = System.IntPtr.Zero;
|
||||
#endregion Private Members
|
||||
|
||||
#region Static Members
|
||||
/// <summary> new a private instance</summary>
|
||||
private static ADLCheckLibrary ADLCheckLibrary_ = new ADLCheckLibrary();
|
||||
#endregion Static Members
|
||||
|
||||
#region Constructor
|
||||
/// <summary> Constructor</summary>
|
||||
private ADLCheckLibrary()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (1 == ADLImport.ADL_Main_Control_IsFunctionValid(IntPtr.Zero, "ADL_Main_Control_Create"))
|
||||
{
|
||||
ADLLibrary = ADLImport.GetModuleHandle(ADLImport.Atiadlxx_FileName);
|
||||
}
|
||||
}
|
||||
catch (DllNotFoundException) { }
|
||||
catch (EntryPointNotFoundException) { }
|
||||
catch (Exception) { }
|
||||
}
|
||||
#endregion Constructor
|
||||
|
||||
#region Destructor
|
||||
/// <summary> Destructor to force calling ADL Destroy function before free up the ADL library</summary>
|
||||
~ADLCheckLibrary()
|
||||
{
|
||||
if (IntPtr.Zero != ADLCheckLibrary_.ADLLibrary)
|
||||
{
|
||||
var del = ADL.GetDelegate<ADL.ADL_Main_Control_Destroy>();
|
||||
if (del != null)
|
||||
{
|
||||
del();
|
||||
}
|
||||
}
|
||||
}
|
||||
#endregion Destructor
|
||||
|
||||
#region Static IsFunctionValid
|
||||
/// <summary> Check the import function to see it exists or not</summary>
|
||||
/// <param name="functionName"> function name</param>
|
||||
/// <returns>return true, if function exists</returns>
|
||||
internal static bool IsFunctionValid(string functionName)
|
||||
{
|
||||
var result = false;
|
||||
if (IntPtr.Zero != ADLCheckLibrary_.ADLLibrary)
|
||||
{
|
||||
if (1 == ADLImport.ADL_Main_Control_IsFunctionValid(ADLCheckLibrary_.ADLLibrary, functionName))
|
||||
{
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
#endregion Static IsFunctionValid
|
||||
|
||||
#region Static GetProcAddress
|
||||
/// <summary> Get the unmanaged function pointer </summary>
|
||||
/// <param name="functionName"> function name</param>
|
||||
/// <returns>return function pointer, if function exists</returns>
|
||||
internal static FARPROC GetProcAddress(string functionName)
|
||||
{
|
||||
var result = IntPtr.Zero;
|
||||
if (IntPtr.Zero != ADLCheckLibrary_.ADLLibrary)
|
||||
{
|
||||
result = ADLImport.ADL_Main_Control_GetProcAddress(ADLCheckLibrary_.ADLLibrary, functionName);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
#endregion Static GetProcAddress
|
||||
}
|
||||
#endregion Class ADLCheckLibrary
|
||||
|
||||
#region Export Functions
|
||||
|
||||
#region ADL_Main_Memory_Alloc
|
||||
/// <summary> Build in memory allocation function</summary>
|
||||
internal static ADL_Main_Memory_Alloc ADL_Main_Memory_Alloc_Func = ADL_Main_Memory_Alloc_;
|
||||
/// <summary> Build in memory allocation function</summary>
|
||||
/// <param name="size">input size</param>
|
||||
/// <returns>return the memory buffer</returns>
|
||||
private static IntPtr ADL_Main_Memory_Alloc_(int size)
|
||||
{
|
||||
IntPtr result = Marshal.AllocCoTaskMem(size);
|
||||
return result;
|
||||
}
|
||||
#endregion ADL_Main_Memory_Alloc
|
||||
|
||||
#region ADL_Main_Memory_Free
|
||||
/// <summary> Build in memory free function</summary>
|
||||
/// <param name="buffer">input buffer</param>
|
||||
internal static void ADL_Main_Memory_Free(IntPtr buffer)
|
||||
{
|
||||
if (IntPtr.Zero != buffer)
|
||||
{
|
||||
Marshal.FreeCoTaskMem(buffer);
|
||||
}
|
||||
}
|
||||
#endregion ADL_Main_Memory_Free
|
||||
|
||||
public static T GetDelegate<T>() where T : class
|
||||
{
|
||||
var type = typeof(T);
|
||||
|
||||
lock (ADLDelegates)
|
||||
{
|
||||
if (ADLDelegates.ContainsKey(type))
|
||||
{
|
||||
return ADLDelegates[type] as T;
|
||||
}
|
||||
|
||||
var ptr = ADLCheckLibrary.GetProcAddress(type.Name);
|
||||
if (ptr != FARPROC.Zero)
|
||||
{
|
||||
var delegateValue = Marshal.GetDelegateForFunctionPointer(ptr, type);
|
||||
ADLDelegates.Add(type, delegateValue);
|
||||
|
||||
return delegateValue as T;
|
||||
}
|
||||
}
|
||||
|
||||
Logger.Error($"ADL-function not supported: {type.Name}");
|
||||
|
||||
return null;
|
||||
//throw new InvalidProgramException("ADL-function not supported");
|
||||
}
|
||||
|
||||
#endregion Export Functions
|
||||
}
|
||||
#endregion ADL Class
|
||||
}
|
||||
|
||||
#endregion ATI.ADL
|
||||
@@ -0,0 +1,402 @@
|
||||
using ATI.ADL;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Windows.Forms;
|
||||
using ADL_CONTEXT_HANDLE = System.IntPtr;
|
||||
|
||||
namespace ColorControl.Services.AMD
|
||||
{
|
||||
enum ADLPixelFormat
|
||||
{
|
||||
[Description("Unknown/unsupported")]
|
||||
UNKNOWN = 0,
|
||||
RGB_FULL_RANGE = 1,
|
||||
YCRCB444 = 2,
|
||||
YCRCB422 = 3,
|
||||
RGB_LIMITED_RANGE = 4,
|
||||
YCRCB420 = 8
|
||||
}
|
||||
|
||||
enum ADLColorDepth
|
||||
{
|
||||
[Description("Unknown/unsupported")]
|
||||
UNKNOWN = 0,
|
||||
BPC6 = 1,
|
||||
BPC8 = 2,
|
||||
BPC10 = 3,
|
||||
BPC12 = 4,
|
||||
BPC14 = 5,
|
||||
BPC16 = 6
|
||||
}
|
||||
|
||||
enum ADLDitherState
|
||||
{
|
||||
DISABLED = 0,
|
||||
DRIVER_DEFAULT = 1,
|
||||
FM6 = 2,
|
||||
FM8 = 3,
|
||||
FM10 = 4,
|
||||
DITH6 = 5,
|
||||
DITH8 = 6,
|
||||
DITH10 = 7,
|
||||
DITH6_NO_FRAME_RAND = 8,
|
||||
DITH8_NO_FRAME_RAND = 9,
|
||||
DITH10_NO_FRAME_RAND = 10,
|
||||
TRUN6 = 11,
|
||||
TRUN8 = 12,
|
||||
TRUN10 = 13,
|
||||
TRUN8_DITH8 = 14,
|
||||
TRUN10_DITH6 = 15,
|
||||
TRUN10_FM8 = 16,
|
||||
TRUN10_FM6 = 17,
|
||||
TRUN10_DITH8_FM6 = 18,
|
||||
DITH10_FM8 = 19,
|
||||
DITH10_FM6 = 20,
|
||||
TRUN8_DITH6 = 21,
|
||||
TRUN8_FM6 = 22,
|
||||
DITH8_FM6 = 23
|
||||
}
|
||||
|
||||
class ADLWrapper
|
||||
{
|
||||
private static readonly NLog.Logger Logger = NLog.LogManager.GetCurrentClassLogger();
|
||||
private static ADL_CONTEXT_HANDLE context = IntPtr.Zero;
|
||||
|
||||
public static bool Initialize()
|
||||
{
|
||||
int ADLRet = -1;
|
||||
|
||||
//Logger.Debug("Initialize");
|
||||
|
||||
var del = ADL.GetDelegate<ADL.ADL_Main_Control_Create>();
|
||||
|
||||
if (del != null)
|
||||
{
|
||||
// Second parameter is 1: Get only the present adapters
|
||||
ADLRet = del(ADL.ADL_Main_Memory_Alloc_Func, 1);
|
||||
CheckError(ADLRet, nameof(ADL.ADL_Main_Control_Create));
|
||||
}
|
||||
|
||||
var del2 = ADL.GetDelegate<ADL.ADL2_Main_Control_Create>();
|
||||
|
||||
if (del2 != null)
|
||||
{
|
||||
// Second parameter is 1: Get only the present adapters
|
||||
ADLRet = del2(ADL.ADL_Main_Memory_Alloc_Func, 1, ref context);
|
||||
CheckError(ADLRet, nameof(ADL.ADL2_Main_Control_Create));
|
||||
}
|
||||
|
||||
return (ADL.ADL_SUCCESS == ADLRet);
|
||||
}
|
||||
|
||||
public static void Uninitialze()
|
||||
{
|
||||
if (!ADL.ADLDelegates.Any())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var del = ADL.GetDelegate<ADL.ADL_Main_Control_Destroy>();
|
||||
|
||||
if (null != del)
|
||||
{
|
||||
del();
|
||||
}
|
||||
|
||||
var del2 = ADL.GetDelegate<ADL.ADL2_Main_Control_Destroy>();
|
||||
|
||||
if (null != del2 && context != IntPtr.Zero)
|
||||
{
|
||||
del2(context);
|
||||
}
|
||||
}
|
||||
|
||||
public static ADLAdapterInfoArray? GetAdapters()
|
||||
{
|
||||
int ADLRet = -1;
|
||||
int NumberOfAdapters = 0;
|
||||
|
||||
var delNumberOfAdapters = ADL.GetDelegate<ADL.ADL2_Adapter_NumberOfAdapters_Get>();
|
||||
|
||||
if (null != delNumberOfAdapters)
|
||||
{
|
||||
delNumberOfAdapters(context, ref NumberOfAdapters);
|
||||
}
|
||||
Logger.Debug("Number Of Adapters: " + NumberOfAdapters.ToString() + "\n");
|
||||
|
||||
if (NumberOfAdapters > 0)
|
||||
{
|
||||
// Get OS adpater info from ADL
|
||||
ADLAdapterInfoArray OSAdapterInfoData;
|
||||
OSAdapterInfoData = new ADLAdapterInfoArray();
|
||||
|
||||
var delAdapterInfo = ADL.GetDelegate<ADL.ADL2_Adapter_AdapterInfo_Get>();
|
||||
|
||||
if (null != delAdapterInfo)
|
||||
{
|
||||
IntPtr AdapterBuffer = IntPtr.Zero;
|
||||
int size = Marshal.SizeOf(OSAdapterInfoData);
|
||||
AdapterBuffer = Marshal.AllocCoTaskMem((int)size);
|
||||
Marshal.StructureToPtr(OSAdapterInfoData, AdapterBuffer, false);
|
||||
|
||||
ADLRet = delAdapterInfo(context, AdapterBuffer, size);
|
||||
if (ADL.ADL_SUCCESS == ADLRet)
|
||||
{
|
||||
OSAdapterInfoData = (ADLAdapterInfoArray)Marshal.PtrToStructure(AdapterBuffer, OSAdapterInfoData.GetType());
|
||||
int IsActive = 0;
|
||||
|
||||
var delActive = ADL.GetDelegate<ADL.ADL2_Adapter_Active_Get>();
|
||||
|
||||
for (int i = 0; i < NumberOfAdapters; i++)
|
||||
{
|
||||
// Check if the adapter is active
|
||||
if (null != delActive)
|
||||
ADLRet = delActive(context, OSAdapterInfoData.ADLAdapterInfo[i].AdapterIndex, ref IsActive);
|
||||
|
||||
if (ADL.ADL_SUCCESS == ADLRet)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger.Debug("ADL_Adapter_AdapterInfo_Get() returned error code " + ADLRet.ToString());
|
||||
}
|
||||
// Release the memory for the AdapterInfo structure
|
||||
if (IntPtr.Zero != AdapterBuffer)
|
||||
{
|
||||
Marshal.FreeCoTaskMem(AdapterBuffer);
|
||||
}
|
||||
}
|
||||
return OSAdapterInfoData;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static List<ADLDisplayInfo> GetAllDisplays(bool connected = true)
|
||||
{
|
||||
int ADLRet;
|
||||
int NumberOfDisplays = 0;
|
||||
|
||||
var DisplayInfoData = new List<ADLDisplayInfo>();
|
||||
|
||||
var OSAdapterInfoData = GetAdapters();
|
||||
if (OSAdapterInfoData == null || !OSAdapterInfoData.Value.ADLAdapterInfo.Any())
|
||||
{
|
||||
return DisplayInfoData;
|
||||
}
|
||||
var primaryAdapter = OSAdapterInfoData.Value.ADLAdapterInfo.First();
|
||||
|
||||
ADLDisplayInfo oneDisplayInfo = new ADLDisplayInfo();
|
||||
|
||||
var del = ADL.GetDelegate<ADL.ADL2_Display_DisplayInfo_Get>();
|
||||
|
||||
if (null != del)
|
||||
{
|
||||
IntPtr DisplayBuffer = IntPtr.Zero;
|
||||
int j = 0;
|
||||
|
||||
// Force the display detection and get the Display Info. Use 0 as last parameter to NOT force detection
|
||||
ADLRet = del(context, primaryAdapter.AdapterIndex, ref NumberOfDisplays, out DisplayBuffer, 1);
|
||||
if (ADL.ADL_SUCCESS == ADLRet)
|
||||
{
|
||||
for (j = 0; j < NumberOfDisplays; j++)
|
||||
{
|
||||
oneDisplayInfo = (ADLDisplayInfo)Marshal.PtrToStructure(new IntPtr(DisplayBuffer.ToInt64() + j * Marshal.SizeOf(oneDisplayInfo)), oneDisplayInfo.GetType());
|
||||
if (!connected || (1 == (oneDisplayInfo.DisplayInfoValue & 1)))
|
||||
{
|
||||
DisplayInfoData.Add(oneDisplayInfo);
|
||||
}
|
||||
}
|
||||
Logger.Debug("Total Number of Displays supported: " + NumberOfDisplays.ToString());
|
||||
Logger.Debug("DispID DispPhyId AdpID Type OutType CnctType Connected Mapped InfoValue DisplayName ");
|
||||
|
||||
for (j = 0; j < DisplayInfoData.Count; j++)
|
||||
{
|
||||
int InfoValue = DisplayInfoData[j].DisplayInfoValue;
|
||||
string StrConnected = (1 == (InfoValue & 1)) ? "Yes" : "No ";
|
||||
string StrMapped = (2 == (InfoValue & 2)) ? "Yes" : "No ";
|
||||
int AdpID = DisplayInfoData[j].DisplayID.DisplayLogicalAdapterIndex;
|
||||
string StrAdpID = (AdpID < 0) ? "--" : AdpID.ToString("d2");
|
||||
|
||||
Logger.Debug(DisplayInfoData[j].DisplayID.DisplayLogicalIndex.ToString() + " " +
|
||||
DisplayInfoData[j].DisplayID.DisplayPhysicalIndex.ToString() + " " +
|
||||
StrAdpID + " " +
|
||||
DisplayInfoData[j].DisplayType.ToString() + " " +
|
||||
DisplayInfoData[j].DisplayOutputType.ToString() + " " +
|
||||
DisplayInfoData[j].DisplayConnector.ToString() + " " +
|
||||
StrConnected + " " +
|
||||
StrMapped + " " +
|
||||
InfoValue.ToString("x4") + " " +
|
||||
DisplayInfoData[j].DisplayName.ToString());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger.Debug("ADL_Display_DisplayInfo_Get() returned error code " + ADLRet.ToString());
|
||||
}
|
||||
// Release the memory for the DisplayInfo structure
|
||||
if (IntPtr.Zero != DisplayBuffer)
|
||||
Marshal.FreeCoTaskMem(DisplayBuffer);
|
||||
}
|
||||
return DisplayInfoData;
|
||||
}
|
||||
|
||||
private static bool CheckError(int ADLRet, string functionName)
|
||||
{
|
||||
var result = ADLRet == ADL.ADL_SUCCESS;
|
||||
|
||||
if (!result)
|
||||
{
|
||||
Logger.Error($"Error calling ADL ({functionName}): {ADLRet}");
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static bool GetDisplayResolution(ADLDisplayInfo display, ref int horizontal, ref int vertical)
|
||||
{
|
||||
var screen = Screen.PrimaryScreen;
|
||||
var bounds = screen.Bounds;
|
||||
|
||||
horizontal = bounds.Width;
|
||||
vertical = bounds.Height;
|
||||
|
||||
Logger.Debug($"GetDisplayResolution: {horizontal}x{vertical}");
|
||||
|
||||
//var del = ADL.GetDelegate<ADL.ADL2_Display_Size_Get>();
|
||||
|
||||
//if (display.DisplayID.DisplayPhysicalIndex >= 0 && del != null)
|
||||
//{
|
||||
// int lpDefaultWidth, lpDefaultHeight, lpMinWidth, lpMinHeight, lpMaxWidth, lpMaxHeight, lpStepWidth, lpStepHeight;
|
||||
// lpDefaultWidth = lpDefaultHeight = lpMinWidth = lpMinHeight = lpMaxWidth = lpMaxHeight = lpStepWidth = lpStepHeight = 0;
|
||||
// var ADLRet = del(context, display.DisplayID.DisplayLogicalAdapterIndex, display.DisplayID.DisplayLogicalIndex, ref horizontal, ref vertical, ref lpDefaultWidth, ref lpDefaultHeight, ref lpMinWidth, ref lpMinHeight, ref lpMaxWidth, ref lpMaxHeight, ref lpStepWidth, ref lpStepHeight);
|
||||
|
||||
// return CheckError(ADLRet, nameof(ADL.ADL2_Display_Size_Get));
|
||||
//}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static bool GetDisplayPixelFormat(ADLDisplayInfo display, ref ADLPixelFormat pixelFormat)
|
||||
{
|
||||
var del = ADL.GetDelegate<ADL.ADL2_Display_PixelFormat_Get>();
|
||||
|
||||
if (display.DisplayID.DisplayPhysicalIndex >= 0 && del != null)
|
||||
{
|
||||
int pixelFormatInt = 0;
|
||||
var ADLRet = del(context, display.DisplayID.DisplayLogicalAdapterIndex, display.DisplayID.DisplayLogicalIndex, ref pixelFormatInt);
|
||||
|
||||
pixelFormat = (ADLPixelFormat)pixelFormatInt;
|
||||
|
||||
return CheckError(ADLRet, nameof(ADL.ADL2_Display_PixelFormat_Get));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool SetDisplayPixelFormat(ADLDisplayInfo display, ADLPixelFormat pixelFormat)
|
||||
{
|
||||
var del = ADL.GetDelegate<ADL.ADL2_Display_PixelFormat_Set>();
|
||||
|
||||
if (display.DisplayID.DisplayPhysicalIndex >= 0 && del != null)
|
||||
{
|
||||
var ADLRet = del(context, display.DisplayID.DisplayLogicalAdapterIndex, display.DisplayID.DisplayLogicalIndex, (int)pixelFormat);
|
||||
|
||||
return CheckError(ADLRet, nameof(ADL.ADL2_Display_PixelFormat_Set));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool GetDisplayColorDepth(ADLDisplayInfo display, ref ADLColorDepth colorDepth)
|
||||
{
|
||||
var del = ADL.GetDelegate<ADL.ADL2_Display_ColorDepth_Get>();
|
||||
|
||||
if (display.DisplayID.DisplayPhysicalIndex >= 0 && del != null)
|
||||
{
|
||||
int colorDepthInt = 0;
|
||||
var ADLRet = del(context, display.DisplayID.DisplayLogicalAdapterIndex, display.DisplayID.DisplayLogicalIndex, ref colorDepthInt);
|
||||
|
||||
colorDepth = (ADLColorDepth)colorDepthInt;
|
||||
|
||||
return CheckError(ADLRet, nameof(ADL.ADL2_Display_ColorDepth_Get));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool SetDisplayColorDepth(ADLDisplayInfo display, ADLColorDepth colorDepth)
|
||||
{
|
||||
var del = ADL.GetDelegate<ADL.ADL2_Display_ColorDepth_Set>();
|
||||
|
||||
if (display.DisplayID.DisplayPhysicalIndex >= 0 && del != null)
|
||||
{
|
||||
var ADLRet = del(context, display.DisplayID.DisplayLogicalAdapterIndex, display.DisplayID.DisplayLogicalIndex, (int)colorDepth);
|
||||
|
||||
return CheckError(ADLRet, nameof(ADL.ADL2_Display_ColorDepth_Set));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool GetDisplayDitherState(ADLDisplayInfo display, ref ADLDitherState ditherState)
|
||||
{
|
||||
var del = ADL.GetDelegate<ADL.ADL2_Display_DitherState_Get>();
|
||||
|
||||
if (display.DisplayID.DisplayPhysicalIndex >= 0 && del != null)
|
||||
{
|
||||
var ditherStateInt = 0;
|
||||
var ADLRet = del(context, display.DisplayID.DisplayLogicalAdapterIndex, display.DisplayID.DisplayLogicalIndex, ref ditherStateInt);
|
||||
|
||||
ditherState = (ADLDitherState)ditherStateInt;
|
||||
|
||||
return CheckError(ADLRet, nameof(ADL.ADL2_Display_DitherState_Get));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool SetDisplayDitherState(ADLDisplayInfo display, ADLDitherState ditherState)
|
||||
{
|
||||
var del = ADL.GetDelegate<ADL.ADL2_Display_DitherState_Set>();
|
||||
|
||||
if (display.DisplayID.DisplayPhysicalIndex >= 0 && del != null)
|
||||
{
|
||||
var ADLRet = del(context, display.DisplayID.DisplayLogicalAdapterIndex, display.DisplayID.DisplayLogicalIndex, (int)ditherState);
|
||||
|
||||
return CheckError(ADLRet, nameof(ADL.ADL2_Display_DitherState_Set));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool GetDisplayHDRState(ADLDisplayInfo display, ref bool supported, ref bool enabled)
|
||||
{
|
||||
var del = ADL.GetDelegate<ADL.ADL2_Display_HDRState_Get>();
|
||||
|
||||
if (display.DisplayID.DisplayPhysicalIndex >= 0 && del != null)
|
||||
{
|
||||
var supportedInt = 0;
|
||||
var enabledInt = 0;
|
||||
var ADLRet = del(context, display.DisplayID.DisplayLogicalAdapterIndex, display.DisplayID, ref supportedInt, ref enabledInt);
|
||||
|
||||
supported = supportedInt != 0;
|
||||
enabled = enabledInt != 0;
|
||||
|
||||
return CheckError(ADLRet, nameof(ADL.ADL2_Display_HDRState_Get));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool SetDisplayHDRState(ADLDisplayInfo display, bool enabled)
|
||||
{
|
||||
var del = ADL.GetDelegate<ADL.ADL2_Display_HDRState_Set>();
|
||||
|
||||
if (display.DisplayID.DisplayPhysicalIndex >= 0 && del != null)
|
||||
{
|
||||
var ADLRet = del(context, display.DisplayID.DisplayLogicalAdapterIndex, display.DisplayID, enabled ? 1 : 0);
|
||||
|
||||
return CheckError(ADLRet, nameof(ADL.ADL2_Display_HDRState_Set));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
using ATI.ADL;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace ColorControl.Services.AMD
|
||||
{
|
||||
class AmdDisplayInfo
|
||||
{
|
||||
public ADLDisplayInfo Display { get; }
|
||||
|
||||
public List<string> Values { get; }
|
||||
|
||||
public string InfoLine { get; }
|
||||
|
||||
public AmdDisplayInfo(ADLDisplayInfo display, List<string> values, string infoLine)
|
||||
{
|
||||
Display = display;
|
||||
Values = values;
|
||||
InfoLine = infoLine;
|
||||
}
|
||||
}
|
||||
}
|
||||
+446
@@ -0,0 +1,446 @@
|
||||
namespace ColorControl.Services.AMD
|
||||
{
|
||||
partial class AmdPanel
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Component Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.components = new System.ComponentModel.Container();
|
||||
this.btnAmdSettings = new System.Windows.Forms.Button();
|
||||
this.chkAmdQuickAccess = new System.Windows.Forms.CheckBox();
|
||||
this.lblAmdPresetName = new System.Windows.Forms.Label();
|
||||
this.edtAmdPresetName = new System.Windows.Forms.TextBox();
|
||||
this.btnAddAmd = new System.Windows.Forms.Button();
|
||||
this.lblErrorAMD = new System.Windows.Forms.Label();
|
||||
this.btnDeleteAmd = new System.Windows.Forms.Button();
|
||||
this.btnCloneAmd = new System.Windows.Forms.Button();
|
||||
this.btnAmdPresetSave = new System.Windows.Forms.Button();
|
||||
this.lblAmdShortcut = new System.Windows.Forms.Label();
|
||||
this.edtAmdShortcut = new System.Windows.Forms.TextBox();
|
||||
this.btnChangeAmd = new System.Windows.Forms.Button();
|
||||
this.mnuAmdPresets = new System.Windows.Forms.ContextMenuStrip(this.components);
|
||||
this.miAmdApply = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.miAmdPresetApplyOnStartup = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.toolStripSeparator2 = new System.Windows.Forms.ToolStripSeparator();
|
||||
this.mnuAmdDisplay = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.miAmdPrimaryDisplay = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.mnuAmdColorSettings = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.miAmdColorSettingsIncluded = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.mnuAmdRefreshRate = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.miAmdRefreshRateIncluded = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.mnuAmdDithering = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.miAmdDitheringIncluded = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.mnuAmdHDR = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.miAmdHDRIncluded = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.miAmdHDRToggle = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.miAmdHDREnabled = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.miAmdCopyId = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.btnApplyAmd = new System.Windows.Forms.Button();
|
||||
this.lvAmdPresets = new System.Windows.Forms.ListView();
|
||||
this.mnuAmdPresets.SuspendLayout();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// btnAmdSettings
|
||||
//
|
||||
this.btnAmdSettings.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.btnAmdSettings.Location = new System.Drawing.Point(1017, 429);
|
||||
this.btnAmdSettings.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
this.btnAmdSettings.Name = "btnAmdSettings";
|
||||
this.btnAmdSettings.Size = new System.Drawing.Size(88, 27);
|
||||
this.btnAmdSettings.TabIndex = 60;
|
||||
this.btnAmdSettings.Text = "Settings...";
|
||||
this.btnAmdSettings.UseVisualStyleBackColor = true;
|
||||
this.btnAmdSettings.Click += new System.EventHandler(this.btnAmdSettings_Click);
|
||||
//
|
||||
// chkAmdQuickAccess
|
||||
//
|
||||
this.chkAmdQuickAccess.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
|
||||
this.chkAmdQuickAccess.AutoSize = true;
|
||||
this.chkAmdQuickAccess.Enabled = false;
|
||||
this.chkAmdQuickAccess.Location = new System.Drawing.Point(343, 465);
|
||||
this.chkAmdQuickAccess.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
this.chkAmdQuickAccess.Name = "chkAmdQuickAccess";
|
||||
this.chkAmdQuickAccess.Size = new System.Drawing.Size(141, 19);
|
||||
this.chkAmdQuickAccess.TabIndex = 46;
|
||||
this.chkAmdQuickAccess.Text = "Show in Quick Access";
|
||||
this.chkAmdQuickAccess.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// lblAmdPresetName
|
||||
//
|
||||
this.lblAmdPresetName.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
|
||||
this.lblAmdPresetName.AutoSize = true;
|
||||
this.lblAmdPresetName.Location = new System.Drawing.Point(7, 466);
|
||||
this.lblAmdPresetName.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
|
||||
this.lblAmdPresetName.Name = "lblAmdPresetName";
|
||||
this.lblAmdPresetName.Size = new System.Drawing.Size(42, 15);
|
||||
this.lblAmdPresetName.TabIndex = 24;
|
||||
this.lblAmdPresetName.Text = "Name:";
|
||||
//
|
||||
// edtAmdPresetName
|
||||
//
|
||||
this.edtAmdPresetName.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
|
||||
this.edtAmdPresetName.Enabled = false;
|
||||
this.edtAmdPresetName.Location = new System.Drawing.Point(102, 463);
|
||||
this.edtAmdPresetName.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
this.edtAmdPresetName.Name = "edtAmdPresetName";
|
||||
this.edtAmdPresetName.Size = new System.Drawing.Size(233, 23);
|
||||
this.edtAmdPresetName.TabIndex = 23;
|
||||
//
|
||||
// btnAddAmd
|
||||
//
|
||||
this.btnAddAmd.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
|
||||
this.btnAddAmd.Location = new System.Drawing.Point(385, 429);
|
||||
this.btnAddAmd.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
this.btnAddAmd.Name = "btnAddAmd";
|
||||
this.btnAddAmd.Size = new System.Drawing.Size(88, 27);
|
||||
this.btnAddAmd.TabIndex = 18;
|
||||
this.btnAddAmd.Text = "Add";
|
||||
this.btnAddAmd.UseVisualStyleBackColor = true;
|
||||
this.btnAddAmd.Click += new System.EventHandler(this.btnAddAmd_Click);
|
||||
//
|
||||
// lblErrorAMD
|
||||
//
|
||||
this.lblErrorAMD.AutoSize = true;
|
||||
this.lblErrorAMD.Location = new System.Drawing.Point(7, 7);
|
||||
this.lblErrorAMD.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
|
||||
this.lblErrorAMD.Name = "lblErrorAMD";
|
||||
this.lblErrorAMD.Size = new System.Drawing.Size(53, 15);
|
||||
this.lblErrorAMD.TabIndex = 8;
|
||||
this.lblErrorAMD.Text = "ErrorText";
|
||||
this.lblErrorAMD.Visible = false;
|
||||
//
|
||||
// btnDeleteAmd
|
||||
//
|
||||
this.btnDeleteAmd.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
|
||||
this.btnDeleteAmd.Enabled = false;
|
||||
this.btnDeleteAmd.Location = new System.Drawing.Point(290, 429);
|
||||
this.btnDeleteAmd.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
this.btnDeleteAmd.Name = "btnDeleteAmd";
|
||||
this.btnDeleteAmd.Size = new System.Drawing.Size(88, 27);
|
||||
this.btnDeleteAmd.TabIndex = 17;
|
||||
this.btnDeleteAmd.Text = "Delete";
|
||||
this.btnDeleteAmd.UseVisualStyleBackColor = true;
|
||||
this.btnDeleteAmd.Click += new System.EventHandler(this.btnDeleteAmd_Click);
|
||||
//
|
||||
// btnCloneAmd
|
||||
//
|
||||
this.btnCloneAmd.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
|
||||
this.btnCloneAmd.Enabled = false;
|
||||
this.btnCloneAmd.Location = new System.Drawing.Point(196, 429);
|
||||
this.btnCloneAmd.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
this.btnCloneAmd.Name = "btnCloneAmd";
|
||||
this.btnCloneAmd.Size = new System.Drawing.Size(88, 27);
|
||||
this.btnCloneAmd.TabIndex = 16;
|
||||
this.btnCloneAmd.Text = "Clone";
|
||||
this.btnCloneAmd.UseVisualStyleBackColor = true;
|
||||
this.btnCloneAmd.Click += new System.EventHandler(this.btnCloneAmd_Click);
|
||||
//
|
||||
// btnAmdPresetSave
|
||||
//
|
||||
this.btnAmdPresetSave.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
|
||||
this.btnAmdPresetSave.Enabled = false;
|
||||
this.btnAmdPresetSave.Location = new System.Drawing.Point(479, 429);
|
||||
this.btnAmdPresetSave.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
this.btnAmdPresetSave.Name = "btnAmdPresetSave";
|
||||
this.btnAmdPresetSave.Size = new System.Drawing.Size(88, 27);
|
||||
this.btnAmdPresetSave.TabIndex = 15;
|
||||
this.btnAmdPresetSave.Text = "Save";
|
||||
this.btnAmdPresetSave.UseVisualStyleBackColor = true;
|
||||
this.btnAmdPresetSave.Click += new System.EventHandler(this.btnSetAmdShortcut_Click);
|
||||
//
|
||||
// lblAmdShortcut
|
||||
//
|
||||
this.lblAmdShortcut.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
|
||||
this.lblAmdShortcut.AutoSize = true;
|
||||
this.lblAmdShortcut.Location = new System.Drawing.Point(7, 496);
|
||||
this.lblAmdShortcut.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
|
||||
this.lblAmdShortcut.Name = "lblAmdShortcut";
|
||||
this.lblAmdShortcut.Size = new System.Drawing.Size(55, 15);
|
||||
this.lblAmdShortcut.TabIndex = 14;
|
||||
this.lblAmdShortcut.Text = "Shortcut:";
|
||||
//
|
||||
// edtAmdShortcut
|
||||
//
|
||||
this.edtAmdShortcut.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
|
||||
this.edtAmdShortcut.Enabled = false;
|
||||
this.edtAmdShortcut.Location = new System.Drawing.Point(102, 493);
|
||||
this.edtAmdShortcut.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
this.edtAmdShortcut.Name = "edtAmdShortcut";
|
||||
this.edtAmdShortcut.ReadOnly = true;
|
||||
this.edtAmdShortcut.Size = new System.Drawing.Size(233, 23);
|
||||
this.edtAmdShortcut.TabIndex = 13;
|
||||
this.edtAmdShortcut.TextChanged += new System.EventHandler(this.edtAmdShortcut_TextChanged);
|
||||
this.edtAmdShortcut.KeyDown += new System.Windows.Forms.KeyEventHandler(this.edtShortcut_KeyDown);
|
||||
this.edtAmdShortcut.KeyUp += new System.Windows.Forms.KeyEventHandler(this.edtShortcut_KeyUp);
|
||||
//
|
||||
// btnChangeAmd
|
||||
//
|
||||
this.btnChangeAmd.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
|
||||
this.btnChangeAmd.ContextMenuStrip = this.mnuAmdPresets;
|
||||
this.btnChangeAmd.Enabled = false;
|
||||
this.btnChangeAmd.Location = new System.Drawing.Point(102, 429);
|
||||
this.btnChangeAmd.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
this.btnChangeAmd.Name = "btnChangeAmd";
|
||||
this.btnChangeAmd.Size = new System.Drawing.Size(88, 27);
|
||||
this.btnChangeAmd.TabIndex = 12;
|
||||
this.btnChangeAmd.Text = "Change...";
|
||||
this.btnChangeAmd.UseVisualStyleBackColor = true;
|
||||
this.btnChangeAmd.Click += new System.EventHandler(this.btnChangeAmd_Click);
|
||||
//
|
||||
// mnuAmdPresets
|
||||
//
|
||||
this.mnuAmdPresets.ImageScalingSize = new System.Drawing.Size(20, 20);
|
||||
this.mnuAmdPresets.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
||||
this.miAmdApply,
|
||||
this.miAmdPresetApplyOnStartup,
|
||||
this.toolStripSeparator2,
|
||||
this.mnuAmdDisplay,
|
||||
this.mnuAmdColorSettings,
|
||||
this.mnuAmdRefreshRate,
|
||||
this.mnuAmdDithering,
|
||||
this.mnuAmdHDR,
|
||||
this.miAmdCopyId});
|
||||
this.mnuAmdPresets.Name = "mnuNvPresets";
|
||||
this.mnuAmdPresets.Size = new System.Drawing.Size(185, 186);
|
||||
this.mnuAmdPresets.Opening += new System.ComponentModel.CancelEventHandler(this.mnuAmdPresets_Opening);
|
||||
//
|
||||
// miAmdApply
|
||||
//
|
||||
this.miAmdApply.Name = "miAmdApply";
|
||||
this.miAmdApply.Size = new System.Drawing.Size(184, 22);
|
||||
this.miAmdApply.Text = "Apply";
|
||||
this.miAmdApply.Click += new System.EventHandler(this.btnApplyAmd_Click);
|
||||
//
|
||||
// miAmdPresetApplyOnStartup
|
||||
//
|
||||
this.miAmdPresetApplyOnStartup.CheckOnClick = true;
|
||||
this.miAmdPresetApplyOnStartup.Name = "miAmdPresetApplyOnStartup";
|
||||
this.miAmdPresetApplyOnStartup.Size = new System.Drawing.Size(184, 22);
|
||||
this.miAmdPresetApplyOnStartup.Text = "Apply on startup";
|
||||
this.miAmdPresetApplyOnStartup.Click += new System.EventHandler(this.miAmdPresetApplyOnStartup_Click);
|
||||
//
|
||||
// toolStripSeparator2
|
||||
//
|
||||
this.toolStripSeparator2.Name = "toolStripSeparator2";
|
||||
this.toolStripSeparator2.Size = new System.Drawing.Size(181, 6);
|
||||
//
|
||||
// mnuAmdDisplay
|
||||
//
|
||||
this.mnuAmdDisplay.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
||||
this.miAmdPrimaryDisplay});
|
||||
this.mnuAmdDisplay.Name = "mnuAmdDisplay";
|
||||
this.mnuAmdDisplay.Size = new System.Drawing.Size(184, 22);
|
||||
this.mnuAmdDisplay.Text = "Display";
|
||||
//
|
||||
// miAmdPrimaryDisplay
|
||||
//
|
||||
this.miAmdPrimaryDisplay.Name = "miAmdPrimaryDisplay";
|
||||
this.miAmdPrimaryDisplay.Size = new System.Drawing.Size(155, 22);
|
||||
this.miAmdPrimaryDisplay.Text = "Primary display";
|
||||
this.miAmdPrimaryDisplay.Click += new System.EventHandler(this.displayMenuItemAmd_Click);
|
||||
//
|
||||
// mnuAmdColorSettings
|
||||
//
|
||||
this.mnuAmdColorSettings.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
||||
this.miAmdColorSettingsIncluded});
|
||||
this.mnuAmdColorSettings.Name = "mnuAmdColorSettings";
|
||||
this.mnuAmdColorSettings.Size = new System.Drawing.Size(184, 22);
|
||||
this.mnuAmdColorSettings.Text = "Color settings";
|
||||
//
|
||||
// miAmdColorSettingsIncluded
|
||||
//
|
||||
this.miAmdColorSettingsIncluded.Name = "miAmdColorSettingsIncluded";
|
||||
this.miAmdColorSettingsIncluded.Size = new System.Drawing.Size(120, 22);
|
||||
this.miAmdColorSettingsIncluded.Text = "Included";
|
||||
this.miAmdColorSettingsIncluded.Click += new System.EventHandler(this.miAmdColorSettingsIncluded_Click);
|
||||
//
|
||||
// mnuAmdRefreshRate
|
||||
//
|
||||
this.mnuAmdRefreshRate.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
||||
this.miAmdRefreshRateIncluded});
|
||||
this.mnuAmdRefreshRate.Name = "mnuAmdRefreshRate";
|
||||
this.mnuAmdRefreshRate.Size = new System.Drawing.Size(184, 22);
|
||||
this.mnuAmdRefreshRate.Text = "Refresh Rate";
|
||||
//
|
||||
// miAmdRefreshRateIncluded
|
||||
//
|
||||
this.miAmdRefreshRateIncluded.Name = "miAmdRefreshRateIncluded";
|
||||
this.miAmdRefreshRateIncluded.Size = new System.Drawing.Size(120, 22);
|
||||
this.miAmdRefreshRateIncluded.Text = "Included";
|
||||
this.miAmdRefreshRateIncluded.Click += new System.EventHandler(this.miAmdRefreshRateIncluded_Click);
|
||||
//
|
||||
// mnuAmdDithering
|
||||
//
|
||||
this.mnuAmdDithering.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
||||
this.miAmdDitheringIncluded});
|
||||
this.mnuAmdDithering.Name = "mnuAmdDithering";
|
||||
this.mnuAmdDithering.Size = new System.Drawing.Size(184, 22);
|
||||
this.mnuAmdDithering.Text = "Dithering";
|
||||
//
|
||||
// miAmdDitheringIncluded
|
||||
//
|
||||
this.miAmdDitheringIncluded.Name = "miAmdDitheringIncluded";
|
||||
this.miAmdDitheringIncluded.Size = new System.Drawing.Size(120, 22);
|
||||
this.miAmdDitheringIncluded.Text = "Included";
|
||||
this.miAmdDitheringIncluded.Click += new System.EventHandler(this.miAmdDitheringIncluded_Click);
|
||||
//
|
||||
// mnuAmdHDR
|
||||
//
|
||||
this.mnuAmdHDR.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
||||
this.miAmdHDRIncluded,
|
||||
this.miAmdHDRToggle,
|
||||
this.miAmdHDREnabled});
|
||||
this.mnuAmdHDR.Name = "mnuAmdHDR";
|
||||
this.mnuAmdHDR.Size = new System.Drawing.Size(184, 22);
|
||||
this.mnuAmdHDR.Text = "HDR";
|
||||
//
|
||||
// miAmdHDRIncluded
|
||||
//
|
||||
this.miAmdHDRIncluded.Name = "miAmdHDRIncluded";
|
||||
this.miAmdHDRIncluded.Size = new System.Drawing.Size(136, 22);
|
||||
this.miAmdHDRIncluded.Text = "Included";
|
||||
this.miAmdHDRIncluded.Click += new System.EventHandler(this.miAmdHDRIncluded_Click);
|
||||
//
|
||||
// miAmdHDRToggle
|
||||
//
|
||||
this.miAmdHDRToggle.Name = "miAmdHDRToggle";
|
||||
this.miAmdHDRToggle.Size = new System.Drawing.Size(136, 22);
|
||||
this.miAmdHDRToggle.Text = "Toggle HDR";
|
||||
this.miAmdHDRToggle.Click += new System.EventHandler(this.miAmdHDRToggle_Click);
|
||||
//
|
||||
// miAmdHDREnabled
|
||||
//
|
||||
this.miAmdHDREnabled.Name = "miAmdHDREnabled";
|
||||
this.miAmdHDREnabled.Size = new System.Drawing.Size(136, 22);
|
||||
this.miAmdHDREnabled.Text = "Enabled";
|
||||
this.miAmdHDREnabled.Click += new System.EventHandler(this.miAmdHDREnabled_Click);
|
||||
//
|
||||
// miAmdCopyId
|
||||
//
|
||||
this.miAmdCopyId.Name = "miAmdCopyId";
|
||||
this.miAmdCopyId.Size = new System.Drawing.Size(184, 22);
|
||||
this.miAmdCopyId.Text = "Copy Id to Clipboard";
|
||||
this.miAmdCopyId.Click += new System.EventHandler(this.miAmdCopyId_Click);
|
||||
//
|
||||
// btnApplyAmd
|
||||
//
|
||||
this.btnApplyAmd.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
|
||||
this.btnApplyAmd.Enabled = false;
|
||||
this.btnApplyAmd.Location = new System.Drawing.Point(7, 429);
|
||||
this.btnApplyAmd.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
this.btnApplyAmd.Name = "btnApplyAmd";
|
||||
this.btnApplyAmd.Size = new System.Drawing.Size(88, 27);
|
||||
this.btnApplyAmd.TabIndex = 11;
|
||||
this.btnApplyAmd.Text = "Apply";
|
||||
this.btnApplyAmd.UseVisualStyleBackColor = true;
|
||||
this.btnApplyAmd.Click += new System.EventHandler(this.btnApplyAmd_Click);
|
||||
//
|
||||
// lvAmdPresets
|
||||
//
|
||||
this.lvAmdPresets.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
|
||||
| System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.lvAmdPresets.CheckBoxes = true;
|
||||
this.lvAmdPresets.ContextMenuStrip = this.mnuAmdPresets;
|
||||
this.lvAmdPresets.FullRowSelect = true;
|
||||
this.lvAmdPresets.Location = new System.Drawing.Point(7, 7);
|
||||
this.lvAmdPresets.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
this.lvAmdPresets.MultiSelect = false;
|
||||
this.lvAmdPresets.Name = "lvAmdPresets";
|
||||
this.lvAmdPresets.ShowItemToolTips = true;
|
||||
this.lvAmdPresets.Size = new System.Drawing.Size(1098, 415);
|
||||
this.lvAmdPresets.TabIndex = 10;
|
||||
this.lvAmdPresets.UseCompatibleStateImageBehavior = false;
|
||||
this.lvAmdPresets.View = System.Windows.Forms.View.Details;
|
||||
this.lvAmdPresets.ColumnClick += new System.Windows.Forms.ColumnClickEventHandler(this.lvLgPresets_ColumnClick);
|
||||
this.lvAmdPresets.ItemCheck += new System.Windows.Forms.ItemCheckEventHandler(this.lvNvPresets_ItemCheck);
|
||||
this.lvAmdPresets.ItemChecked += new System.Windows.Forms.ItemCheckedEventHandler(this.lvAmdPresets_ItemChecked);
|
||||
this.lvAmdPresets.SelectedIndexChanged += new System.EventHandler(this.lvAmdPresets_SelectedIndexChanged);
|
||||
this.lvAmdPresets.DoubleClick += new System.EventHandler(this.btnApplyAmd_Click);
|
||||
//
|
||||
// AmdPanel
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.Controls.Add(this.btnAmdSettings);
|
||||
this.Controls.Add(this.chkAmdQuickAccess);
|
||||
this.Controls.Add(this.lblAmdPresetName);
|
||||
this.Controls.Add(this.edtAmdPresetName);
|
||||
this.Controls.Add(this.btnAddAmd);
|
||||
this.Controls.Add(this.lblErrorAMD);
|
||||
this.Controls.Add(this.btnDeleteAmd);
|
||||
this.Controls.Add(this.btnCloneAmd);
|
||||
this.Controls.Add(this.btnAmdPresetSave);
|
||||
this.Controls.Add(this.lblAmdShortcut);
|
||||
this.Controls.Add(this.edtAmdShortcut);
|
||||
this.Controls.Add(this.btnChangeAmd);
|
||||
this.Controls.Add(this.btnApplyAmd);
|
||||
this.Controls.Add(this.lvAmdPresets);
|
||||
this.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
this.Name = "AmdPanel";
|
||||
this.Size = new System.Drawing.Size(1114, 539);
|
||||
this.mnuAmdPresets.ResumeLayout(false);
|
||||
this.ResumeLayout(false);
|
||||
this.PerformLayout();
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.Label lblErrorAMD;
|
||||
private System.Windows.Forms.Button btnDeleteAmd;
|
||||
private System.Windows.Forms.Button btnCloneAmd;
|
||||
private System.Windows.Forms.Button btnAmdPresetSave;
|
||||
private System.Windows.Forms.Label lblAmdShortcut;
|
||||
private System.Windows.Forms.TextBox edtAmdShortcut;
|
||||
private System.Windows.Forms.Button btnChangeAmd;
|
||||
private System.Windows.Forms.ContextMenuStrip mnuAmdPresets;
|
||||
private System.Windows.Forms.ToolStripMenuItem miAmdApply;
|
||||
private System.Windows.Forms.ToolStripMenuItem miAmdPresetApplyOnStartup;
|
||||
private System.Windows.Forms.ToolStripSeparator toolStripSeparator2;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuAmdDisplay;
|
||||
private System.Windows.Forms.ToolStripMenuItem miAmdPrimaryDisplay;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuAmdColorSettings;
|
||||
private System.Windows.Forms.ToolStripMenuItem miAmdColorSettingsIncluded;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuAmdRefreshRate;
|
||||
private System.Windows.Forms.ToolStripMenuItem miAmdRefreshRateIncluded;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuAmdDithering;
|
||||
private System.Windows.Forms.ToolStripMenuItem miAmdDitheringIncluded;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuAmdHDR;
|
||||
private System.Windows.Forms.ToolStripMenuItem miAmdHDRIncluded;
|
||||
private System.Windows.Forms.ToolStripMenuItem miAmdHDRToggle;
|
||||
private System.Windows.Forms.ToolStripMenuItem miAmdHDREnabled;
|
||||
private System.Windows.Forms.Button btnApplyAmd;
|
||||
private System.Windows.Forms.ListView lvAmdPresets;
|
||||
private System.Windows.Forms.Button btnAddAmd;
|
||||
private System.Windows.Forms.Label lblAmdPresetName;
|
||||
private System.Windows.Forms.TextBox edtAmdPresetName;
|
||||
private System.Windows.Forms.ToolStripMenuItem miAmdCopyId;
|
||||
private System.Windows.Forms.CheckBox chkAmdQuickAccess;
|
||||
private System.Windows.Forms.Button btnAmdSettings;
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,618 @@
|
||||
using ATI.ADL;
|
||||
using ColorControl.Shared.Common;
|
||||
using ColorControl.Shared.Contracts;
|
||||
using ColorControl.Shared.Forms;
|
||||
using ColorControl.Shared.Native;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace ColorControl.Services.AMD
|
||||
{
|
||||
public partial class AmdPanel : UserControl, IModulePanel
|
||||
{
|
||||
public static readonly int SHORTCUTID_AMDQA = -201;
|
||||
|
||||
private AmdService _amdService;
|
||||
private NotifyIcon _trayIcon;
|
||||
private IntPtr _mainHandle;
|
||||
private Config _config;
|
||||
private string _lastDisplayRefreshRates = string.Empty;
|
||||
|
||||
internal AmdPanel(AmdService amdService, NotifyIcon trayIcon, IntPtr handle)
|
||||
{
|
||||
_amdService = amdService;
|
||||
_trayIcon = trayIcon;
|
||||
_mainHandle = handle;
|
||||
|
||||
_config = Shared.Common.GlobalContext.CurrentContext.Config;
|
||||
|
||||
InitializeComponent();
|
||||
|
||||
FillAmdPresets();
|
||||
|
||||
FormUtils.InitSortState(lvAmdPresets, _config.AmdPresetsSortState);
|
||||
|
||||
_amdService.AfterApplyPreset += AmdServiceAfterApplyPreset;
|
||||
}
|
||||
|
||||
private void AmdServiceAfterApplyPreset(object sender, AmdPreset preset)
|
||||
{
|
||||
UpdateDisplayInfoItemsAmd();
|
||||
}
|
||||
|
||||
private void FillAmdPresets()
|
||||
{
|
||||
FormUtils.InitListView(lvAmdPresets, AmdPreset.GetColumnNames());
|
||||
|
||||
UpdateDisplayInfoItemsAmd();
|
||||
|
||||
foreach (var preset in _amdService.GetPresets())
|
||||
{
|
||||
AddOrUpdateItemAmd(preset);
|
||||
KeyboardShortcutManager.RegisterShortcut(preset.id, preset.shortcut);
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateDisplayInfoItemsAmd()
|
||||
{
|
||||
var displays = _amdService?.GetDisplayInfos();
|
||||
if (displays == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var text = Program.TS_TASKNAME;
|
||||
foreach (var displayInfo in displays)
|
||||
{
|
||||
var display = displayInfo.Display;
|
||||
|
||||
var id = display.DisplayID.DisplayPhysicalIndex;
|
||||
|
||||
ListViewItem item = null;
|
||||
for (var i = 0; i < lvAmdPresets.Items.Count; i++)
|
||||
{
|
||||
item = lvAmdPresets.Items[i];
|
||||
|
||||
if (item.Tag == null && item.ImageIndex == id)
|
||||
{
|
||||
break;
|
||||
}
|
||||
item = null;
|
||||
}
|
||||
|
||||
if (item == null)
|
||||
{
|
||||
item = lvAmdPresets.Items.Add(display.DisplayName);
|
||||
item.ImageIndex = id;
|
||||
item.Font = new Font(item.Font, item.Font.Style | FontStyle.Bold);
|
||||
item.BackColor = Color.LightGray;
|
||||
}
|
||||
|
||||
var values = displayInfo.Values;
|
||||
|
||||
item.Text = values[0];
|
||||
for (var i = 1; i < values.Count; i++)
|
||||
{
|
||||
if (item.SubItems.Count - 1 >= i)
|
||||
{
|
||||
item.SubItems[i].Text = values[i];
|
||||
}
|
||||
else
|
||||
{
|
||||
item.SubItems.Add(values[i]);
|
||||
}
|
||||
}
|
||||
|
||||
text += "\n" + displayInfo.InfoLine;
|
||||
}
|
||||
|
||||
FormUtils.SetNotifyIconText(_trayIcon, text);
|
||||
}
|
||||
|
||||
private void AddOrUpdateItemAmd(AmdPreset preset = null)
|
||||
{
|
||||
ServiceFormUtils.AddOrUpdateListItem(lvAmdPresets, _amdService.GetPresets(), _config, preset);
|
||||
}
|
||||
|
||||
public void AfterInitialized()
|
||||
{
|
||||
var _ = ApplyAmdPresetOnStartup();
|
||||
}
|
||||
|
||||
private async Task ApplyAmdPresetOnStartup(int attempts = 5)
|
||||
{
|
||||
var startUpParams = Shared.Common.GlobalContext.CurrentContext.StartUpParams;
|
||||
var presetIdOrName = !string.IsNullOrEmpty(startUpParams.AmdPresetIdOrName) ? startUpParams.AmdPresetIdOrName : _config.AmdPresetId_ApplyOnStartup.ToString();
|
||||
|
||||
if (!string.IsNullOrEmpty(presetIdOrName))
|
||||
{
|
||||
var preset = _amdService?.GetPresetByIdOrName(presetIdOrName);
|
||||
if (preset == null)
|
||||
{
|
||||
if (string.IsNullOrEmpty(startUpParams.AmdPresetIdOrName))
|
||||
{
|
||||
_config.AmdPresetId_ApplyOnStartup = 0;
|
||||
}
|
||||
}
|
||||
else if (_amdService != null)
|
||||
{
|
||||
if (_amdService.HasDisplaysAttached())
|
||||
{
|
||||
await ApplyAmdPreset(preset);
|
||||
}
|
||||
else
|
||||
{
|
||||
attempts--;
|
||||
if (attempts > 0)
|
||||
{
|
||||
await Task.Delay(2000);
|
||||
await ApplyAmdPresetOnStartup(attempts);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal void Save()
|
||||
{
|
||||
FormUtils.SaveSortState(lvAmdPresets.ListViewItemSorter, _config.AmdPresetsSortState);
|
||||
}
|
||||
|
||||
public void UpdateInfo()
|
||||
{
|
||||
UpdateDisplayInfoItemsAmd();
|
||||
}
|
||||
|
||||
private void edtShortcut_KeyDown(object sender, KeyEventArgs e)
|
||||
{
|
||||
((TextBox)sender).Text = KeyboardShortcutManager.FormatKeyboardShortcut(e);
|
||||
}
|
||||
|
||||
private void edtShortcut_KeyUp(object sender, KeyEventArgs e)
|
||||
{
|
||||
KeyboardShortcutManager.HandleKeyboardShortcutUp(e);
|
||||
}
|
||||
|
||||
private AmdPreset GetSelectedAmdPreset()
|
||||
{
|
||||
if (lvAmdPresets.SelectedItems.Count > 0)
|
||||
{
|
||||
var item = lvAmdPresets.SelectedItems[0];
|
||||
return (AmdPreset)item.Tag;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private void refreshRateMenuItemAmd_Click(object sender, EventArgs e)
|
||||
{
|
||||
var refreshRate = (uint)((ToolStripItem)sender).Tag;
|
||||
|
||||
var preset = GetSelectedAmdPreset();
|
||||
|
||||
preset.refreshRate = refreshRate;
|
||||
|
||||
AddOrUpdateItemAmd();
|
||||
}
|
||||
|
||||
private void displayMenuItemAmd_Click(object sender, EventArgs e)
|
||||
{
|
||||
var preset = GetSelectedAmdPreset();
|
||||
|
||||
var menuItem = (ToolStripItem)sender;
|
||||
if (menuItem.Tag != null)
|
||||
{
|
||||
var display = (ADLDisplayInfo)menuItem.Tag;
|
||||
|
||||
preset.displayName = display.DisplayName;
|
||||
preset.primaryDisplay = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
preset.primaryDisplay = true;
|
||||
preset.displayName = null;
|
||||
}
|
||||
|
||||
AddOrUpdateItemAmd();
|
||||
}
|
||||
|
||||
private async Task ApplySelectedAmdPreset()
|
||||
{
|
||||
var preset = GetSelectedAmdPreset();
|
||||
await ApplyAmdPreset(preset);
|
||||
}
|
||||
|
||||
internal async Task<bool> ApplyAmdPreset(AmdPreset preset)
|
||||
{
|
||||
if (preset == null || _amdService == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
try
|
||||
{
|
||||
var result = await _amdService.ApplyPreset(preset);
|
||||
if (!result)
|
||||
{
|
||||
throw new Exception("Error while applying AMD preset. At least one setting could not be applied. Check the log for details.");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
MessageForms.ErrorOk($"Error applying AMD-preset ({e.TargetSite.Name}): {e.Message}");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private async void btnApplyAmd_Click(object sender, EventArgs e)
|
||||
{
|
||||
await ApplySelectedAmdPreset();
|
||||
}
|
||||
|
||||
private void btnChangeAmd_Click(object sender, EventArgs e)
|
||||
{
|
||||
mnuAmdPresets.ShowCustom(btnChangeAmd);
|
||||
}
|
||||
|
||||
private void edtAmdShortcut_TextChanged(object sender, EventArgs e)
|
||||
{
|
||||
var text = edtAmdShortcut.Text;
|
||||
|
||||
var preset = GetSelectedAmdPreset();
|
||||
|
||||
ServiceFormUtils.UpdateShortcutTextBox(edtAmdShortcut, preset);
|
||||
}
|
||||
|
||||
private void btnSetAmdShortcut_Click(object sender, EventArgs e)
|
||||
{
|
||||
var shortcut = edtAmdShortcut.Text.Trim();
|
||||
|
||||
if (!KeyboardShortcutManager.ValidateShortcut(shortcut))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var preset = GetSelectedAmdPreset();
|
||||
|
||||
var name = edtAmdPresetName.Text.Trim();
|
||||
|
||||
if (!string.IsNullOrEmpty(name) && _amdService.GetPresets().Any(x => x.id != preset.id && x.name != null && x.name.Equals(name, StringComparison.OrdinalIgnoreCase)))
|
||||
{
|
||||
MessageForms.WarningOk("The name must be unique.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(name) && chkAmdQuickAccess.Checked)
|
||||
{
|
||||
MessageForms.WarningOk("A name must be entered before enabling Quick Access.");
|
||||
return;
|
||||
}
|
||||
|
||||
preset.shortcut = shortcut;
|
||||
preset.name = name;
|
||||
preset.ShowInQuickAccess = chkAmdQuickAccess.Checked;
|
||||
|
||||
AddOrUpdateItemAmd();
|
||||
|
||||
KeyboardShortcutManager.RegisterShortcut(preset.id, preset.shortcut);
|
||||
}
|
||||
|
||||
private void btnCloneAmd_Click(object sender, EventArgs e)
|
||||
{
|
||||
var preset = GetSelectedAmdPreset();
|
||||
|
||||
var newPreset = preset.Clone();
|
||||
AddOrUpdateItemAmd(newPreset);
|
||||
}
|
||||
|
||||
private void btnDeleteAmd_Click(object sender, EventArgs e)
|
||||
{
|
||||
var preset = GetSelectedAmdPreset();
|
||||
|
||||
if (preset == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(preset.shortcut))
|
||||
{
|
||||
WinApi.UnregisterHotKey(_mainHandle, preset.id);
|
||||
}
|
||||
|
||||
_amdService.GetPresets().Remove(preset);
|
||||
|
||||
var item = lvAmdPresets.SelectedItems[0];
|
||||
lvAmdPresets.Items.Remove(item);
|
||||
}
|
||||
|
||||
private void mnuAmdPresets_Opening(object sender, CancelEventArgs e)
|
||||
{
|
||||
var preset = GetSelectedAmdPreset();
|
||||
|
||||
miAmdApply.Enabled = preset != null;
|
||||
miAmdPresetApplyOnStartup.Enabled = preset != null;
|
||||
mnuAmdDisplay.Enabled = preset != null;
|
||||
mnuAmdColorSettings.Enabled = preset != null;
|
||||
mnuAmdRefreshRate.Enabled = preset != null;
|
||||
mnuAmdDithering.Enabled = preset != null;
|
||||
mnuAmdHDR.Enabled = preset != null;
|
||||
|
||||
if (preset != null)
|
||||
{
|
||||
miAmdPresetApplyOnStartup.Checked = _config.AmdPresetId_ApplyOnStartup == preset.id;
|
||||
|
||||
if (mnuAmdDisplay.DropDownItems.Count == 1)
|
||||
{
|
||||
var displays = _amdService.GetDisplays();
|
||||
for (var i = 0; i < displays.Count; i++)
|
||||
{
|
||||
var display = displays[i];
|
||||
var name = _amdService.GetFullDisplayName(display);
|
||||
|
||||
var item = mnuAmdDisplay.DropDownItems.AddCustom(name);
|
||||
item.Tag = display;
|
||||
item.Click += displayMenuItemAmd_Click;
|
||||
}
|
||||
}
|
||||
|
||||
FormUtils.BuildDropDownMenu(mnuAmdColorSettings, "Color depth", typeof(ADLColorDepth), preset, "colorDepth", amdPresetColorDataMenuItem_Click);
|
||||
FormUtils.BuildDropDownMenu(mnuAmdColorSettings, "Pixel format", typeof(ADLPixelFormat), preset, "pixelFormat", amdPresetColorDataMenuItem_Click);
|
||||
|
||||
if (preset.displayName != _lastDisplayRefreshRates)
|
||||
{
|
||||
while (mnuAmdRefreshRate.DropDownItems.Count > 1)
|
||||
{
|
||||
mnuAmdRefreshRate.DropDownItems.RemoveAt(mnuAmdRefreshRate.DropDownItems.Count - 1);
|
||||
}
|
||||
}
|
||||
|
||||
if (mnuAmdRefreshRate.DropDownItems.Count == 1)
|
||||
{
|
||||
var refreshRates = _amdService.GetAvailableRefreshRates(preset);
|
||||
_lastDisplayRefreshRates = preset.displayName;
|
||||
|
||||
foreach (var refreshRate in refreshRates)
|
||||
{
|
||||
var item = mnuAmdRefreshRate.DropDownItems.AddCustom(refreshRate.ToString() + "Hz");
|
||||
item.Tag = refreshRate;
|
||||
item.Click += refreshRateMenuItemAmd_Click;
|
||||
}
|
||||
}
|
||||
|
||||
miAmdPrimaryDisplay.Checked = preset.primaryDisplay;
|
||||
foreach (var item in mnuAmdDisplay.DropDownItems)
|
||||
{
|
||||
if (item is ToolStripMenuItem)
|
||||
{
|
||||
var menuItem = (ToolStripMenuItem)item;
|
||||
if (menuItem.Tag != null)
|
||||
{
|
||||
menuItem.Checked = ((ADLDisplayInfo)menuItem.Tag).DisplayName.Equals(preset.displayName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
miAmdColorSettingsIncluded.Checked = preset.applyColorData;
|
||||
|
||||
miAmdRefreshRateIncluded.Checked = preset.applyRefreshRate;
|
||||
foreach (var item in mnuAmdRefreshRate.DropDownItems)
|
||||
{
|
||||
if (item is ToolStripMenuItem)
|
||||
{
|
||||
var menuItem = (ToolStripMenuItem)item;
|
||||
if (menuItem.Tag != null)
|
||||
{
|
||||
menuItem.Checked = (uint)menuItem.Tag == preset.refreshRate;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
miAmdDitheringIncluded.Checked = preset.applyDithering;
|
||||
|
||||
FormUtils.BuildDropDownMenu(mnuAmdDithering, "Mode", typeof(ADLDitherState), preset, "ditherState", amdPresetColorDataMenuItem_Click);
|
||||
|
||||
miAmdHDRIncluded.Checked = preset.applyHDR;
|
||||
miAmdHDREnabled.Checked = preset.HDREnabled;
|
||||
miAmdHDRToggle.Checked = preset.toggleHDR;
|
||||
}
|
||||
}
|
||||
|
||||
private void miAmdPresetApplyOnStartup_Click(object sender, EventArgs e)
|
||||
{
|
||||
var preset = GetSelectedAmdPreset();
|
||||
_config.AmdPresetId_ApplyOnStartup = miAmdPresetApplyOnStartup.Checked ? preset.id : 0;
|
||||
|
||||
AddOrUpdateItemAmd();
|
||||
}
|
||||
|
||||
private void lvAmdPresets_SelectedIndexChanged(object sender, EventArgs e)
|
||||
{
|
||||
var preset = GetSelectedAmdPreset();
|
||||
var enabled = preset != null;
|
||||
|
||||
FormUtils.EnableControls(this, enabled, new List<Control> { lvAmdPresets, btnAddAmd });
|
||||
|
||||
if (enabled)
|
||||
{
|
||||
edtAmdPresetName.Text = preset.name;
|
||||
edtAmdShortcut.Text = preset.shortcut;
|
||||
chkAmdQuickAccess.Checked = preset.ShowInQuickAccess;
|
||||
}
|
||||
else
|
||||
{
|
||||
edtAmdPresetName.Text = string.Empty;
|
||||
edtAmdShortcut.Text = string.Empty;
|
||||
chkAmdQuickAccess.Checked = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void amdPresetColorDataMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
var menuItem = (ToolStripMenuItem)sender;
|
||||
var property = (PropertyInfo)menuItem.OwnerItem.Tag;
|
||||
|
||||
var value = menuItem.Tag;
|
||||
|
||||
var preset = GetSelectedAmdPreset();
|
||||
|
||||
property.SetValue(preset, value);
|
||||
|
||||
AddOrUpdateItemAmd();
|
||||
}
|
||||
|
||||
private void miAmdColorSettingsIncluded_Click(object sender, EventArgs e)
|
||||
{
|
||||
var preset = GetSelectedAmdPreset();
|
||||
|
||||
preset.applyColorData = !preset.applyColorData;
|
||||
|
||||
AddOrUpdateItemAmd();
|
||||
}
|
||||
|
||||
private void miAmdRefreshRateIncluded_Click(object sender, EventArgs e)
|
||||
{
|
||||
var preset = GetSelectedAmdPreset();
|
||||
|
||||
preset.applyRefreshRate = !preset.applyRefreshRate;
|
||||
|
||||
AddOrUpdateItemAmd();
|
||||
}
|
||||
|
||||
private void miAmdDitheringIncluded_Click(object sender, EventArgs e)
|
||||
{
|
||||
var preset = GetSelectedAmdPreset();
|
||||
|
||||
preset.applyDithering = !preset.applyDithering;
|
||||
|
||||
AddOrUpdateItemAmd();
|
||||
}
|
||||
|
||||
private void miAmdHDRIncluded_Click(object sender, EventArgs e)
|
||||
{
|
||||
var preset = GetSelectedAmdPreset();
|
||||
|
||||
preset.applyHDR = !preset.applyHDR;
|
||||
|
||||
AddOrUpdateItemAmd();
|
||||
}
|
||||
|
||||
private void miAmdHDRToggle_Click(object sender, EventArgs e)
|
||||
{
|
||||
var preset = GetSelectedAmdPreset();
|
||||
|
||||
preset.toggleHDR = !preset.toggleHDR;
|
||||
|
||||
if (preset.toggleHDR)
|
||||
{
|
||||
preset.HDREnabled = false;
|
||||
}
|
||||
|
||||
AddOrUpdateItemAmd();
|
||||
}
|
||||
|
||||
private void miAmdHDREnabled_Click(object sender, EventArgs e)
|
||||
{
|
||||
var preset = GetSelectedAmdPreset();
|
||||
|
||||
preset.HDREnabled = !preset.HDREnabled;
|
||||
preset.toggleHDR = false;
|
||||
|
||||
AddOrUpdateItemAmd();
|
||||
}
|
||||
|
||||
private void btnAddAmd_Click(object sender, EventArgs e)
|
||||
{
|
||||
var presets = AmdPreset.GetDefaultPresets();
|
||||
//var added = false;
|
||||
|
||||
foreach (var preset in presets)
|
||||
{
|
||||
AddOrUpdateItemAmd(preset);
|
||||
}
|
||||
|
||||
//if (added)
|
||||
//{
|
||||
// MessageForms.InfoOk("Missing presets added.");
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
// MessageForms.InfoOk("All presets for every color setting already exist.");
|
||||
//}
|
||||
}
|
||||
|
||||
private void miAmdCopyId_Click(object sender, EventArgs e)
|
||||
{
|
||||
var preset = GetSelectedAmdPreset();
|
||||
|
||||
if (preset != null)
|
||||
{
|
||||
Clipboard.SetText(preset.id.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
private void lvNvPresets_ItemCheck(object sender, ItemCheckEventArgs e)
|
||||
{
|
||||
var listView = sender as ListView;
|
||||
|
||||
if (!listView.Focused)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
var point = listView.PointToClient(Cursor.Position);
|
||||
|
||||
if (point.X >= 20)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var listItem = listView.Items[e.Index];
|
||||
|
||||
if (listItem.Tag == null)
|
||||
{
|
||||
MessageForms.WarningOk("Quick Access cannot be enabled for this item.");
|
||||
e.NewValue = e.CurrentValue;
|
||||
}
|
||||
|
||||
if (e.NewValue == CheckState.Checked && string.IsNullOrEmpty(listItem.Text))
|
||||
{
|
||||
MessageForms.WarningOk("A name must be entered before enabling Quick Access.");
|
||||
e.NewValue = e.CurrentValue;
|
||||
}
|
||||
}
|
||||
|
||||
private void lvAmdPresets_ItemChecked(object sender, ItemCheckedEventArgs e)
|
||||
{
|
||||
ServiceFormUtils.ListViewItemChecked<AmdPreset>(lvAmdPresets, e);
|
||||
}
|
||||
|
||||
private void btnAmdSettings_Click(object sender, EventArgs e)
|
||||
{
|
||||
var shortcut = FormUtils.EditShortcut(_config.AmdQuickAccessShortcut, "Quick Access shortcut", "AMD controller settings");
|
||||
|
||||
if (shortcut == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_config.AmdQuickAccessShortcut = shortcut;
|
||||
|
||||
KeyboardShortcutManager.RegisterShortcut(SHORTCUTID_AMDQA, _config.AmdQuickAccessShortcut);
|
||||
}
|
||||
|
||||
private void lvLgPresets_ColumnClick(object sender, ColumnClickEventArgs e)
|
||||
{
|
||||
FormUtils.ListViewSort(sender, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
<root>
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<metadata name="mnuAmdPresets.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>17, 17</value>
|
||||
</metadata>
|
||||
</root>
|
||||
@@ -0,0 +1,145 @@
|
||||
using ColorControl.Services.Common;
|
||||
using ColorControl.Shared.Contracts;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace ColorControl.Services.AMD
|
||||
{
|
||||
class AmdPreset : PresetBase
|
||||
{
|
||||
public bool applyColorData { get; set; }
|
||||
public ADLColorDepth colorDepth { get; set; }
|
||||
public ADLPixelFormat pixelFormat { get; set; }
|
||||
public bool applyHDR { get; set; }
|
||||
public bool HDREnabled { get; set; }
|
||||
public bool toggleHDR { get; set; }
|
||||
public bool applyDithering { get; set; }
|
||||
public ADLDitherState ditherState { get; set; }
|
||||
public bool applyRefreshRate { get; set; }
|
||||
public uint refreshRate { get; set; }
|
||||
public bool primaryDisplay { get; set; }
|
||||
public string displayName { get; set; }
|
||||
|
||||
public AmdPreset() : base()
|
||||
{
|
||||
applyColorData = true;
|
||||
applyDithering = false;
|
||||
ditherState = ADLDitherState.DRIVER_DEFAULT;
|
||||
applyHDR = false;
|
||||
HDREnabled = false;
|
||||
toggleHDR = false;
|
||||
applyRefreshRate = false;
|
||||
refreshRate = 60;
|
||||
primaryDisplay = true;
|
||||
}
|
||||
|
||||
public AmdPreset(AmdPreset preset) : this()
|
||||
{
|
||||
id = GetNewId();
|
||||
|
||||
primaryDisplay = preset.primaryDisplay;
|
||||
displayName = preset.displayName;
|
||||
|
||||
applyColorData = preset.applyColorData;
|
||||
colorDepth = preset.colorDepth;
|
||||
pixelFormat = preset.pixelFormat;
|
||||
|
||||
applyHDR = preset.applyHDR;
|
||||
HDREnabled = preset.HDREnabled;
|
||||
toggleHDR = preset.toggleHDR;
|
||||
applyDithering = preset.applyDithering;
|
||||
ditherState = preset.ditherState;
|
||||
applyRefreshRate = preset.applyRefreshRate;
|
||||
refreshRate = preset.refreshRate;
|
||||
}
|
||||
|
||||
public AmdPreset Clone()
|
||||
{
|
||||
var preset = new AmdPreset(this);
|
||||
|
||||
return preset;
|
||||
}
|
||||
|
||||
public static string[] GetColumnNames()
|
||||
{
|
||||
//return new[] { "BPC", "Format", "Dynamic range", "Toggle HDR", "Shortcut" };
|
||||
return new[] { "Name", "Display|140", "Color settings (BPC, format)|260", "Refresh rate|100", "Dithering", "HDR", "Shortcut", "Apply on startup" };
|
||||
}
|
||||
|
||||
public override List<string> GetDisplayValues(Config config = null)
|
||||
{
|
||||
var values = new List<string>();
|
||||
|
||||
values.Add(name);
|
||||
|
||||
var display = string.Format("{0}", primaryDisplay ? "Primary" : displayName);
|
||||
values.Add(display);
|
||||
|
||||
var colorSettings = string.Format("{0}: {1}, {2}", applyColorData ? "Included" : "Excluded", colorDepth, pixelFormat);
|
||||
|
||||
values.Add(colorSettings);
|
||||
values.Add(string.Format("{0}: {1}Hz", applyRefreshRate ? "Included" : "Excluded", refreshRate));
|
||||
values.Add(string.Format("{0}: {1}", applyDithering ? "Included" : "Excluded", ditherState));
|
||||
values.Add(string.Format("{0}: {1}", applyHDR ? "Included" : "Excluded", toggleHDR ? "Toggle" : HDREnabled ? "Enabled" : "Disabled"));
|
||||
values.Add(shortcut);
|
||||
values.Add(string.Format("{0}", config?.AmdPresetId_ApplyOnStartup == id ? "Yes" : string.Empty));
|
||||
|
||||
return values;
|
||||
}
|
||||
|
||||
public static List<AmdPreset> GetDefaultPresets()
|
||||
{
|
||||
var presets = new List<AmdPreset>();
|
||||
|
||||
var preset = new AmdPreset();
|
||||
preset.colorDepth = ADLColorDepth.BPC8;
|
||||
preset.pixelFormat = ADLPixelFormat.RGB_FULL_RANGE;
|
||||
|
||||
presets.Add(preset);
|
||||
|
||||
return presets;
|
||||
}
|
||||
|
||||
public override string GetTextForMenuItem()
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
if (!string.IsNullOrEmpty(name))
|
||||
{
|
||||
sb.Append(name);
|
||||
sb.Append(" / ");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (displayName != null)
|
||||
{
|
||||
sb.AppendFormat("Display: {0} / ", displayName);
|
||||
}
|
||||
if (applyColorData)
|
||||
{
|
||||
var colorSettings = string.Format("Format: {0}, {1}", colorDepth, pixelFormat);
|
||||
sb.Append(colorSettings);
|
||||
sb.Append(" / ");
|
||||
}
|
||||
if (applyRefreshRate)
|
||||
{
|
||||
sb.AppendFormat("{0}Hz", refreshRate);
|
||||
sb.Append(" / ");
|
||||
}
|
||||
if (applyDithering)
|
||||
{
|
||||
sb.AppendFormat("Dithering: {0}", ditherState);
|
||||
sb.Append(" / ");
|
||||
}
|
||||
if (applyHDR)
|
||||
{
|
||||
sb.AppendFormat("HDR: {0}", toggleHDR ? "Toggle" : HDREnabled ? "Enabled" : "Disabled");
|
||||
sb.Append(" / ");
|
||||
}
|
||||
}
|
||||
|
||||
return sb.ToString(0, Math.Max(0, sb.Length - 3));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,364 @@
|
||||
using ATI.ADL;
|
||||
using ColorControl.Services.Common;
|
||||
using ColorControl.Shared.Common;
|
||||
using ColorControl.Shared.Native;
|
||||
using ColorControl.Shared.Services;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace ColorControl.Services.AMD
|
||||
{
|
||||
class AmdService : GraphicsService<AmdPreset>
|
||||
{
|
||||
private static readonly NLog.Logger Logger = NLog.LogManager.GetCurrentClassLogger();
|
||||
|
||||
public override string ServiceName => "AMD";
|
||||
|
||||
protected override string PresetsBaseFilename => "AmdPresets.json";
|
||||
|
||||
private ADLDisplayInfo _currentDisplay;
|
||||
|
||||
public AmdService(AppContextProvider appContextProvider) : base(appContextProvider)
|
||||
{
|
||||
LoadPresets();
|
||||
}
|
||||
|
||||
public static async Task<bool> ExecutePresetAsync(string idOrName)
|
||||
{
|
||||
try
|
||||
{
|
||||
var appContextProvider = Program.ServiceProvider.GetRequiredService<AppContextProvider>();
|
||||
|
||||
var service = new AmdService(appContextProvider);
|
||||
|
||||
var result = await service.ApplyPreset(idOrName);
|
||||
|
||||
if (!result)
|
||||
{
|
||||
Console.WriteLine("Preset not found or error while executing.");
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine("Error executing preset: " + ex.ToLogString());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
protected override List<AmdPreset> GetDefaultPresets()
|
||||
{
|
||||
return AmdPreset.GetDefaultPresets();
|
||||
}
|
||||
|
||||
private void SavePresets()
|
||||
{
|
||||
Utils.WriteObject(_presetsFilename, _presets);
|
||||
}
|
||||
|
||||
public void GlobalSave()
|
||||
{
|
||||
SavePresets();
|
||||
}
|
||||
|
||||
public override bool HasDisplaysAttached(bool reinitialize = false)
|
||||
{
|
||||
try
|
||||
{
|
||||
return GetDisplays().Any();
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public void SetCurrentDisplay(AmdPreset preset)
|
||||
{
|
||||
var displays = GetDisplays();
|
||||
if (preset.primaryDisplay)
|
||||
{
|
||||
_currentDisplay = displays.FirstOrDefault();
|
||||
}
|
||||
else
|
||||
{
|
||||
_currentDisplay = displays.FirstOrDefault(x => x.DisplayName.Equals(preset.displayName));
|
||||
}
|
||||
}
|
||||
|
||||
public ADLDisplayInfo GetCurrentDisplay()
|
||||
{
|
||||
if (string.IsNullOrEmpty(_currentDisplay.DisplayName))
|
||||
{
|
||||
_currentDisplay = GetDisplays().FirstOrDefault();
|
||||
}
|
||||
|
||||
return _currentDisplay;
|
||||
}
|
||||
|
||||
public async Task<bool> ApplyPreset(string idOrName)
|
||||
{
|
||||
var preset = GetPresetByIdOrName(idOrName);
|
||||
if (preset != null)
|
||||
{
|
||||
return await ApplyPreset(preset);
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public override async Task<bool> ApplyPreset(AmdPreset preset)
|
||||
{
|
||||
SetCurrentDisplay(preset);
|
||||
|
||||
if (string.IsNullOrEmpty(_currentDisplay.DisplayName))
|
||||
{
|
||||
Logger.Error("Could not set current display");
|
||||
return false;
|
||||
}
|
||||
|
||||
var result = true;
|
||||
|
||||
if (preset.applyHDR)
|
||||
{
|
||||
var hdrEnabled = IsHDREnabled();
|
||||
if (preset.toggleHDR)
|
||||
{
|
||||
result = ADLWrapper.SetDisplayHDRState(_currentDisplay, !hdrEnabled);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = ADLWrapper.SetDisplayHDRState(_currentDisplay, preset.HDREnabled);
|
||||
}
|
||||
|
||||
//if (preset.toggleHDR || preset.HDREnabled != hdrEnabled)
|
||||
//{
|
||||
// ToggleHDR(config.DisplaySettingsDelay);
|
||||
//}
|
||||
}
|
||||
|
||||
if (preset.applyRefreshRate)
|
||||
{
|
||||
{
|
||||
if (!SetRefreshRate(preset.refreshRate))
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (preset.applyColorData)
|
||||
{
|
||||
if (!ADLWrapper.SetDisplayColorDepth(_currentDisplay, preset.colorDepth))
|
||||
{
|
||||
Logger.Error("Could not set color depth");
|
||||
result = false;
|
||||
}
|
||||
if (preset.pixelFormat != ADLPixelFormat.UNKNOWN && !ADLWrapper.SetDisplayPixelFormat(_currentDisplay, preset.pixelFormat))
|
||||
{
|
||||
Logger.Error("Could not set pixel format");
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (preset.applyDithering)
|
||||
{
|
||||
if (!SetDithering(preset.ditherState))
|
||||
{
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
|
||||
_lastAppliedPreset = preset;
|
||||
|
||||
PresetApplied();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public bool SetDithering(ADLDitherState ditherState)
|
||||
{
|
||||
var display = GetCurrentDisplay();
|
||||
|
||||
return ADLWrapper.SetDisplayDitherState(display, ditherState);
|
||||
}
|
||||
|
||||
public ADLDitherState GetDithering(ADLDisplayInfo display = default(ADLDisplayInfo))
|
||||
{
|
||||
if (string.IsNullOrEmpty(display.DisplayName))
|
||||
{
|
||||
display = GetCurrentDisplay();
|
||||
}
|
||||
|
||||
var ditherState = ADLDitherState.DRIVER_DEFAULT;
|
||||
|
||||
if (ADLWrapper.GetDisplayDitherState(display, ref ditherState))
|
||||
{
|
||||
return ditherState;
|
||||
}
|
||||
|
||||
return ditherState;
|
||||
}
|
||||
|
||||
public string GetDisplayDeviceName(ADLDisplayInfo display)
|
||||
{
|
||||
return Screen.PrimaryScreen.DeviceName;
|
||||
}
|
||||
|
||||
public bool SetRefreshRate(uint refreshRate)
|
||||
{
|
||||
var horizontal = 3840;
|
||||
var vertical = 2160;
|
||||
var display = GetCurrentDisplay();
|
||||
|
||||
ADLWrapper.GetDisplayResolution(display, ref horizontal, ref vertical);
|
||||
|
||||
var portrait = vertical > horizontal;
|
||||
|
||||
return SetRefreshRateInternal(GetDisplayDeviceName(display), (int)refreshRate, portrait, horizontal, vertical);
|
||||
}
|
||||
|
||||
public List<uint> GetAvailableRefreshRates(AmdPreset preset = null)
|
||||
{
|
||||
if (preset != null)
|
||||
{
|
||||
SetCurrentDisplay(preset);
|
||||
}
|
||||
|
||||
var horizontal = 3840;
|
||||
var vertical = 2160;
|
||||
var display = GetCurrentDisplay();
|
||||
|
||||
ADLWrapper.GetDisplayResolution(display, ref horizontal, ref vertical);
|
||||
|
||||
var portrait = vertical > horizontal;
|
||||
|
||||
return GetAvailableRefreshRatesInternal(GetDisplayDeviceName(display), portrait, horizontal, vertical);
|
||||
}
|
||||
|
||||
public bool IsHDREnabled()
|
||||
{
|
||||
var display = GetCurrentDisplay();
|
||||
|
||||
var supported = false;
|
||||
var enabled = false;
|
||||
ADLWrapper.GetDisplayHDRState(display, ref supported, ref enabled);
|
||||
|
||||
Logger.Debug($"IsHDREnabled: supported {supported}, enabled {enabled}");
|
||||
|
||||
return enabled;
|
||||
}
|
||||
|
||||
public List<ADLDisplayInfo> GetDisplays()
|
||||
{
|
||||
var displays = ADLWrapper.GetAllDisplays();
|
||||
|
||||
//if (!displays.Any())
|
||||
//{
|
||||
// displays.Add(new ADLDisplayInfo
|
||||
// {
|
||||
// DisplayName = "Dummy"
|
||||
// });
|
||||
//}
|
||||
|
||||
return displays;
|
||||
}
|
||||
|
||||
public string GetFullDisplayName(ADLDisplayInfo display)
|
||||
{
|
||||
var name = display.DisplayName;
|
||||
|
||||
var screen = GetScreenForDisplay(display);
|
||||
if (screen != null)
|
||||
{
|
||||
name = $"{screen.DeviceName} ({name})";
|
||||
}
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
public Screen GetScreenForDisplay(ADLDisplayInfo display)
|
||||
{
|
||||
var index = 0;
|
||||
foreach (var screen in Screen.AllScreens)
|
||||
{
|
||||
Logger.Debug($"SCREEN[{index}]: {screen.DeviceName}, {screen.DeviceFriendlyName()}, {screen.Primary}");
|
||||
index++;
|
||||
}
|
||||
return Screen.AllScreens.FirstOrDefault(x => x.DeviceFriendlyName().Equals(display.DisplayName));
|
||||
}
|
||||
|
||||
public List<AmdDisplayInfo> GetDisplayInfos()
|
||||
{
|
||||
List<ADLDisplayInfo> displays;
|
||||
try
|
||||
{
|
||||
displays = GetDisplays();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.Error("Error while getting displays: " + e.ToLogString());
|
||||
return null;
|
||||
}
|
||||
|
||||
var list = new List<AmdDisplayInfo>();
|
||||
|
||||
foreach (var display in displays)
|
||||
{
|
||||
var values = new List<string>();
|
||||
|
||||
values.Add("Current settings");
|
||||
|
||||
var screen = GetScreenForDisplay(display);
|
||||
|
||||
var name = GetFullDisplayName(display);
|
||||
values.Add(name);
|
||||
|
||||
var colorDepth = ADLColorDepth.UNKNOWN;
|
||||
ADLWrapper.GetDisplayColorDepth(display, ref colorDepth);
|
||||
|
||||
var pixelFormat = ADLPixelFormat.UNKNOWN;
|
||||
ADLWrapper.GetDisplayPixelFormat(display, ref pixelFormat);
|
||||
|
||||
var colorSettings = $"{colorDepth.GetDescription()}, {pixelFormat.GetDescription()}";
|
||||
values.Add(colorSettings);
|
||||
|
||||
var refreshRate = GetCurrentRefreshRate(screen?.DeviceName);
|
||||
values.Add($"{refreshRate}Hz");
|
||||
|
||||
var ditherState = GetDithering(display);
|
||||
values.Add(ditherState.GetDescription());
|
||||
|
||||
var hdrEnabled = IsHDREnabled();
|
||||
values.Add(hdrEnabled ? "Yes" : "No");
|
||||
|
||||
var infoLine = string.Format("{0}: {1}, {2}Hz, HDR: {3}", name, colorSettings, refreshRate, hdrEnabled ? "Yes" : "No");
|
||||
|
||||
var displayInfo = new AmdDisplayInfo(display, values, infoLine);
|
||||
|
||||
list.Add(displayInfo);
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
|
||||
protected override void Initialize()
|
||||
{
|
||||
if (!ADLWrapper.Initialize())
|
||||
{
|
||||
throw new InvalidOperationException("Cannot load AMD API");
|
||||
}
|
||||
}
|
||||
|
||||
protected override void Uninitialize()
|
||||
{
|
||||
ADLWrapper.Uninitialze();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,6 @@
|
||||
using NWin32;
|
||||
using ColorControl.Shared.Native;
|
||||
using ColorControl.Shared.Services;
|
||||
using NWin32;
|
||||
using NWin32.NativeTypes;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
@@ -7,15 +9,14 @@ using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Threading;
|
||||
|
||||
namespace ColorControl
|
||||
namespace ColorControl.Services.Common
|
||||
{
|
||||
class GraphicsService
|
||||
abstract class GraphicsService<T> : ServiceBase<T> where T : PresetBase, new()
|
||||
{
|
||||
protected static readonly NLog.Logger Logger = NLog.LogManager.GetCurrentClassLogger();
|
||||
private static readonly NLog.Logger Logger = NLog.LogManager.GetCurrentClassLogger();
|
||||
|
||||
public GraphicsService()
|
||||
public GraphicsService(AppContextProvider appContextProvider) : base(appContextProvider)
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
|
||||
~GraphicsService()
|
||||
@@ -23,15 +24,7 @@ namespace ColorControl
|
||||
Uninitialize();
|
||||
}
|
||||
|
||||
protected virtual void Initialize()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
protected virtual void Uninitialize()
|
||||
{
|
||||
|
||||
}
|
||||
public abstract bool HasDisplaysAttached(bool reinitialize = false);
|
||||
|
||||
protected void ToggleHDR(int delay = 1000)
|
||||
{
|
||||
@@ -48,7 +41,19 @@ namespace ColorControl
|
||||
}
|
||||
}
|
||||
|
||||
protected bool SetRefreshRateInternal(string displayName, uint refreshRate, bool portrait, int horizontal, int vertical)
|
||||
protected void OpenDisplaySettings(int delay = 1000)
|
||||
{
|
||||
Process.Start("ms-settings:display");
|
||||
Thread.Sleep(delay);
|
||||
|
||||
var process = Process.GetProcessesByName("SystemSettings").FirstOrDefault();
|
||||
if (process != null)
|
||||
{
|
||||
System.Windows.Forms.SendKeys.SendWait("%{F4}");
|
||||
}
|
||||
}
|
||||
|
||||
protected bool SetRefreshRateInternal(string displayName, int refreshRate, bool portrait, int horizontal, int vertical, bool updateRegistry = false)
|
||||
{
|
||||
uint i = 0;
|
||||
DEVMODEA devMode;
|
||||
@@ -61,7 +66,7 @@ namespace ColorControl
|
||||
{
|
||||
IntPtr bla = Marshal.AllocHGlobal(Marshal.SizeOf(devMode));
|
||||
Marshal.StructureToPtr(devMode, bla, false);
|
||||
var result = NativeMethods.ChangeDisplaySettingsExA(displayName, bla, IntPtr.Zero, 0, IntPtr.Zero);
|
||||
var result = NativeMethods.ChangeDisplaySettingsExA(displayName, bla, IntPtr.Zero, updateRegistry ? (uint)NativeConstants.CDS_UPDATEREGISTRY : 0, IntPtr.Zero);
|
||||
if (result != NativeConstants.DISP_CHANGE_SUCCESSFUL)
|
||||
{
|
||||
Logger.Error($"Could not set refreshrate {refreshRate} on display {displayName} because ChangeDisplaySettingsExA returned a non-zero return code: {result}");
|
||||
@@ -83,8 +88,9 @@ namespace ColorControl
|
||||
DEVMODEA devMode;
|
||||
while (NativeMethods.EnumDisplaySettingsA(displayName, i, out devMode))
|
||||
{
|
||||
if ((!portrait && devMode.dmPelsWidth == horizontal && devMode.dmPelsHeight == vertical) ||
|
||||
(portrait && devMode.dmPelsWidth == vertical && devMode.dmPelsHeight == horizontal))
|
||||
if (((!portrait && devMode.dmPelsWidth == horizontal && devMode.dmPelsHeight == vertical) ||
|
||||
(portrait && devMode.dmPelsWidth == vertical && devMode.dmPelsHeight == horizontal)) &&
|
||||
!list.Contains(devMode.dmDisplayFrequency))
|
||||
{
|
||||
list.Add(devMode.dmDisplayFrequency);
|
||||
}
|
||||
@@ -93,5 +99,50 @@ namespace ColorControl
|
||||
return list;
|
||||
}
|
||||
|
||||
protected uint GetCurrentRefreshRate(string displayName)
|
||||
{
|
||||
DEVMODEA devMode;
|
||||
// NativeMethods defines modeNum as an 'uint' but we need to pass '-1'
|
||||
if (WinApi.EnumDisplaySettingsA(displayName, WinApi.ENUM_CURRENT_SETTINGS, out devMode))
|
||||
{
|
||||
return devMode.dmDisplayFrequency;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
protected DEVMODEA GetCurrentMode(string displayName)
|
||||
{
|
||||
DEVMODEA devMode;
|
||||
// NativeMethods defines modeNum as an 'uint' but we need to pass '-1'
|
||||
if (WinApi.EnumDisplaySettingsA(displayName, WinApi.ENUM_CURRENT_SETTINGS, out devMode))
|
||||
{
|
||||
return devMode;
|
||||
}
|
||||
return devMode;
|
||||
}
|
||||
|
||||
protected List<DEVMODEA> GetAvailableResolutionsInternal(string displayName, bool portrait, uint refreshRate = 0)
|
||||
{
|
||||
var list = new List<DEVMODEA>();
|
||||
|
||||
uint i = 0;
|
||||
DEVMODEA devMode;
|
||||
while (NativeMethods.EnumDisplaySettingsA(displayName, i, out devMode))
|
||||
{
|
||||
if ((portrait ? devMode.dmPelsWidth < devMode.dmPelsHeight : devMode.dmPelsWidth > devMode.dmPelsHeight) &&
|
||||
(refreshRate == 0 || devMode.dmDisplayFrequency == refreshRate) &&
|
||||
!list.Any(m => m.dmPelsWidth == devMode.dmPelsWidth && m.dmPelsHeight == devMode.dmPelsHeight))
|
||||
{
|
||||
list.Add(devMode);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
list.Sort((a, b) => (int)(a.dmPelsWidth - b.dmPelsWidth));
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,212 @@
|
||||
using ColorControl.Shared.Common;
|
||||
using ColorControl.Shared.Contracts;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
|
||||
namespace ColorControl.Services.Common
|
||||
{
|
||||
enum PresetTriggerType
|
||||
{
|
||||
[Description("None")]
|
||||
None = 0,
|
||||
[Description("Startup")]
|
||||
Startup = 1,
|
||||
[Description("Resume")]
|
||||
Resume = 2,
|
||||
[Description("Shutdown")]
|
||||
Shutdown = 3,
|
||||
[Description("Standby")]
|
||||
Standby = 4,
|
||||
[Description("Reserved5")]
|
||||
Reserved5 = 5,
|
||||
[Description("Process switch")]
|
||||
ProcessSwitch = 6,
|
||||
[Description("Screensaver start")]
|
||||
ScreensaverStart = 7,
|
||||
[Description("Screensaver stop")]
|
||||
ScreensaverStop = 8,
|
||||
}
|
||||
|
||||
[Flags]
|
||||
enum PresetConditionType
|
||||
{
|
||||
[Description("None")]
|
||||
None = 0,
|
||||
[Description("SDR")]
|
||||
SDR = 1,
|
||||
[Description("HDR")]
|
||||
HDR = 2,
|
||||
[Description("Full Screen")]
|
||||
FullScreen = 4,
|
||||
[Description("Notifications Disabled")]
|
||||
NotificationsDisabled = 8,
|
||||
[Description("G-SYNC Disabled")]
|
||||
GsyncDisabled = 16,
|
||||
[Description("G-SYNC Enabled")]
|
||||
GsyncEnabled = 32
|
||||
}
|
||||
|
||||
class PresetTrigger
|
||||
{
|
||||
public PresetTriggerType Trigger { get; set; }
|
||||
public List<string> IncludedProcesses { get; set; }
|
||||
public List<string> ExcludedProcesses { get; set; }
|
||||
public PresetConditionType Conditions { get; set; }
|
||||
|
||||
public PresetTrigger()
|
||||
{
|
||||
IncludedProcesses = new List<string>();
|
||||
ExcludedProcesses = new List<string>();
|
||||
}
|
||||
|
||||
public bool TriggerActive(PresetTriggerContext context)
|
||||
{
|
||||
var active = Conditions == PresetConditionType.None ||
|
||||
(Conditions.HasFlag(PresetConditionType.SDR) ? !context.IsHDRActive : true) && (Conditions.HasFlag(PresetConditionType.HDR) ? context.IsHDRActive : true) &&
|
||||
(Conditions.HasFlag(PresetConditionType.GsyncDisabled) ? !context.IsGsyncActive : true) && (Conditions.HasFlag(PresetConditionType.GsyncEnabled) ? context.IsGsyncActive : true);
|
||||
var allProcesses = IncludedProcesses.Contains("*");
|
||||
|
||||
if (Trigger == PresetTriggerType.ProcessSwitch)
|
||||
{
|
||||
active = active && (allProcesses || (context.ChangedProcesses?.Any() ?? false));
|
||||
|
||||
if (active)
|
||||
{
|
||||
var included = allProcesses || context.ChangedProcesses.Any(cp => IncludedProcesses.Any(ip => cp.ProcessName.NormEquals(ip)));
|
||||
var excluded = context.ChangedProcesses.Any(cp => ExcludedProcesses.Any(ep => cp.ProcessName.NormEquals(ep)));
|
||||
|
||||
var screenSizeCheck = (!Conditions.HasFlag(PresetConditionType.FullScreen) && !context.ForegroundProcessIsFullScreen) ||
|
||||
(context.ForegroundProcess != null && context.ForegroundProcessIsFullScreen &&
|
||||
(allProcesses || IncludedProcesses.Any(ip => context.ForegroundProcess.ProcessName.NormEquals(ip))));
|
||||
|
||||
var notificationsDisabledCheck = !Conditions.HasFlag(PresetConditionType.NotificationsDisabled) || context.IsNotificationDisabled;
|
||||
|
||||
active = included && !excluded && screenSizeCheck && notificationsDisabledCheck;
|
||||
}
|
||||
}
|
||||
|
||||
return active;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
if (Trigger == PresetTriggerType.None)
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
return $"On {Trigger.GetDescription()} of {DisplayProcesses(IncludedProcesses)}{(ExcludedProcesses.Any() ? ", excluding " + DisplayProcesses(ExcludedProcesses) : string.Empty)}{(Conditions > 0 ? ", only in " + string.Join(", ", Utils.GetDescriptions<PresetConditionType>((int)Conditions)) : string.Empty)}";
|
||||
}
|
||||
|
||||
public static string DisplayProcesses(IEnumerable<string> processes)
|
||||
{
|
||||
return processes.Contains("*") ? "all processes" : string.Join(", ", processes);
|
||||
}
|
||||
}
|
||||
|
||||
class PresetTriggerContext
|
||||
{
|
||||
public bool IsHDRActive { get; set; }
|
||||
public bool IsGsyncActive { get; set; }
|
||||
public Process ForegroundProcess { get; set; }
|
||||
public bool ForegroundProcessIsFullScreen { get; set; }
|
||||
public List<Process> ChangedProcesses { get; set; }
|
||||
public bool IsNotificationDisabled { get; set; }
|
||||
}
|
||||
|
||||
internal abstract class PresetBase
|
||||
{
|
||||
public string name { get; set; }
|
||||
public string shortcut { get; set; }
|
||||
public List<PresetTrigger> Triggers { get; set; }
|
||||
public string Description { get; set; }
|
||||
public bool ShowInQuickAccess { get; set; }
|
||||
|
||||
private int _id;
|
||||
|
||||
protected PresetBase()
|
||||
{
|
||||
Triggers = new List<PresetTrigger>();
|
||||
}
|
||||
|
||||
public int id
|
||||
{
|
||||
get
|
||||
{
|
||||
return _id;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value == 0 || ids.Contains(value))
|
||||
{
|
||||
value = GetNewId();
|
||||
}
|
||||
else
|
||||
{
|
||||
ids.Add(value);
|
||||
}
|
||||
_id = value;
|
||||
}
|
||||
}
|
||||
|
||||
public static List<int> ids = new List<int>();
|
||||
|
||||
public static int GetNewId()
|
||||
{
|
||||
int id;
|
||||
do
|
||||
{
|
||||
id = new Random().Next();
|
||||
}
|
||||
while (ids.Contains(id));
|
||||
|
||||
ids.Add(id);
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
public abstract List<string> GetDisplayValues(Config config = null);
|
||||
|
||||
public virtual string GetTextForMenuItem()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
public void UpdateTrigger(PresetTriggerType triggerType, PresetConditionType conditions, string includedProcesses, string excludedProcesses)
|
||||
{
|
||||
if (!Triggers.Any())
|
||||
{
|
||||
Triggers.Add(new PresetTrigger());
|
||||
}
|
||||
|
||||
var trigger = Triggers.First();
|
||||
|
||||
trigger.Trigger = triggerType;
|
||||
trigger.Conditions = conditions;
|
||||
|
||||
if (trigger.IncludedProcesses == null)
|
||||
{
|
||||
trigger.IncludedProcesses = new List<string>();
|
||||
}
|
||||
if (trigger.ExcludedProcesses == null)
|
||||
{
|
||||
trigger.ExcludedProcesses = new List<string>();
|
||||
}
|
||||
Utils.ParseWords(trigger.IncludedProcesses, includedProcesses);
|
||||
Utils.ParseWords(trigger.ExcludedProcesses, excludedProcesses);
|
||||
}
|
||||
|
||||
public PresetTrigger AddTrigger()
|
||||
{
|
||||
if (!Triggers.Any())
|
||||
{
|
||||
Triggers.Add(new PresetTrigger());
|
||||
}
|
||||
|
||||
return Triggers.First();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,124 @@
|
||||
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace ColorControl.Services.Common
|
||||
{
|
||||
partial class QuickAccessForm<T> : Form where T : PresetBase, new()
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Windows Form Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.components = new System.ComponentModel.Container();
|
||||
this.flowPanel = new System.Windows.Forms.FlowLayoutPanel();
|
||||
this.btnClose = new System.Windows.Forms.Button();
|
||||
this.lblTitle = new System.Windows.Forms.Label();
|
||||
this.tmrHide = new System.Windows.Forms.Timer(this.components);
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// flowPanel
|
||||
//
|
||||
this.flowPanel.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
|
||||
| System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.flowPanel.FlowDirection = System.Windows.Forms.FlowDirection.TopDown;
|
||||
this.flowPanel.Location = new System.Drawing.Point(14, 33);
|
||||
this.flowPanel.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
this.flowPanel.Name = "flowPanel";
|
||||
this.flowPanel.Size = new System.Drawing.Size(270, 339);
|
||||
this.flowPanel.TabIndex = 0;
|
||||
this.flowPanel.MouseMove += new System.Windows.Forms.MouseEventHandler(this.flowPanel_MouseMove);
|
||||
//
|
||||
// btnClose
|
||||
//
|
||||
this.btnClose.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.btnClose.FlatAppearance.BorderColor = System.Drawing.Color.DarkGray;
|
||||
this.btnClose.FlatAppearance.BorderSize = 0;
|
||||
this.btnClose.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
|
||||
this.btnClose.ForeColor = System.Drawing.Color.White;
|
||||
this.btnClose.Location = new System.Drawing.Point(280, 0);
|
||||
this.btnClose.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
this.btnClose.Name = "btnClose";
|
||||
this.btnClose.Size = new System.Drawing.Size(16, 27);
|
||||
this.btnClose.TabIndex = 1;
|
||||
this.btnClose.TabStop = false;
|
||||
this.btnClose.Text = "x";
|
||||
this.btnClose.UseVisualStyleBackColor = true;
|
||||
this.btnClose.Click += new System.EventHandler(this.btnClose_Click);
|
||||
//
|
||||
// lblTitle
|
||||
//
|
||||
this.lblTitle.AutoSize = true;
|
||||
this.lblTitle.ForeColor = System.Drawing.Color.White;
|
||||
this.lblTitle.Location = new System.Drawing.Point(13, 6);
|
||||
this.lblTitle.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
|
||||
this.lblTitle.Name = "lblTitle";
|
||||
this.lblTitle.Size = new System.Drawing.Size(77, 15);
|
||||
this.lblTitle.TabIndex = 0;
|
||||
this.lblTitle.Text = "Quick Access";
|
||||
//
|
||||
// tmrHide
|
||||
//
|
||||
this.tmrHide.Interval = 5000;
|
||||
this.tmrHide.Tick += new System.EventHandler(this.tmrHide_Tick);
|
||||
//
|
||||
// QuickAccessForm
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.BackColor = System.Drawing.Color.Black;
|
||||
this.ClientSize = new System.Drawing.Size(298, 387);
|
||||
this.Controls.Add(this.lblTitle);
|
||||
this.Controls.Add(this.btnClose);
|
||||
this.Controls.Add(this.flowPanel);
|
||||
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
|
||||
this.KeyPreview = true;
|
||||
this.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
this.MaximizeBox = false;
|
||||
this.MinimizeBox = false;
|
||||
this.Name = "QuickAccessForm";
|
||||
this.Opacity = 0.8D;
|
||||
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
|
||||
this.Text = "RemoteControlForm";
|
||||
this.TopMost = true;
|
||||
this.Activated += new System.EventHandler(this.LgGameBar_Activated);
|
||||
this.Deactivate += new System.EventHandler(this.LgGameBar_Deactivate);
|
||||
this.Shown += new System.EventHandler(this.RemoteControlForm_Shown);
|
||||
this.KeyUp += new System.Windows.Forms.KeyEventHandler(this.RemoteControlForm_KeyUp);
|
||||
this.Move += new System.EventHandler(this.LgGameBar_Move);
|
||||
this.PreviewKeyDown += new System.Windows.Forms.PreviewKeyDownEventHandler(this.QuickAccessForm_PreviewKeyDown);
|
||||
this.ResumeLayout(false);
|
||||
this.PerformLayout();
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.FlowLayoutPanel flowPanel;
|
||||
private System.Windows.Forms.Button btnClose;
|
||||
private System.Windows.Forms.Label lblTitle;
|
||||
private System.Windows.Forms.Timer tmrHide;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,237 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace ColorControl.Services.Common
|
||||
{
|
||||
partial class QuickAccessForm<T> : Form where T : PresetBase, new()
|
||||
{
|
||||
private ServiceBase<T> _service;
|
||||
private List<Button> _buttons = new List<Button>();
|
||||
private bool _shown = false;
|
||||
|
||||
private static Dictionary<ServiceBase<T>, QuickAccessForm<T>> QuickAccessForms = new();
|
||||
|
||||
public static void ToggleQuickAccessForm(ServiceBase<T> service)
|
||||
{
|
||||
if (!QuickAccessForms.TryGetValue(service, out var form) || form.IsDisposed)
|
||||
{
|
||||
form = new QuickAccessForm<T>(service);
|
||||
QuickAccessForms.Add(service, form);
|
||||
}
|
||||
|
||||
|
||||
if (!form.Visible)
|
||||
{
|
||||
form.Show();
|
||||
form.Activate();
|
||||
}
|
||||
else
|
||||
{
|
||||
form.Hide();
|
||||
}
|
||||
}
|
||||
|
||||
public QuickAccessForm(ServiceBase<T> service)
|
||||
{
|
||||
_service = service;
|
||||
|
||||
InitializeComponent();
|
||||
|
||||
lblTitle.Text = $"Quick Access - {service.ServiceName}";
|
||||
}
|
||||
|
||||
private void GenerateComponents()
|
||||
{
|
||||
var presets = _service.GetPresets().Where(p => p.ShowInQuickAccess);
|
||||
|
||||
flowPanel.Controls.Clear();
|
||||
_buttons.Clear();
|
||||
|
||||
if (presets.Any())
|
||||
{
|
||||
foreach (var preset in presets)
|
||||
{
|
||||
CreateGroup(preset);
|
||||
}
|
||||
Height = Height - flowPanel.Height + (_buttons.Count() * 46) + 8;
|
||||
|
||||
return;
|
||||
}
|
||||
var panel = new Panel();
|
||||
panel.Width = flowPanel.Width - 4;
|
||||
panel.Height = 40;
|
||||
|
||||
var label = new Label();
|
||||
label.Text = "No Quick Access presets configured";
|
||||
label.Parent = panel;
|
||||
label.AutoSize = true;
|
||||
label.ForeColor = Color.White;
|
||||
|
||||
panel.Parent = flowPanel;
|
||||
|
||||
Height = Height - flowPanel.Height + 36;
|
||||
}
|
||||
|
||||
private Button CreateGroup(PresetBase preset)
|
||||
{
|
||||
var panel = new Panel();
|
||||
panel.Width = flowPanel.Width - 4;
|
||||
panel.Height = 40;
|
||||
|
||||
var button = new Button();
|
||||
button.Text = preset.name;
|
||||
button.Tag = preset;
|
||||
button.Font = new Font(button.Font, FontStyle.Bold);
|
||||
button.Parent = panel;
|
||||
button.Width = panel.Width - 4;
|
||||
button.Height = panel.Height - 4;
|
||||
var margin = button.Margin;
|
||||
margin.Top = 0;
|
||||
margin.Bottom = 0;
|
||||
button.Margin = margin;
|
||||
button.ForeColor = Color.White;
|
||||
button.FlatStyle = FlatStyle.Flat;
|
||||
button.FlatAppearance.BorderColor = Color.DarkGray;
|
||||
button.FlatAppearance.MouseOverBackColor = Color.DimGray;
|
||||
button.Click += Button_Click;
|
||||
|
||||
panel.Parent = flowPanel;
|
||||
|
||||
_buttons.Add(button);
|
||||
|
||||
return button;
|
||||
}
|
||||
|
||||
private void Button_Click(object sender, EventArgs e)
|
||||
{
|
||||
var preset = (T)(sender as Button).Tag;
|
||||
|
||||
if (NWin32.NativeMethods.GetAsyncKeyState(NWin32.NativeConstants.VK_SHIFT) < 0)
|
||||
{
|
||||
preset.ShowInQuickAccess = false;
|
||||
|
||||
GenerateComponents();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
Hide();
|
||||
|
||||
var _ = _service.ApplyPreset(preset);
|
||||
}
|
||||
|
||||
private void btnClose_Click(object sender, EventArgs e)
|
||||
{
|
||||
Hide();
|
||||
}
|
||||
|
||||
private void HandleKey(Keys key)
|
||||
{
|
||||
if (key == Keys.Escape)
|
||||
{
|
||||
Hide();
|
||||
return;
|
||||
}
|
||||
|
||||
ResetAutoHide();
|
||||
|
||||
if (!_buttons.Any())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(ActiveControl is Button button))
|
||||
{
|
||||
_buttons.First().Focus();
|
||||
return;
|
||||
}
|
||||
var diff = 0;
|
||||
|
||||
if (key == Keys.Up)
|
||||
{
|
||||
diff = -1;
|
||||
}
|
||||
else if (key == Keys.Down)
|
||||
{
|
||||
diff = 1;
|
||||
}
|
||||
|
||||
if (diff == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var index = _buttons.IndexOf(button);
|
||||
index += diff;
|
||||
|
||||
if (index == -1)
|
||||
{
|
||||
index = _buttons.Count - 1;
|
||||
}
|
||||
else if (index == _buttons.Count)
|
||||
{
|
||||
index = 0;
|
||||
}
|
||||
|
||||
button = _buttons[index];
|
||||
|
||||
button.Focus();
|
||||
}
|
||||
|
||||
private void RemoteControlForm_KeyUp(object sender, KeyEventArgs e)
|
||||
{
|
||||
HandleKey(e.KeyCode);
|
||||
}
|
||||
|
||||
private void flowPanel_MouseMove(object sender, MouseEventArgs e)
|
||||
{
|
||||
ResetAutoHide();
|
||||
}
|
||||
|
||||
private void RemoteControlForm_Shown(object sender, EventArgs e)
|
||||
{
|
||||
GenerateComponents();
|
||||
ResetAutoHide();
|
||||
|
||||
_shown = true;
|
||||
}
|
||||
|
||||
private void LgGameBar_Deactivate(object sender, EventArgs e)
|
||||
{
|
||||
Hide();
|
||||
}
|
||||
|
||||
private void tmrHide_Tick(object sender, EventArgs e)
|
||||
{
|
||||
Hide();
|
||||
}
|
||||
|
||||
private void LgGameBar_Activated(object sender, EventArgs e)
|
||||
{
|
||||
if (_shown)
|
||||
{
|
||||
GenerateComponents();
|
||||
}
|
||||
ResetAutoHide();
|
||||
}
|
||||
|
||||
private void LgGameBar_Move(object sender, EventArgs e)
|
||||
{
|
||||
ResetAutoHide();
|
||||
}
|
||||
|
||||
private void ResetAutoHide()
|
||||
{
|
||||
tmrHide.Enabled = false;
|
||||
tmrHide.Enabled = true;
|
||||
}
|
||||
|
||||
private void QuickAccessForm_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
|
||||
{
|
||||
HandleKey(e.KeyCode);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
<root>
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<metadata name="tmrHide.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>17, 17</value>
|
||||
</metadata>
|
||||
</root>
|
||||
@@ -0,0 +1,180 @@
|
||||
using ColorControl.Shared.Services;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace ColorControl.Services.Common
|
||||
{
|
||||
abstract class ServiceBase<T> where T : PresetBase, new()
|
||||
{
|
||||
private static readonly NLog.Logger Logger = NLog.LogManager.GetCurrentClassLogger();
|
||||
|
||||
public event EventHandler<T> AfterApplyPreset;
|
||||
|
||||
public abstract string ServiceName
|
||||
{
|
||||
get;
|
||||
}
|
||||
protected abstract string PresetsBaseFilename { get; }
|
||||
|
||||
protected string _dataPath;
|
||||
protected string _presetsFilename;
|
||||
protected string _presetsBackupFilename;
|
||||
protected bool _initialized = false;
|
||||
protected List<T> _presets;
|
||||
protected T _lastAppliedPreset;
|
||||
protected string _loadPresetsError;
|
||||
|
||||
protected AppContextProvider _appContextProvider;
|
||||
|
||||
private List<JsonConverter> _jsonConverters;
|
||||
|
||||
public ServiceBase(AppContextProvider appContextProvider)
|
||||
{
|
||||
_appContextProvider = appContextProvider;
|
||||
_dataPath = appContextProvider.GetAppContext().DataPath;
|
||||
_jsonConverters = new List<JsonConverter>();
|
||||
|
||||
Initialize();
|
||||
}
|
||||
|
||||
~ServiceBase()
|
||||
{
|
||||
Uninitialize();
|
||||
}
|
||||
|
||||
public List<T> GetPresets()
|
||||
{
|
||||
return _presets;
|
||||
}
|
||||
|
||||
public T GetPresetByIdOrName(string idOrName)
|
||||
{
|
||||
var preset = _presets.FirstOrDefault(p => p.name != null && p.name.Equals(idOrName, StringComparison.OrdinalIgnoreCase));
|
||||
if (preset == null && int.TryParse(idOrName, out var id))
|
||||
{
|
||||
preset = _presets.FirstOrDefault(p => p.id == id);
|
||||
}
|
||||
|
||||
return preset;
|
||||
}
|
||||
|
||||
public abstract Task<bool> ApplyPreset(T preset);
|
||||
|
||||
public T GetLastAppliedPreset()
|
||||
{
|
||||
return _lastAppliedPreset;
|
||||
}
|
||||
|
||||
public virtual T CreateNewPreset()
|
||||
{
|
||||
var preset = new T();
|
||||
preset.name = CreateNewPresetName();
|
||||
|
||||
return preset;
|
||||
}
|
||||
|
||||
public string CreateNewPresetName()
|
||||
{
|
||||
var name = "New preset";
|
||||
string fullname;
|
||||
var number = 1;
|
||||
do
|
||||
{
|
||||
fullname = $"{name} ({number})";
|
||||
number++;
|
||||
} while (_presets.Any(x => x.name?.Equals(fullname) == true));
|
||||
|
||||
return fullname;
|
||||
}
|
||||
|
||||
protected virtual void Initialize()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
protected virtual void Uninitialize()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
protected void PresetApplied()
|
||||
{
|
||||
AfterApplyPreset?.Invoke(this, _lastAppliedPreset);
|
||||
}
|
||||
|
||||
protected void LoadPresets()
|
||||
{
|
||||
_presetsFilename = Path.Combine(_dataPath, PresetsBaseFilename);
|
||||
_presetsBackupFilename = Path.Combine(_dataPath, $"{PresetsBaseFilename}.backup");
|
||||
|
||||
try
|
||||
{
|
||||
var presetsExists = File.Exists(_presetsFilename);
|
||||
if (presetsExists)
|
||||
{
|
||||
try
|
||||
{
|
||||
var json = File.ReadAllText(_presetsFilename);
|
||||
|
||||
// Hack to convert incorrect triggers
|
||||
json = json.Replace(@"""Triggers"":0", @"""Triggers"":[]");
|
||||
|
||||
_presets = JsonConvert.DeserializeObject<List<T>>(json, _jsonConverters.ToArray());
|
||||
|
||||
if (_presets != null)
|
||||
{
|
||||
if (File.Exists(_presetsBackupFilename))
|
||||
{
|
||||
File.Delete(_presetsBackupFilename);
|
||||
}
|
||||
File.Copy(_presetsFilename, _presetsBackupFilename);
|
||||
}
|
||||
}
|
||||
catch (Exception ex1)
|
||||
{
|
||||
Logger.Error($"Error while loading presets, reverting to default presets: {ex1.Message}");
|
||||
_loadPresetsError = ex1.Message;
|
||||
}
|
||||
}
|
||||
if (!presetsExists || _presets == null)
|
||||
{
|
||||
Logger.Debug("Reverting to default presets");
|
||||
try
|
||||
{
|
||||
_presets = GetDefaultPresets();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.Error($"Error loading default presets, reverting to empty list: {e.Message}");
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Error($"General error while loading presets, reverting to empty list: {ex.Message}");
|
||||
_loadPresetsError = ex.Message;
|
||||
}
|
||||
if (_presets == null)
|
||||
{
|
||||
_presets = new List<T>();
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract List<T> GetDefaultPresets();
|
||||
|
||||
protected void AddJsonConverter(JsonConverter jsonConverter)
|
||||
{
|
||||
_jsonConverters.Add(jsonConverter);
|
||||
}
|
||||
|
||||
public void ToggleQuickAccessForm()
|
||||
{
|
||||
QuickAccessForm<T>.ToggleQuickAccessForm(this);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,133 @@
|
||||
using ColorControl.Services.Common;
|
||||
using ColorControl.Shared.Contracts;
|
||||
using ColorControl.Shared.Forms;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace ColorControl.Shared.Forms
|
||||
{
|
||||
static class ServiceFormUtils
|
||||
{
|
||||
public static void AddOrUpdateListItem<T>(ListView listView, List<T> presets, Config config, T preset = null, ListViewItem specItem = null) where T : PresetBase
|
||||
{
|
||||
ListViewItem item = null;
|
||||
if (preset == null)
|
||||
{
|
||||
item = listView.SelectedItems[0];
|
||||
preset = (T)item.Tag;
|
||||
}
|
||||
else
|
||||
{
|
||||
item = specItem;
|
||||
}
|
||||
|
||||
if (preset.id == 0)
|
||||
{
|
||||
preset.id = preset.GetHashCode();
|
||||
}
|
||||
|
||||
var values = preset.GetDisplayValues(config);
|
||||
|
||||
if (item == null)
|
||||
{
|
||||
item = listView.Items.Add(values[0]);
|
||||
item.Tag = preset;
|
||||
item.Checked = preset.ShowInQuickAccess;
|
||||
for (var i = 1; i < values.Count; i++)
|
||||
{
|
||||
item.SubItems.Add(values[i]);
|
||||
}
|
||||
if (!presets.Any(x => x.id == preset.id))
|
||||
{
|
||||
presets.Add(preset);
|
||||
listView.SelectedIndices.Clear();
|
||||
listView.SelectedIndices.Add(item.Index);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
item.Text = values[0];
|
||||
item.Checked = preset.ShowInQuickAccess;
|
||||
for (var i = 1; i < values.Count; i++)
|
||||
{
|
||||
if (item.SubItems.Count == i)
|
||||
{
|
||||
item.SubItems.Add(values[i]);
|
||||
}
|
||||
else
|
||||
{
|
||||
item.SubItems[i].Text = values[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (listView.ListViewItemSorter is ListViewColumnSorter sorter && sorter?.Order != SortOrder.None)
|
||||
{
|
||||
listView.Sort();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static void ListViewItemChecked<T>(ListView listView, ItemCheckedEventArgs e) where T : PresetBase
|
||||
{
|
||||
var checkedPreset = (T)e.Item.Tag;
|
||||
|
||||
if (checkedPreset == null || checkedPreset.ShowInQuickAccess == e.Item.Checked)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var point = listView.PointToClient(Cursor.Position);
|
||||
|
||||
if (point.X >= 20)
|
||||
{
|
||||
e.Item.Checked = !e.Item.Checked;
|
||||
return;
|
||||
}
|
||||
|
||||
checkedPreset.ShowInQuickAccess = e.Item.Checked;
|
||||
|
||||
var preset = listView.GetSelectedItemTag<T>();
|
||||
|
||||
if (preset == checkedPreset)
|
||||
{
|
||||
listView.FireEvent("SelectedIndexChanged", listView, e);
|
||||
}
|
||||
}
|
||||
|
||||
public static void BuildServicePresetsMenu<T>(ToolStripMenuItem menu, ServiceBase<T> service, string name, EventHandler eventHandler) where T : PresetBase, new()
|
||||
{
|
||||
menu.DropDownItems.Clear();
|
||||
|
||||
foreach (var nvPreset in service?.GetPresets() ?? new List<T>())
|
||||
{
|
||||
var text = nvPreset.name;
|
||||
|
||||
if (!string.IsNullOrEmpty(text))
|
||||
{
|
||||
var item = menu.DropDownItems.AddCustom(text);
|
||||
item.Tag = nvPreset;
|
||||
item.Click += eventHandler;
|
||||
}
|
||||
}
|
||||
|
||||
menu.Visible = service != null;
|
||||
|
||||
menu.Text = menu.DropDownItems.Count > 0 ? $"{name} presets" : $"{name} presets (no named presets found)";
|
||||
}
|
||||
|
||||
public static void UpdateShortcutTextBox(TextBox edtShortcut, PresetBase preset)
|
||||
{
|
||||
if (preset == null || string.IsNullOrEmpty(edtShortcut.Text))
|
||||
{
|
||||
edtShortcut.ForeColor = FormUtils.CurrentForeColor;
|
||||
}
|
||||
else
|
||||
{
|
||||
//edtShortcutLg.ForeColor = ShortCutExists(text, preset.id) ? Color.Red : SystemColors.WindowText;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
using ColorControl.Services.AMD;
|
||||
using ColorControl.Services.GameLauncher;
|
||||
using ColorControl.Services.LG;
|
||||
using ColorControl.Services.NVIDIA;
|
||||
using ColorControl.Services.Samsung;
|
||||
using ColorControl.Shared.Services;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace ColorControl.Services.Common;
|
||||
|
||||
public class ServiceManager
|
||||
{
|
||||
private readonly WinApiAdminService _winApiAdminService;
|
||||
|
||||
internal NvService NvService { get; set; }
|
||||
internal LgService LgService { get; set; }
|
||||
internal AmdService AmdService { get; set; }
|
||||
internal GameService GameService { get; set; }
|
||||
internal SamsungService SamsungService { get; set; }
|
||||
|
||||
public ServiceManager(WinApiAdminService winApiAdminService)
|
||||
{
|
||||
_winApiAdminService = winApiAdminService;
|
||||
}
|
||||
|
||||
public async Task<bool> HandleExternalServiceAsync(string serviceName, string[] parameters)
|
||||
{
|
||||
if (string.IsNullOrEmpty(serviceName) || parameters.Length == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (NvService != null && serviceName.Equals("NvPreset", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return await NvService.ApplyPreset(parameters[0]);
|
||||
}
|
||||
if (NvService != null && serviceName.Equals("GsyncEnabled", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return NvService.IsGsyncEnabled();
|
||||
}
|
||||
if (AmdService != null && serviceName.Equals("AmdPreset", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return await AmdService.ApplyPreset(parameters[0]);
|
||||
}
|
||||
if (LgService != null && serviceName.Equals("LgPreset", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
await LgService.ApplyPreset(parameters[0]);
|
||||
|
||||
return true;
|
||||
}
|
||||
if (SamsungService != null && serviceName.Equals("SamsungPreset", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
await SamsungService.ApplyPreset(parameters[0]);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if (serviceName.Equals("StartProgram", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
_winApiAdminService.StartProcess(parameters[0], parameters.Length > 1 ? string.Join(" ", parameters.Skip(1)) : null, setWorkingDir: true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public void Save()
|
||||
{
|
||||
NvService?.GlobalSave();
|
||||
AmdService?.GlobalSave();
|
||||
LgService?.GlobalSave();
|
||||
GameService?.GlobalSave();
|
||||
SamsungService?.GlobalSave();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using static ColorControl.Services.EventDispatcher.EventExtensions;
|
||||
|
||||
namespace ColorControl.Services.EventDispatcher;
|
||||
|
||||
public class EventDispatcher<T> where T : EventArgs
|
||||
{
|
||||
private Dictionary<string, EventHandler<T>> eventHandlers = new Dictionary<string, EventHandler<T>>();
|
||||
private Dictionary<string, AsyncEventHandler<T>> asyncEventHandlers = new Dictionary<string, AsyncEventHandler<T>>();
|
||||
|
||||
public void RegisterEventHandler(string eventName, EventHandler<T> eventHandler)
|
||||
{
|
||||
if (!eventHandlers.ContainsKey(eventName))
|
||||
{
|
||||
eventHandlers.Add(eventName, eventHandler);
|
||||
}
|
||||
else
|
||||
{
|
||||
eventHandlers[eventName] += eventHandler;
|
||||
}
|
||||
}
|
||||
|
||||
public void RegisterAsyncEventHandler(string eventName, AsyncEventHandler<T> eventHandler)
|
||||
{
|
||||
if (!asyncEventHandlers.ContainsKey(eventName))
|
||||
{
|
||||
asyncEventHandlers.Add(eventName, eventHandler);
|
||||
}
|
||||
else
|
||||
{
|
||||
asyncEventHandlers[eventName] += eventHandler;
|
||||
}
|
||||
}
|
||||
|
||||
public void UnregisterEventHandler(string eventName)
|
||||
{
|
||||
eventHandlers.Remove(eventName);
|
||||
}
|
||||
|
||||
public void DispatchEvent(string eventName, T eventArgs)
|
||||
{
|
||||
if (eventHandlers.ContainsKey(eventName))
|
||||
{
|
||||
eventHandlers[eventName]?.Invoke(this, eventArgs);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task DispatchEventAsync(string eventName, T eventArgs)
|
||||
{
|
||||
if (asyncEventHandlers.ContainsKey(eventName))
|
||||
{
|
||||
await asyncEventHandlers[eventName]?.InvokeAsync(this, eventArgs);
|
||||
}
|
||||
}
|
||||
|
||||
protected bool HasHandlers(string eventName)
|
||||
{
|
||||
return eventHandlers.ContainsKey(eventName) || asyncEventHandlers.ContainsKey(eventName);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace ColorControl.Services.EventDispatcher
|
||||
{
|
||||
public static class EventExtensions
|
||||
{
|
||||
public delegate Task AsyncEventHandler<TEventArgs>(object sender, TEventArgs e, CancellationToken token);
|
||||
|
||||
public static Task InvokeAsync<TArgs>(this AsyncEventHandler<TArgs> func, object sender, TArgs e)
|
||||
{
|
||||
return func == null ? Task.CompletedTask
|
||||
: Task.WhenAll(func.GetInvocationList().Cast<AsyncEventHandler<TArgs>>().Select(f => f(sender, e, CancellationToken.None)));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
using Microsoft.Win32;
|
||||
using System;
|
||||
|
||||
namespace ColorControl.Services.EventDispatcher
|
||||
{
|
||||
public enum PowerOnOffState
|
||||
{
|
||||
None = 0,
|
||||
StartUp = 1,
|
||||
Resume = 2,
|
||||
ScreenSaver = 3,
|
||||
ShutDown = 4,
|
||||
StandBy = 5,
|
||||
MonitorOff = 6,
|
||||
MonitorOn = 7
|
||||
}
|
||||
|
||||
internal enum WindowsMonitorPowerSetting
|
||||
{
|
||||
Off = 0,
|
||||
On = 1,
|
||||
Dimmed = 2
|
||||
}
|
||||
|
||||
public class PowerStateChangedEventArgs : EventArgs
|
||||
{
|
||||
public PowerOnOffState State { get; private set; }
|
||||
|
||||
public PowerStateChangedEventArgs(PowerOnOffState state)
|
||||
{
|
||||
State = state;
|
||||
}
|
||||
}
|
||||
|
||||
public class PowerEventDispatcher : EventDispatcher<PowerStateChangedEventArgs>
|
||||
{
|
||||
public const string Event_Suspend = "Suspend";
|
||||
public const string Event_Resume = "Resume";
|
||||
public const string Event_Shutdown = "Shutdown";
|
||||
public const string Event_MonitorOff = "MonitorOff";
|
||||
public const string Event_MonitorOn = "MonitorOn";
|
||||
|
||||
public PowerEventDispatcher()
|
||||
{
|
||||
SystemEvents.PowerModeChanged += OnPowerModeChanged;
|
||||
}
|
||||
|
||||
public void SendEvent(string eventName)
|
||||
{
|
||||
var state = eventName switch
|
||||
{
|
||||
Event_Shutdown => PowerOnOffState.ShutDown,
|
||||
Event_MonitorOff => PowerOnOffState.MonitorOff,
|
||||
Event_MonitorOn => PowerOnOffState.MonitorOn,
|
||||
_ => PowerOnOffState.None
|
||||
};
|
||||
|
||||
if (state == PowerOnOffState.None)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
DispatchEvent(eventName, new PowerStateChangedEventArgs(state));
|
||||
}
|
||||
|
||||
private void OnPowerModeChanged(object sender, PowerModeChangedEventArgs e)
|
||||
{
|
||||
if (e.Mode == PowerModes.Suspend)
|
||||
{
|
||||
DispatchEvent(Event_Suspend, new PowerStateChangedEventArgs(PowerOnOffState.StandBy));
|
||||
}
|
||||
else if (e.Mode == PowerModes.Resume)
|
||||
{
|
||||
DispatchEvent(Event_Resume, new PowerStateChangedEventArgs(PowerOnOffState.Resume));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,127 @@
|
||||
using ColorControl.Shared.Common;
|
||||
using ColorControl.Shared.Forms;
|
||||
using ColorControl.Shared.Services;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Management;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace ColorControl.Services.EventDispatcher
|
||||
{
|
||||
public class ProcessChangedEventArgs : EventArgs
|
||||
{
|
||||
public IList<Process> StartedProcesses { get; set; }
|
||||
public IList<Process> StoppedProcesses { get; set; }
|
||||
public IList<Process> RunningProcesses { get; set; }
|
||||
public bool IsNotificationDisabled { get; set; }
|
||||
public Process ForegroundProcess { get; set; }
|
||||
public bool ForegroundProcessIsFullScreen { get; set; }
|
||||
public string LastFullScreenProcessName = string.Empty;
|
||||
public bool StoppedFullScreen { get; set; }
|
||||
public bool IsScreenSaverActive { get; set; }
|
||||
}
|
||||
|
||||
|
||||
public class ProcessEventDispatcher : EventDispatcher<ProcessChangedEventArgs>
|
||||
{
|
||||
public const string Event_ProcessChanged = "ProcessChanged";
|
||||
public bool IsRunning { get; set; }
|
||||
public ProcessChangedEventArgs MonitorContext { get; private set; }
|
||||
|
||||
protected static readonly NLog.Logger Logger = NLog.LogManager.GetCurrentClassLogger();
|
||||
|
||||
private AppContextProvider _appContextProvider { get; }
|
||||
|
||||
public ProcessEventDispatcher(AppContextProvider appContextProvider)
|
||||
{
|
||||
_appContextProvider = appContextProvider;
|
||||
|
||||
IsRunning = true;
|
||||
|
||||
//Task.Run(async () => await CheckProcesses());
|
||||
|
||||
var _ = CheckProcesses();
|
||||
}
|
||||
|
||||
private async Task CheckProcesses()
|
||||
{
|
||||
await Task.Delay(2000);
|
||||
|
||||
//var startWatch = new ManagementEventWatcher("SELECT * FROM Win32_ProcessStartTrace");
|
||||
//startWatch.EventArrived += startWatch_EventArrived;
|
||||
//startWatch.Start();
|
||||
|
||||
MonitorContext ??= new ProcessChangedEventArgs();
|
||||
|
||||
while (IsRunning)
|
||||
{
|
||||
await Task.Delay(_appContextProvider.GetAppContext().Config.ProcessMonitorPollingInterval);
|
||||
|
||||
if (!HasHandlers(Event_ProcessChanged))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
FillContext(MonitorContext);
|
||||
|
||||
// Ignore if own process has the foreground
|
||||
if (MonitorContext.ForegroundProcess?.Id == Environment.ProcessId)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
await DispatchEventAsync(Event_ProcessChanged, MonitorContext);
|
||||
DispatchEvent(Event_ProcessChanged, MonitorContext);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Error("CheckProcesses: " + ex.ToLogString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void FillContext(ProcessChangedEventArgs context)
|
||||
{
|
||||
var processes = Process.GetProcesses();
|
||||
|
||||
context.StartedProcesses = processes.Where(p => context.RunningProcesses?.Any(rp => rp.Id == p.Id) == false).ToList();
|
||||
context.StoppedProcesses = context.RunningProcesses?.Where(p => processes.Any(rp => rp.Id == p.Id) == false).ToList();
|
||||
context.RunningProcesses = processes;
|
||||
|
||||
context.IsNotificationDisabled = FormUtils.IsNotificationDisabled();
|
||||
|
||||
var (processId, isFullScreen) = FormUtils.GetForegroundProcessIdAndIfFullScreen();
|
||||
|
||||
if (processId > 0)
|
||||
{
|
||||
var process = context.RunningProcesses.FirstOrDefault(p => p.Id == processId);
|
||||
|
||||
context.IsScreenSaverActive = process?.ProcessName?.Contains(".scr") == true;
|
||||
context.ForegroundProcess = process;
|
||||
context.ForegroundProcessIsFullScreen = isFullScreen;
|
||||
|
||||
if (isFullScreen)
|
||||
{
|
||||
context.LastFullScreenProcessName = context.ForegroundProcess.ProcessName;
|
||||
//Logger.Debug($"Foreground fullscreen app detected: {context.ForegroundProcess.ProcessName}");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
context.StoppedFullScreen = context.ForegroundProcessIsFullScreen;
|
||||
context.ForegroundProcess = null;
|
||||
context.ForegroundProcessIsFullScreen = false;
|
||||
context.LastFullScreenProcessName = string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
private void startWatch_EventArrived(object sender, EventArrivedEventArgs e)
|
||||
{
|
||||
//Logger.Debug("Process started: " + e.NewEvent.Properties["ProcessName"].Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
using Microsoft.Win32;
|
||||
|
||||
namespace ColorControl.Services.EventDispatcher
|
||||
{
|
||||
public class SessionSwitchDispatcher : EventDispatcher<SessionSwitchEventArgs>
|
||||
{
|
||||
public const string Event_SessionSwitch = "SessionSwitch";
|
||||
|
||||
private static readonly NLog.Logger Logger = NLog.LogManager.GetCurrentClassLogger();
|
||||
|
||||
public bool UserLocalSession { get; private set; } = true;
|
||||
public SessionSwitchReason LastSessionSwitchReason { get; private set; } = 0;
|
||||
|
||||
public SessionSwitchDispatcher()
|
||||
{
|
||||
SystemEvents.SessionSwitch += SessionSwitchHandler;
|
||||
}
|
||||
|
||||
public void SessionSwitchHandler(object sender, SessionSwitchEventArgs evt)
|
||||
{
|
||||
if (evt.Reason == SessionSwitchReason.ConsoleDisconnect)
|
||||
{
|
||||
Logger.Debug("Detected a disconnect from the console");
|
||||
UserLocalSession = false;
|
||||
|
||||
DispatchEvent(Event_SessionSwitch, evt);
|
||||
}
|
||||
else if (evt.Reason == SessionSwitchReason.ConsoleConnect)
|
||||
{
|
||||
Logger.Debug("Detected a connect to the console");
|
||||
if (!UserLocalSession)
|
||||
{
|
||||
Logger.Debug("Session state switched to local");
|
||||
UserLocalSession = true;
|
||||
DispatchEvent(Event_SessionSwitch, evt);
|
||||
}
|
||||
}
|
||||
LastSessionSwitchReason = evt.Reason;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,493 @@
|
||||
namespace ColorControl.Services.GameLauncher
|
||||
{
|
||||
partial class GamePanel
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Component Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
components = new System.ComponentModel.Container();
|
||||
cbxGameStepType = new System.Windows.Forms.ComboBox();
|
||||
btnGameOptions = new System.Windows.Forms.Button();
|
||||
mnuGameOptions = new System.Windows.Forms.ContextMenuStrip(components);
|
||||
miGameProcessorAffinity = new System.Windows.Forms.ToolStripMenuItem();
|
||||
miGameProcessPriority = new System.Windows.Forms.ToolStripMenuItem();
|
||||
miPresetNVIDIAProfileInspector = new System.Windows.Forms.ToolStripMenuItem();
|
||||
chkGameQuickAccess = new System.Windows.Forms.CheckBox();
|
||||
btnGameSettings = new System.Windows.Forms.Button();
|
||||
mnuGameActions = new System.Windows.Forms.ContextMenuStrip(components);
|
||||
mnuGameNvInspector = new System.Windows.Forms.ToolStripMenuItem();
|
||||
miGameSetQuickAccessShortcut = new System.Windows.Forms.ToolStripMenuItem();
|
||||
chkGameRunAsAdmin = new System.Windows.Forms.CheckBox();
|
||||
lblGameParameters = new System.Windows.Forms.Label();
|
||||
edtGameParameters = new System.Windows.Forms.TextBox();
|
||||
btnGameBrowse = new System.Windows.Forms.Button();
|
||||
lblGameFilePath = new System.Windows.Forms.Label();
|
||||
edtGamePath = new System.Windows.Forms.TextBox();
|
||||
edtGamePrelaunchSteps = new System.Windows.Forms.TextBox();
|
||||
btnGameAddStep = new System.Windows.Forms.Button();
|
||||
mnuGameAddStep = new System.Windows.Forms.ContextMenuStrip(components);
|
||||
mnuGameNvidiaPresets = new System.Windows.Forms.ToolStripMenuItem();
|
||||
mnuGameAmdPresets = new System.Windows.Forms.ToolStripMenuItem();
|
||||
mnuGameLgPresets = new System.Windows.Forms.ToolStripMenuItem();
|
||||
mnuGameSamsungPresets = new System.Windows.Forms.ToolStripMenuItem();
|
||||
mnuGameStartProgram = new System.Windows.Forms.ToolStripMenuItem();
|
||||
label4 = new System.Windows.Forms.Label();
|
||||
edtGameName = new System.Windows.Forms.TextBox();
|
||||
btnGameDelete = new System.Windows.Forms.Button();
|
||||
btnGameClone = new System.Windows.Forms.Button();
|
||||
btnGameSave = new System.Windows.Forms.Button();
|
||||
btnGameAdd = new System.Windows.Forms.Button();
|
||||
btnGameLaunch = new System.Windows.Forms.Button();
|
||||
lvGamePresets = new System.Windows.Forms.ListView();
|
||||
miGameOptionsAutoApplySettings = new System.Windows.Forms.ToolStripMenuItem();
|
||||
mnuGameOptions.SuspendLayout();
|
||||
mnuGameActions.SuspendLayout();
|
||||
mnuGameAddStep.SuspendLayout();
|
||||
SuspendLayout();
|
||||
//
|
||||
// cbxGameStepType
|
||||
//
|
||||
cbxGameStepType.Anchor = System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left;
|
||||
cbxGameStepType.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
|
||||
cbxGameStepType.Enabled = false;
|
||||
cbxGameStepType.FormattingEnabled = true;
|
||||
cbxGameStepType.Location = new System.Drawing.Point(10, 474);
|
||||
cbxGameStepType.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
cbxGameStepType.Name = "cbxGameStepType";
|
||||
cbxGameStepType.Size = new System.Drawing.Size(136, 23);
|
||||
cbxGameStepType.TabIndex = 46;
|
||||
cbxGameStepType.SelectedIndexChanged += cbxGameStepType_SelectedIndexChanged;
|
||||
//
|
||||
// btnGameOptions
|
||||
//
|
||||
btnGameOptions.Anchor = System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left;
|
||||
btnGameOptions.ContextMenuStrip = mnuGameOptions;
|
||||
btnGameOptions.Enabled = false;
|
||||
btnGameOptions.Location = new System.Drawing.Point(785, 439);
|
||||
btnGameOptions.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
btnGameOptions.Name = "btnGameOptions";
|
||||
btnGameOptions.Size = new System.Drawing.Size(88, 27);
|
||||
btnGameOptions.TabIndex = 45;
|
||||
btnGameOptions.Text = "Options...";
|
||||
btnGameOptions.UseVisualStyleBackColor = true;
|
||||
btnGameOptions.Click += btnGameOptions_Click;
|
||||
//
|
||||
// mnuGameOptions
|
||||
//
|
||||
mnuGameOptions.ImageScalingSize = new System.Drawing.Size(20, 20);
|
||||
mnuGameOptions.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { miGameProcessorAffinity, miGameProcessPriority, miPresetNVIDIAProfileInspector, miGameOptionsAutoApplySettings });
|
||||
mnuGameOptions.Name = "mnuLgButtons";
|
||||
mnuGameOptions.Size = new System.Drawing.Size(202, 114);
|
||||
//
|
||||
// miGameProcessorAffinity
|
||||
//
|
||||
miGameProcessorAffinity.Name = "miGameProcessorAffinity";
|
||||
miGameProcessorAffinity.Size = new System.Drawing.Size(201, 22);
|
||||
miGameProcessorAffinity.Text = "Processor affinity";
|
||||
miGameProcessorAffinity.Click += btnGameProcessAffinity_Click;
|
||||
//
|
||||
// miGameProcessPriority
|
||||
//
|
||||
miGameProcessPriority.Name = "miGameProcessPriority";
|
||||
miGameProcessPriority.Size = new System.Drawing.Size(201, 22);
|
||||
miGameProcessPriority.Text = "Process priority";
|
||||
miGameProcessPriority.Click += miGameProcessPriority_Click;
|
||||
//
|
||||
// miPresetNVIDIAProfileInspector
|
||||
//
|
||||
miPresetNVIDIAProfileInspector.Name = "miPresetNVIDIAProfileInspector";
|
||||
miPresetNVIDIAProfileInspector.Size = new System.Drawing.Size(201, 22);
|
||||
miPresetNVIDIAProfileInspector.Text = "NVIDIA Profile Inspector";
|
||||
miPresetNVIDIAProfileInspector.Click += miPresetNVIDIAProfileInspector_Click;
|
||||
//
|
||||
// chkGameQuickAccess
|
||||
//
|
||||
chkGameQuickAccess.Anchor = System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left;
|
||||
chkGameQuickAccess.AutoSize = true;
|
||||
chkGameQuickAccess.Enabled = false;
|
||||
chkGameQuickAccess.Location = new System.Drawing.Point(353, 387);
|
||||
chkGameQuickAccess.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
chkGameQuickAccess.Name = "chkGameQuickAccess";
|
||||
chkGameQuickAccess.Size = new System.Drawing.Size(141, 19);
|
||||
chkGameQuickAccess.TabIndex = 44;
|
||||
chkGameQuickAccess.Text = "Show in Quick Access";
|
||||
chkGameQuickAccess.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// btnGameSettings
|
||||
//
|
||||
btnGameSettings.Anchor = System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right;
|
||||
btnGameSettings.ContextMenuStrip = mnuGameActions;
|
||||
btnGameSettings.Location = new System.Drawing.Point(1018, 351);
|
||||
btnGameSettings.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
btnGameSettings.Name = "btnGameSettings";
|
||||
btnGameSettings.Size = new System.Drawing.Size(88, 27);
|
||||
btnGameSettings.TabIndex = 43;
|
||||
btnGameSettings.Text = "Settings...";
|
||||
btnGameSettings.UseVisualStyleBackColor = true;
|
||||
btnGameSettings.Click += btnGameActions_Click;
|
||||
//
|
||||
// mnuGameActions
|
||||
//
|
||||
mnuGameActions.ImageScalingSize = new System.Drawing.Size(20, 20);
|
||||
mnuGameActions.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { mnuGameNvInspector, miGameSetQuickAccessShortcut });
|
||||
mnuGameActions.Name = "mnuLgButtons";
|
||||
mnuGameActions.Size = new System.Drawing.Size(202, 48);
|
||||
mnuGameActions.Opening += mnuGameActions_Opening;
|
||||
//
|
||||
// mnuGameNvInspector
|
||||
//
|
||||
mnuGameNvInspector.Name = "mnuGameNvInspector";
|
||||
mnuGameNvInspector.Size = new System.Drawing.Size(201, 22);
|
||||
mnuGameNvInspector.Text = "NVIDIA Profile Inspector";
|
||||
mnuGameNvInspector.Click += mnuGameNvInspector_Click;
|
||||
//
|
||||
// miGameSetQuickAccessShortcut
|
||||
//
|
||||
miGameSetQuickAccessShortcut.Name = "miGameSetQuickAccessShortcut";
|
||||
miGameSetQuickAccessShortcut.Size = new System.Drawing.Size(201, 22);
|
||||
miGameSetQuickAccessShortcut.Text = "Settings...";
|
||||
miGameSetQuickAccessShortcut.Click += miGameSetQuickAccessShortcut_Click;
|
||||
//
|
||||
// chkGameRunAsAdmin
|
||||
//
|
||||
chkGameRunAsAdmin.Anchor = System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left;
|
||||
chkGameRunAsAdmin.AutoSize = true;
|
||||
chkGameRunAsAdmin.Enabled = false;
|
||||
chkGameRunAsAdmin.Location = new System.Drawing.Point(881, 415);
|
||||
chkGameRunAsAdmin.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
chkGameRunAsAdmin.Name = "chkGameRunAsAdmin";
|
||||
chkGameRunAsAdmin.Size = new System.Drawing.Size(135, 19);
|
||||
chkGameRunAsAdmin.TabIndex = 42;
|
||||
chkGameRunAsAdmin.Text = "Run as administrator";
|
||||
chkGameRunAsAdmin.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// lblGameParameters
|
||||
//
|
||||
lblGameParameters.Anchor = System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left;
|
||||
lblGameParameters.AutoSize = true;
|
||||
lblGameParameters.Location = new System.Drawing.Point(8, 445);
|
||||
lblGameParameters.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
|
||||
lblGameParameters.Name = "lblGameParameters";
|
||||
lblGameParameters.Size = new System.Drawing.Size(69, 15);
|
||||
lblGameParameters.TabIndex = 41;
|
||||
lblGameParameters.Text = "Parameters:";
|
||||
//
|
||||
// edtGameParameters
|
||||
//
|
||||
edtGameParameters.Anchor = System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left;
|
||||
edtGameParameters.Enabled = false;
|
||||
edtGameParameters.Location = new System.Drawing.Point(154, 442);
|
||||
edtGameParameters.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
edtGameParameters.Name = "edtGameParameters";
|
||||
edtGameParameters.Size = new System.Drawing.Size(623, 23);
|
||||
edtGameParameters.TabIndex = 40;
|
||||
//
|
||||
// btnGameBrowse
|
||||
//
|
||||
btnGameBrowse.Anchor = System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left;
|
||||
btnGameBrowse.Enabled = false;
|
||||
btnGameBrowse.Location = new System.Drawing.Point(785, 410);
|
||||
btnGameBrowse.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
btnGameBrowse.Name = "btnGameBrowse";
|
||||
btnGameBrowse.Size = new System.Drawing.Size(88, 27);
|
||||
btnGameBrowse.TabIndex = 39;
|
||||
btnGameBrowse.Text = "Browse...";
|
||||
btnGameBrowse.UseVisualStyleBackColor = true;
|
||||
btnGameBrowse.Click += btnGameBrowse_Click;
|
||||
//
|
||||
// lblGameFilePath
|
||||
//
|
||||
lblGameFilePath.Anchor = System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left;
|
||||
lblGameFilePath.AutoSize = true;
|
||||
lblGameFilePath.Location = new System.Drawing.Point(8, 417);
|
||||
lblGameFilePath.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
|
||||
lblGameFilePath.Name = "lblGameFilePath";
|
||||
lblGameFilePath.Size = new System.Drawing.Size(51, 15);
|
||||
lblGameFilePath.TabIndex = 38;
|
||||
lblGameFilePath.Text = "File/URI:";
|
||||
//
|
||||
// edtGamePath
|
||||
//
|
||||
edtGamePath.Anchor = System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left;
|
||||
edtGamePath.Enabled = false;
|
||||
edtGamePath.Location = new System.Drawing.Point(154, 413);
|
||||
edtGamePath.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
edtGamePath.Name = "edtGamePath";
|
||||
edtGamePath.Size = new System.Drawing.Size(623, 23);
|
||||
edtGamePath.TabIndex = 37;
|
||||
//
|
||||
// edtGamePrelaunchSteps
|
||||
//
|
||||
edtGamePrelaunchSteps.Anchor = System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left;
|
||||
edtGamePrelaunchSteps.Enabled = false;
|
||||
edtGamePrelaunchSteps.Location = new System.Drawing.Point(154, 471);
|
||||
edtGamePrelaunchSteps.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
edtGamePrelaunchSteps.Multiline = true;
|
||||
edtGamePrelaunchSteps.Name = "edtGamePrelaunchSteps";
|
||||
edtGamePrelaunchSteps.Size = new System.Drawing.Size(623, 48);
|
||||
edtGamePrelaunchSteps.TabIndex = 35;
|
||||
edtGamePrelaunchSteps.Leave += edtGamePrelaunchSteps_Leave;
|
||||
//
|
||||
// btnGameAddStep
|
||||
//
|
||||
btnGameAddStep.Anchor = System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left;
|
||||
btnGameAddStep.ContextMenuStrip = mnuGameAddStep;
|
||||
btnGameAddStep.Enabled = false;
|
||||
btnGameAddStep.Location = new System.Drawing.Point(785, 470);
|
||||
btnGameAddStep.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
btnGameAddStep.Name = "btnGameAddStep";
|
||||
btnGameAddStep.Size = new System.Drawing.Size(88, 27);
|
||||
btnGameAddStep.TabIndex = 36;
|
||||
btnGameAddStep.Text = "Add step";
|
||||
btnGameAddStep.UseVisualStyleBackColor = true;
|
||||
btnGameAddStep.Click += btnGameAddStep_Click;
|
||||
//
|
||||
// mnuGameAddStep
|
||||
//
|
||||
mnuGameAddStep.ImageScalingSize = new System.Drawing.Size(20, 20);
|
||||
mnuGameAddStep.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { mnuGameNvidiaPresets, mnuGameAmdPresets, mnuGameLgPresets, mnuGameSamsungPresets, mnuGameStartProgram });
|
||||
mnuGameAddStep.Name = "mnuLgButtons";
|
||||
mnuGameAddStep.Size = new System.Drawing.Size(164, 114);
|
||||
mnuGameAddStep.Opening += mnuGameAddStep_Opening;
|
||||
//
|
||||
// mnuGameNvidiaPresets
|
||||
//
|
||||
mnuGameNvidiaPresets.Name = "mnuGameNvidiaPresets";
|
||||
mnuGameNvidiaPresets.Size = new System.Drawing.Size(163, 22);
|
||||
mnuGameNvidiaPresets.Text = "NVIDIA presets";
|
||||
//
|
||||
// mnuGameAmdPresets
|
||||
//
|
||||
mnuGameAmdPresets.Name = "mnuGameAmdPresets";
|
||||
mnuGameAmdPresets.Size = new System.Drawing.Size(163, 22);
|
||||
mnuGameAmdPresets.Text = "AMD presets";
|
||||
//
|
||||
// mnuGameLgPresets
|
||||
//
|
||||
mnuGameLgPresets.Name = "mnuGameLgPresets";
|
||||
mnuGameLgPresets.Size = new System.Drawing.Size(163, 22);
|
||||
mnuGameLgPresets.Text = "LG presets";
|
||||
//
|
||||
// mnuGameSamsungPresets
|
||||
//
|
||||
mnuGameSamsungPresets.Name = "mnuGameSamsungPresets";
|
||||
mnuGameSamsungPresets.Size = new System.Drawing.Size(163, 22);
|
||||
mnuGameSamsungPresets.Text = "Samsung presets";
|
||||
//
|
||||
// mnuGameStartProgram
|
||||
//
|
||||
mnuGameStartProgram.Name = "mnuGameStartProgram";
|
||||
mnuGameStartProgram.Size = new System.Drawing.Size(163, 22);
|
||||
mnuGameStartProgram.Text = "Start Program";
|
||||
mnuGameStartProgram.Click += mnuGameStartProgram_Click;
|
||||
//
|
||||
// label4
|
||||
//
|
||||
label4.Anchor = System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left;
|
||||
label4.AutoSize = true;
|
||||
label4.Location = new System.Drawing.Point(8, 388);
|
||||
label4.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
|
||||
label4.Name = "label4";
|
||||
label4.Size = new System.Drawing.Size(42, 15);
|
||||
label4.TabIndex = 33;
|
||||
label4.Text = "Name:";
|
||||
//
|
||||
// edtGameName
|
||||
//
|
||||
edtGameName.Anchor = System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left;
|
||||
edtGameName.Enabled = false;
|
||||
edtGameName.Location = new System.Drawing.Point(154, 384);
|
||||
edtGameName.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
edtGameName.Name = "edtGameName";
|
||||
edtGameName.Size = new System.Drawing.Size(191, 23);
|
||||
edtGameName.TabIndex = 32;
|
||||
//
|
||||
// btnGameDelete
|
||||
//
|
||||
btnGameDelete.Anchor = System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left;
|
||||
btnGameDelete.Enabled = false;
|
||||
btnGameDelete.Location = new System.Drawing.Point(291, 351);
|
||||
btnGameDelete.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
btnGameDelete.Name = "btnGameDelete";
|
||||
btnGameDelete.Size = new System.Drawing.Size(88, 27);
|
||||
btnGameDelete.TabIndex = 30;
|
||||
btnGameDelete.Text = "Delete";
|
||||
btnGameDelete.UseVisualStyleBackColor = true;
|
||||
btnGameDelete.Click += btnGameDelete_Click;
|
||||
//
|
||||
// btnGameClone
|
||||
//
|
||||
btnGameClone.Anchor = System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left;
|
||||
btnGameClone.Enabled = false;
|
||||
btnGameClone.Location = new System.Drawing.Point(103, 351);
|
||||
btnGameClone.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
btnGameClone.Name = "btnGameClone";
|
||||
btnGameClone.Size = new System.Drawing.Size(88, 27);
|
||||
btnGameClone.TabIndex = 29;
|
||||
btnGameClone.Text = "Clone";
|
||||
btnGameClone.UseVisualStyleBackColor = true;
|
||||
btnGameClone.Click += btnGameClone_Click;
|
||||
//
|
||||
// btnGameSave
|
||||
//
|
||||
btnGameSave.Anchor = System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left;
|
||||
btnGameSave.Enabled = false;
|
||||
btnGameSave.Location = new System.Drawing.Point(387, 351);
|
||||
btnGameSave.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
btnGameSave.Name = "btnGameSave";
|
||||
btnGameSave.Size = new System.Drawing.Size(88, 27);
|
||||
btnGameSave.TabIndex = 28;
|
||||
btnGameSave.Text = "Save";
|
||||
btnGameSave.UseVisualStyleBackColor = true;
|
||||
btnGameSave.Click += btnGameSave_Click;
|
||||
//
|
||||
// btnGameAdd
|
||||
//
|
||||
btnGameAdd.Anchor = System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left;
|
||||
btnGameAdd.Location = new System.Drawing.Point(199, 351);
|
||||
btnGameAdd.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
btnGameAdd.Name = "btnGameAdd";
|
||||
btnGameAdd.Size = new System.Drawing.Size(88, 27);
|
||||
btnGameAdd.TabIndex = 25;
|
||||
btnGameAdd.Text = "Add";
|
||||
btnGameAdd.UseVisualStyleBackColor = true;
|
||||
btnGameAdd.Click += btnGameAdd_Click;
|
||||
//
|
||||
// btnGameLaunch
|
||||
//
|
||||
btnGameLaunch.Anchor = System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left;
|
||||
btnGameLaunch.Enabled = false;
|
||||
btnGameLaunch.Location = new System.Drawing.Point(8, 351);
|
||||
btnGameLaunch.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
btnGameLaunch.Name = "btnGameLaunch";
|
||||
btnGameLaunch.Size = new System.Drawing.Size(88, 27);
|
||||
btnGameLaunch.TabIndex = 24;
|
||||
btnGameLaunch.Text = "Launch";
|
||||
btnGameLaunch.UseVisualStyleBackColor = true;
|
||||
btnGameLaunch.Click += btnGameLaunch_Click;
|
||||
//
|
||||
// lvGamePresets
|
||||
//
|
||||
lvGamePresets.AllowDrop = true;
|
||||
lvGamePresets.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right;
|
||||
lvGamePresets.CheckBoxes = true;
|
||||
lvGamePresets.ContextMenuStrip = mnuGameOptions;
|
||||
lvGamePresets.FullRowSelect = true;
|
||||
lvGamePresets.Location = new System.Drawing.Point(8, 8);
|
||||
lvGamePresets.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
lvGamePresets.MultiSelect = false;
|
||||
lvGamePresets.Name = "lvGamePresets";
|
||||
lvGamePresets.ShowItemToolTips = true;
|
||||
lvGamePresets.Size = new System.Drawing.Size(1098, 335);
|
||||
lvGamePresets.TabIndex = 23;
|
||||
lvGamePresets.UseCompatibleStateImageBehavior = false;
|
||||
lvGamePresets.View = System.Windows.Forms.View.Details;
|
||||
lvGamePresets.ColumnClick += lvLgPresets_ColumnClick;
|
||||
lvGamePresets.ItemChecked += lvGamePresets_ItemChecked;
|
||||
lvGamePresets.SelectedIndexChanged += lvGamePresets_SelectedIndexChanged;
|
||||
lvGamePresets.DragDrop += lvGamePresets_DragDrop;
|
||||
lvGamePresets.DragEnter += lvGamePresets_DragEnter;
|
||||
lvGamePresets.DoubleClick += lvGamePresets_DoubleClick;
|
||||
//
|
||||
// miGameOptionsAutoApplySettings
|
||||
//
|
||||
miGameOptionsAutoApplySettings.Name = "miGameOptionsAutoApplySettings";
|
||||
miGameOptionsAutoApplySettings.Size = new System.Drawing.Size(201, 22);
|
||||
miGameOptionsAutoApplySettings.Text = "Auto apply settings...";
|
||||
miGameOptionsAutoApplySettings.Click += miGameOptionsAutoApplySettings_Click;
|
||||
//
|
||||
// GamePanel
|
||||
//
|
||||
AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
|
||||
AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
Controls.Add(cbxGameStepType);
|
||||
Controls.Add(btnGameOptions);
|
||||
Controls.Add(chkGameQuickAccess);
|
||||
Controls.Add(btnGameSettings);
|
||||
Controls.Add(chkGameRunAsAdmin);
|
||||
Controls.Add(lblGameParameters);
|
||||
Controls.Add(edtGameParameters);
|
||||
Controls.Add(btnGameBrowse);
|
||||
Controls.Add(lblGameFilePath);
|
||||
Controls.Add(edtGamePath);
|
||||
Controls.Add(edtGamePrelaunchSteps);
|
||||
Controls.Add(btnGameAddStep);
|
||||
Controls.Add(label4);
|
||||
Controls.Add(edtGameName);
|
||||
Controls.Add(btnGameDelete);
|
||||
Controls.Add(btnGameClone);
|
||||
Controls.Add(btnGameSave);
|
||||
Controls.Add(btnGameAdd);
|
||||
Controls.Add(btnGameLaunch);
|
||||
Controls.Add(lvGamePresets);
|
||||
Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
Name = "GamePanel";
|
||||
Size = new System.Drawing.Size(1114, 539);
|
||||
mnuGameOptions.ResumeLayout(false);
|
||||
mnuGameActions.ResumeLayout(false);
|
||||
mnuGameAddStep.ResumeLayout(false);
|
||||
ResumeLayout(false);
|
||||
PerformLayout();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.Label lblGameParameters;
|
||||
private System.Windows.Forms.TextBox edtGameParameters;
|
||||
private System.Windows.Forms.Button btnGameBrowse;
|
||||
private System.Windows.Forms.Label lblGameFilePath;
|
||||
private System.Windows.Forms.TextBox edtGamePath;
|
||||
private System.Windows.Forms.TextBox edtGamePrelaunchSteps;
|
||||
private System.Windows.Forms.Button btnGameAddStep;
|
||||
private System.Windows.Forms.Label label4;
|
||||
private System.Windows.Forms.TextBox edtGameName;
|
||||
private System.Windows.Forms.Button btnGameDelete;
|
||||
private System.Windows.Forms.Button btnGameClone;
|
||||
private System.Windows.Forms.Button btnGameSave;
|
||||
private System.Windows.Forms.Button btnGameAdd;
|
||||
private System.Windows.Forms.Button btnGameLaunch;
|
||||
private System.Windows.Forms.ListView lvGamePresets;
|
||||
private System.Windows.Forms.ContextMenuStrip mnuGameAddStep;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuGameNvidiaPresets;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuGameAmdPresets;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuGameLgPresets;
|
||||
private System.Windows.Forms.CheckBox chkGameRunAsAdmin;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuGameStartProgram;
|
||||
private System.Windows.Forms.Button btnGameSettings;
|
||||
private System.Windows.Forms.ContextMenuStrip mnuGameActions;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuGameNvInspector;
|
||||
private System.Windows.Forms.CheckBox chkGameQuickAccess;
|
||||
private System.Windows.Forms.ToolStripMenuItem miGameSetQuickAccessShortcut;
|
||||
private System.Windows.Forms.Button btnGameOptions;
|
||||
private System.Windows.Forms.ContextMenuStrip mnuGameOptions;
|
||||
private System.Windows.Forms.ToolStripMenuItem miGameProcessorAffinity;
|
||||
private System.Windows.Forms.ToolStripMenuItem miGameProcessPriority;
|
||||
private System.Windows.Forms.ComboBox cbxGameStepType;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuGameSamsungPresets;
|
||||
private System.Windows.Forms.ToolStripMenuItem miPresetNVIDIAProfileInspector;
|
||||
private System.Windows.Forms.ToolStripMenuItem miGameOptionsAutoApplySettings;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,569 @@
|
||||
using ColorControl.Services.AMD;
|
||||
using ColorControl.Services.Common;
|
||||
using ColorControl.Services.LG;
|
||||
using ColorControl.Services.NVIDIA;
|
||||
using ColorControl.Services.Samsung;
|
||||
using ColorControl.Shared.Common;
|
||||
using ColorControl.Shared.Contracts;
|
||||
using ColorControl.Shared.Forms;
|
||||
using ColorControl.Shared.Native;
|
||||
using nspector;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace ColorControl.Services.GameLauncher
|
||||
{
|
||||
public partial class GamePanel : UserControl, IModulePanel
|
||||
{
|
||||
public static readonly int SHORTCUTID_GAMEQA = -203;
|
||||
|
||||
//private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
|
||||
|
||||
private Config _config;
|
||||
private GameService _gameService;
|
||||
private IntPtr _mainHandle;
|
||||
private NotifyIcon _trayIcon;
|
||||
private NvService _nvService;
|
||||
private AmdService _amdService;
|
||||
private LgService _lgService;
|
||||
private SamsungService _samsungService;
|
||||
|
||||
internal GamePanel(GameService gameService, NvService nvService, AmdService amdService, LgService lgService, SamsungService samsungService, NotifyIcon trayIcon, IntPtr handle)
|
||||
{
|
||||
_gameService = gameService;
|
||||
_trayIcon = trayIcon;
|
||||
_mainHandle = handle;
|
||||
_nvService = nvService;
|
||||
_amdService = amdService;
|
||||
_lgService = lgService;
|
||||
_samsungService = samsungService;
|
||||
_config = Shared.Common.GlobalContext.CurrentContext.Config;
|
||||
|
||||
InitializeComponent();
|
||||
|
||||
FillGamePresets();
|
||||
|
||||
FormUtils.InitSortState(lvGamePresets, _config.GamePresetsSortState);
|
||||
}
|
||||
|
||||
private void FillGamePresets()
|
||||
{
|
||||
FormUtils.InitListView(lvGamePresets, GamePreset.GetColumnNames());
|
||||
|
||||
foreach (var preset in _gameService.GetPresets())
|
||||
{
|
||||
AddOrUpdateItemGame(preset);
|
||||
KeyboardShortcutManager.RegisterShortcut(preset.id, preset.shortcut);
|
||||
}
|
||||
}
|
||||
|
||||
private void AddOrUpdateItemGame(GamePreset preset = null)
|
||||
{
|
||||
ServiceFormUtils.AddOrUpdateListItem(lvGamePresets, _gameService.GetPresets(), _config, preset);
|
||||
}
|
||||
|
||||
internal void Save()
|
||||
{
|
||||
FormUtils.SaveSortState(lvGamePresets.ListViewItemSorter, _config.GamePresetsSortState);
|
||||
}
|
||||
|
||||
private void edtShortcut_KeyDown(object sender, KeyEventArgs e)
|
||||
{
|
||||
((TextBox)sender).Text = KeyboardShortcutManager.FormatKeyboardShortcut(e);
|
||||
}
|
||||
|
||||
private void edtShortcut_KeyUp(object sender, KeyEventArgs e)
|
||||
{
|
||||
KeyboardShortcutManager.HandleKeyboardShortcutUp(e);
|
||||
}
|
||||
|
||||
private GamePreset GetSelectedGamePreset()
|
||||
{
|
||||
if (lvGamePresets.SelectedItems.Count > 0)
|
||||
{
|
||||
var item = lvGamePresets.SelectedItems[0];
|
||||
return (GamePreset)item.Tag;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public void UpdateInfo()
|
||||
{
|
||||
if (cbxGameStepType.Items.Count == 0)
|
||||
{
|
||||
cbxGameStepType.Items.AddRange(Utils.GetDescriptions<GameStepType>().ToArray());
|
||||
cbxGameStepType.SelectedIndex = 0;
|
||||
}
|
||||
}
|
||||
|
||||
private async Task ApplySelectedGamePreset()
|
||||
{
|
||||
var preset = GetSelectedGamePreset();
|
||||
await ApplyGamePreset(preset);
|
||||
}
|
||||
|
||||
internal async Task<bool> ApplyGamePreset(GamePreset preset)
|
||||
{
|
||||
if (preset == null || _gameService == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
try
|
||||
{
|
||||
var result = await _gameService.ApplyPreset(preset, Program.AppContext);
|
||||
if (!result)
|
||||
{
|
||||
throw new Exception("Error while applying Game-preset. At least one setting could not be applied. Check the log for details.");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
MessageForms.ErrorOk($"Error applying Game-preset ({e.TargetSite.Name}): {e.Message}");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private void lvGamePresets_SelectedIndexChanged(object sender, EventArgs _)
|
||||
{
|
||||
var preset = GetSelectedGamePreset();
|
||||
var enabled = preset != null;
|
||||
|
||||
FormUtils.EnableControls(this, enabled, new List<Control> { lvGamePresets, btnGameAdd, btnGameSettings });
|
||||
|
||||
if (preset != null)
|
||||
{
|
||||
edtGameName.Text = preset.name;
|
||||
edtGamePath.Text = preset.Path;
|
||||
edtGameParameters.Text = preset.Parameters;
|
||||
chkGameRunAsAdmin.Checked = preset.RunAsAdministrator;
|
||||
chkGameQuickAccess.Checked = preset.ShowInQuickAccess;
|
||||
ShowGameSteps();
|
||||
}
|
||||
else
|
||||
{
|
||||
edtGameName.Text = string.Empty;
|
||||
edtGamePath.Text = string.Empty;
|
||||
edtGameParameters.Text = string.Empty;
|
||||
chkGameRunAsAdmin.Checked = false;
|
||||
chkGameQuickAccess.Checked = false;
|
||||
edtGamePrelaunchSteps.Text = string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
private async void lvGamePresets_DoubleClick(object sender, EventArgs e)
|
||||
{
|
||||
await ApplySelectedGamePreset();
|
||||
}
|
||||
|
||||
private async void btnGameLaunch_Click(object sender, EventArgs e)
|
||||
{
|
||||
await ApplySelectedGamePreset();
|
||||
}
|
||||
|
||||
private void btnGameClone_Click(object sender, EventArgs e)
|
||||
{
|
||||
var preset = GetSelectedGamePreset();
|
||||
|
||||
var newPreset = preset.Clone();
|
||||
|
||||
AddOrUpdateItemGame(newPreset);
|
||||
}
|
||||
|
||||
private void btnGameAdd_Click(object sender, EventArgs e)
|
||||
{
|
||||
var file = Utils.SelectFile();
|
||||
|
||||
AddGamePreset(file);
|
||||
}
|
||||
|
||||
private void AddGamePreset(FileInfo file)
|
||||
{
|
||||
var preset = _gameService.CreateNewPreset();
|
||||
|
||||
if (file != null)
|
||||
{
|
||||
var versionInfo = FileVersionInfo.GetVersionInfo(file.FullName);
|
||||
|
||||
preset.Path = file.FullName;
|
||||
|
||||
var fileName = Path.GetFileNameWithoutExtension(preset.Path);
|
||||
|
||||
preset.name = !string.IsNullOrEmpty(versionInfo.FileDescription) ? versionInfo.FileDescription :
|
||||
!string.IsNullOrEmpty(versionInfo.ProductName) ? versionInfo.ProductName : fileName;
|
||||
}
|
||||
|
||||
AddOrUpdateItemGame(preset);
|
||||
}
|
||||
|
||||
private void btnGameSave_Click(object sender, EventArgs e)
|
||||
{
|
||||
SaveGamePreset();
|
||||
}
|
||||
|
||||
private void SaveGamePreset()
|
||||
{
|
||||
var shortcut = string.Empty;
|
||||
if (!KeyboardShortcutManager.ValidateShortcut(shortcut))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var preset = GetSelectedGamePreset();
|
||||
|
||||
var name = edtGameName.Text.Trim();
|
||||
|
||||
if (name.Length == 0 || _gameService.GetPresets().Any(x => x.id != preset.id && x.name.Equals(name, StringComparison.OrdinalIgnoreCase)))
|
||||
{
|
||||
MessageForms.WarningOk("The name can not be empty and must be unique.");
|
||||
return;
|
||||
}
|
||||
|
||||
preset.name = name;
|
||||
preset.Path = edtGamePath.Text;
|
||||
preset.Parameters = edtGameParameters.Text;
|
||||
preset.RunAsAdministrator = chkGameRunAsAdmin.Checked;
|
||||
preset.ShowInQuickAccess = chkGameQuickAccess.Checked;
|
||||
|
||||
preset.shortcut = shortcut;
|
||||
|
||||
var text = edtGamePrelaunchSteps.Text;
|
||||
|
||||
var stepsList = (GameStepType)cbxGameStepType.SelectedIndex switch
|
||||
{
|
||||
GameStepType.PreLaunch => preset.PreLaunchSteps,
|
||||
GameStepType.PostLaunch => preset.PostLaunchSteps,
|
||||
GameStepType.Finalize => preset.FinalizeSteps,
|
||||
_ => throw new InvalidOperationException("Invalid game step type")
|
||||
};
|
||||
|
||||
Utils.ParseWords(stepsList, text);
|
||||
|
||||
AddOrUpdateItemGame();
|
||||
|
||||
KeyboardShortcutManager.RegisterShortcut(preset.id, preset.shortcut);
|
||||
}
|
||||
|
||||
private void btnGameBrowse_Click(object sender, EventArgs e)
|
||||
{
|
||||
var file = Utils.SelectFile();
|
||||
|
||||
if (file == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var preset = GetSelectedGamePreset();
|
||||
|
||||
preset.Path = file.FullName;
|
||||
|
||||
edtGamePath.Text = preset.Path;
|
||||
|
||||
if (string.IsNullOrEmpty(preset.name) || preset.name.StartsWith("New preset", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
var fileName = Path.GetFileNameWithoutExtension(preset.Path);
|
||||
|
||||
edtGameName.Text = fileName;
|
||||
preset.name = fileName;
|
||||
}
|
||||
|
||||
AddOrUpdateItemGame();
|
||||
}
|
||||
|
||||
private void btnGameDelete_Click(object sender, EventArgs e)
|
||||
{
|
||||
var preset = GetSelectedGamePreset();
|
||||
|
||||
if (preset == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(preset.shortcut))
|
||||
{
|
||||
WinApi.UnregisterHotKey(_mainHandle, preset.id);
|
||||
}
|
||||
_gameService.GetPresets().Remove(preset);
|
||||
|
||||
var item = lvGamePresets.SelectedItems[0];
|
||||
lvGamePresets.Items.Remove(item);
|
||||
}
|
||||
|
||||
private void mnuGameAddStep_Opening(object sender, CancelEventArgs e)
|
||||
{
|
||||
ServiceFormUtils.BuildServicePresetsMenu(mnuGameNvidiaPresets, _nvService, "NVIDIA", miGameAddPreset_Click);
|
||||
ServiceFormUtils.BuildServicePresetsMenu(mnuGameAmdPresets, _amdService, "AMD", miGameAddPreset_Click);
|
||||
ServiceFormUtils.BuildServicePresetsMenu(mnuGameLgPresets, _lgService, "LG", miGameAddPreset_Click);
|
||||
ServiceFormUtils.BuildServicePresetsMenu(mnuGameSamsungPresets, _samsungService, "Samsung", miGameAddPreset_Click);
|
||||
}
|
||||
|
||||
private void miGameAddPreset_Click(object sender, EventArgs e)
|
||||
{
|
||||
var item = sender as ToolStripItem;
|
||||
var preset = item.Tag as PresetBase;
|
||||
|
||||
var text = $"{preset.GetType().Name}({preset.name})";
|
||||
|
||||
FormUtils.AddStepToTextBox(edtGamePrelaunchSteps, text);
|
||||
}
|
||||
|
||||
private void btnGameAddStep_Click(object sender, EventArgs e)
|
||||
{
|
||||
mnuGameAddStep.ShowCustom(btnGameAddStep);
|
||||
}
|
||||
|
||||
private void mnuGameStartProgram_Click(object sender, EventArgs e)
|
||||
{
|
||||
var file = Utils.SelectFile();
|
||||
|
||||
if (file != null)
|
||||
{
|
||||
FormUtils.AddStepToTextBox(edtGamePrelaunchSteps, $"StartProgram({file.FullName})");
|
||||
}
|
||||
}
|
||||
|
||||
private void lvGamePresets_DragDrop(object sender, DragEventArgs e)
|
||||
{
|
||||
if (e.Data.GetDataPresent(DataFormats.FileDrop))
|
||||
{
|
||||
var files = (string[])e.Data.GetData(DataFormats.FileDrop);
|
||||
var file = new FileInfo(files.First());
|
||||
|
||||
AddGamePreset(file);
|
||||
}
|
||||
}
|
||||
|
||||
private void lvGamePresets_DragEnter(object sender, DragEventArgs e)
|
||||
{
|
||||
e.Effect = DragDropEffects.All;
|
||||
}
|
||||
|
||||
private void btnGameActions_Click(object sender, EventArgs e)
|
||||
{
|
||||
mnuGameActions.ShowCustom(btnGameSettings);
|
||||
}
|
||||
|
||||
private void mnuGameNvInspector_Click(object sender, EventArgs e)
|
||||
{
|
||||
var form = new frmDrvSettings();
|
||||
form.Show();
|
||||
}
|
||||
|
||||
private void miGameSetQuickAccessShortcut_Click(object sender, EventArgs e)
|
||||
{
|
||||
EditGameSettings();
|
||||
}
|
||||
|
||||
private void EditGameSettings()
|
||||
{
|
||||
var quickAccessField = new FieldDefinition
|
||||
{
|
||||
Label = "Quick Access shortcut",
|
||||
FieldType = FieldType.Shortcut,
|
||||
Value = _config.GameQuickAccessShortcut
|
||||
};
|
||||
|
||||
var applyExternallyLaunched = new FieldDefinition
|
||||
{
|
||||
Label = "Apply presets when launching games externally",
|
||||
SubLabel = "This will monitor processes and automatically apply the preset whenever a known game is launched",
|
||||
FieldType = FieldType.CheckBox,
|
||||
Value = _gameService.Config.ApplyExternallyLaunched
|
||||
};
|
||||
|
||||
var values = MessageForms.ShowDialog("Game launcher settings", new[] {
|
||||
quickAccessField,
|
||||
applyExternallyLaunched
|
||||
});
|
||||
if (!values.Any())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var shortcut = (string)quickAccessField.Value;
|
||||
|
||||
_config.GameQuickAccessShortcut = shortcut;
|
||||
|
||||
KeyboardShortcutManager.RegisterShortcut(SHORTCUTID_GAMEQA, _config.GameQuickAccessShortcut);
|
||||
|
||||
_gameService.Config.ApplyExternallyLaunched = applyExternallyLaunched.ValueAsBool;
|
||||
|
||||
UpdateInfo();
|
||||
}
|
||||
|
||||
private void mnuGameActions_Opening(object sender, CancelEventArgs e)
|
||||
{
|
||||
mnuGameNvInspector.Visible = _nvService != null;
|
||||
}
|
||||
|
||||
private void lvGamePresets_ItemChecked(object sender, ItemCheckedEventArgs e)
|
||||
{
|
||||
ServiceFormUtils.ListViewItemChecked<GamePreset>(lvGamePresets, e);
|
||||
}
|
||||
|
||||
private void btnGameProcessAffinity_Click(object sender, EventArgs e)
|
||||
{
|
||||
var preset = GetSelectedGamePreset();
|
||||
|
||||
if (preset == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var numberOfProcessors = Environment.ProcessorCount;
|
||||
|
||||
var options = Enumerable.Range(0, numberOfProcessors).Select(i => $"CPU #{i}");
|
||||
|
||||
var values = MessageForms.ShowDialog("Set processor affinity", new[] {
|
||||
new FieldDefinition
|
||||
{
|
||||
Label = "Set desired processors which are allowed to run program",
|
||||
FieldType = FieldType.Flags,
|
||||
Values = options,
|
||||
Value = preset.ProcessAffinityMask
|
||||
}
|
||||
});
|
||||
|
||||
if (!values.Any())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var value = values.First().Value;
|
||||
|
||||
preset.ProcessAffinityMask = (uint)(int)value;
|
||||
}
|
||||
|
||||
private void btnGameOptions_Click(object sender, EventArgs e)
|
||||
{
|
||||
mnuGameOptions.ShowCustom(btnGameOptions);
|
||||
}
|
||||
|
||||
private void miGameProcessPriority_Click(object sender, EventArgs e)
|
||||
{
|
||||
var preset = GetSelectedGamePreset();
|
||||
|
||||
if (preset == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var dropDownValues = Utils.GetDescriptions<GamePriorityClass>();
|
||||
|
||||
var values = MessageForms.ShowDialog("Set process priority", new[] {
|
||||
new FieldDefinition
|
||||
{
|
||||
Label = "Set desired process priority",
|
||||
FieldType = FieldType.DropDown,
|
||||
Values = dropDownValues,
|
||||
Value = preset.ProcessPriorityClass > 0 ? ((GamePriorityClass)preset.ProcessPriorityClass).GetDescription() : GamePriorityClass.Normal.GetDescription()
|
||||
}
|
||||
});
|
||||
|
||||
if (!values.Any())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var value = values.First().Value.ToString();
|
||||
var enumValue = Utils.GetEnumValueByDescription<GamePriorityClass>(value);
|
||||
|
||||
preset.ProcessPriorityClass = (uint)(int)enumValue;
|
||||
}
|
||||
|
||||
private void cbxGameStepType_SelectedIndexChanged(object sender, EventArgs e)
|
||||
{
|
||||
ShowGameSteps();
|
||||
}
|
||||
|
||||
private void ShowGameSteps()
|
||||
{
|
||||
var preset = GetSelectedGamePreset();
|
||||
|
||||
if (preset == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
switch ((GameStepType)cbxGameStepType.SelectedIndex)
|
||||
{
|
||||
case GameStepType.PreLaunch:
|
||||
edtGamePrelaunchSteps.Text = string.Join(", ", preset.PreLaunchSteps);
|
||||
break;
|
||||
case GameStepType.PostLaunch:
|
||||
edtGamePrelaunchSteps.Text = string.Join(", ", preset.PostLaunchSteps);
|
||||
break;
|
||||
case GameStepType.Finalize:
|
||||
edtGamePrelaunchSteps.Text = string.Join(", ", preset.FinalizeSteps);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void edtGamePrelaunchSteps_Leave(object sender, EventArgs e)
|
||||
{
|
||||
SaveGamePreset();
|
||||
}
|
||||
|
||||
private void lvLgPresets_ColumnClick(object sender, ColumnClickEventArgs e)
|
||||
{
|
||||
FormUtils.ListViewSort(sender, e);
|
||||
}
|
||||
|
||||
private void miPresetNVIDIAProfileInspector_Click(object sender, EventArgs e)
|
||||
{
|
||||
var form = new frmDrvSettings();
|
||||
form.Show();
|
||||
|
||||
var preset = GetSelectedGamePreset();
|
||||
|
||||
var executable = Path.GetFileName(preset.Path);
|
||||
|
||||
form.SetProfileByExecutable(executable);
|
||||
}
|
||||
|
||||
private void miGameOptionsAutoApplySettings_Click(object sender, EventArgs e)
|
||||
{
|
||||
var preset = GetSelectedGamePreset();
|
||||
|
||||
var allowAutoApplyField = new FieldDefinition
|
||||
{
|
||||
Label = "Allow this preset to be automatically executed when the process starts",
|
||||
FieldType = FieldType.CheckBox,
|
||||
Value = preset.AutoSettings.AllowAutoApply
|
||||
};
|
||||
|
||||
var processActions = new[] { ProcessAutoAction.None, ProcessAutoAction.Suspend }.Select(t => Utils.GetDescription(t));
|
||||
|
||||
var processActionField = new FieldDefinition
|
||||
{
|
||||
Label = "Optional action to perform directly after the process starts",
|
||||
SubLabel = "Temporarily suspending the process may help when enabling/disabling HDR or other settings",
|
||||
FieldType = FieldType.DropDown,
|
||||
Values = processActions,
|
||||
Value = preset.AutoSettings.ProcessAutoAction
|
||||
};
|
||||
|
||||
var values = MessageForms.ShowDialog("Auto apply settings", new[] {
|
||||
allowAutoApplyField,
|
||||
processActionField
|
||||
});
|
||||
if (!values.Any())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
preset.AutoSettings.AllowAutoApply = allowAutoApplyField.ValueAsBool;
|
||||
preset.AutoSettings.ProcessAutoAction = processActionField.ValueAsEnum<ProcessAutoAction>();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,129 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<metadata name="mnuGameOptions.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>17, 17</value>
|
||||
</metadata>
|
||||
<metadata name="mnuGameActions.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>168, 17</value>
|
||||
</metadata>
|
||||
<metadata name="mnuGameAddStep.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>316, 17</value>
|
||||
</metadata>
|
||||
</root>
|
||||
@@ -0,0 +1,106 @@
|
||||
using ColorControl.Services.Common;
|
||||
using ColorControl.Shared.Contracts;
|
||||
using NWin32;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
|
||||
namespace ColorControl.Services.GameLauncher
|
||||
{
|
||||
public enum GameStepType
|
||||
{
|
||||
[Description("Pre-launch steps")]
|
||||
PreLaunch = 0,
|
||||
[Description("Post-launch steps")]
|
||||
PostLaunch = 1,
|
||||
[Description("Finalize steps")]
|
||||
Finalize = 2,
|
||||
}
|
||||
|
||||
public enum GamePriorityClass
|
||||
{
|
||||
Idle = NativeConstants.IDLE_PRIORITY_CLASS,
|
||||
BelowNormal = NativeConstants.BELOW_NORMAL_PRIORITY_CLASS,
|
||||
Normal = NativeConstants.NORMAL_PRIORITY_CLASS,
|
||||
AboveNormal = NativeConstants.ABOVE_NORMAL_PRIORITY_CLASS,
|
||||
High = NativeConstants.HIGH_PRIORITY_CLASS,
|
||||
RealTime = NativeConstants.REALTIME_PRIORITY_CLASS
|
||||
}
|
||||
|
||||
public enum ProcessAutoAction
|
||||
{
|
||||
None = 0,
|
||||
Suspend = 1,
|
||||
Restart = 2
|
||||
}
|
||||
|
||||
class AutoSettings
|
||||
{
|
||||
public bool AllowAutoApply { get; set; }
|
||||
public ProcessAutoAction ProcessAutoAction { get; set; }
|
||||
}
|
||||
|
||||
class GamePreset : PresetBase
|
||||
{
|
||||
public string Path { get; set; }
|
||||
public string Parameters { get; set; }
|
||||
public bool RunAsAdministrator { get; set; }
|
||||
public List<string> PreLaunchSteps { get; set; }
|
||||
public List<string> PostLaunchSteps { get; set; }
|
||||
public List<string> FinalizeSteps { get; set; }
|
||||
public uint ProcessAffinityMask { get; set; }
|
||||
public uint ProcessPriorityClass { get; set; }
|
||||
public AutoSettings AutoSettings { get; set; }
|
||||
|
||||
public GamePreset() : base()
|
||||
{
|
||||
PreLaunchSteps = new List<string>();
|
||||
PostLaunchSteps = new List<string>();
|
||||
FinalizeSteps = new List<string>();
|
||||
AutoSettings = new AutoSettings();
|
||||
}
|
||||
|
||||
public GamePreset(GamePreset preset) : this()
|
||||
{
|
||||
id = GetNewId();
|
||||
|
||||
name = preset.name;
|
||||
Path = preset.Path;
|
||||
Parameters = preset.Parameters;
|
||||
RunAsAdministrator = preset.RunAsAdministrator;
|
||||
PreLaunchSteps.AddRange(preset.PreLaunchSteps);
|
||||
PostLaunchSteps.AddRange(preset.PostLaunchSteps);
|
||||
FinalizeSteps.AddRange(preset.FinalizeSteps);
|
||||
}
|
||||
|
||||
public GamePreset Clone()
|
||||
{
|
||||
var preset = new GamePreset(this);
|
||||
|
||||
preset.name += " (copy)";
|
||||
|
||||
return preset;
|
||||
}
|
||||
|
||||
public static string[] GetColumnNames()
|
||||
{
|
||||
return new[] { "Name|160", "File/URI|400", "Parameters|200", "Pre-launch steps|300", "Post-launch steps|300", "Finalize steps|300" };
|
||||
}
|
||||
|
||||
public override List<string> GetDisplayValues(Config config = null)
|
||||
{
|
||||
var values = new List<string>
|
||||
{
|
||||
name,
|
||||
Path,
|
||||
Parameters,
|
||||
|
||||
string.Join(", ", PreLaunchSteps),
|
||||
string.Join(", ", PostLaunchSteps),
|
||||
string.Join(", ", FinalizeSteps)
|
||||
};
|
||||
|
||||
return values;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,288 @@
|
||||
using ColorControl.Services.Common;
|
||||
using ColorControl.Services.EventDispatcher;
|
||||
using ColorControl.Shared.Common;
|
||||
using ColorControl.Shared.Services;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace ColorControl.Services.GameLauncher
|
||||
{
|
||||
class GameService : ServiceBase<GamePreset>
|
||||
{
|
||||
private static readonly NLog.Logger Logger = NLog.LogManager.GetCurrentClassLogger();
|
||||
|
||||
public override string ServiceName => "Game";
|
||||
|
||||
protected override string PresetsBaseFilename => "GamePresets.json";
|
||||
|
||||
private ProcessEventDispatcher _processEventDispatcher;
|
||||
private readonly WinApiAdminService _winApiAdminService;
|
||||
private readonly WinApiService _winApiService;
|
||||
private ServiceManager _serviceManager;
|
||||
private int _lastStartedProcessId;
|
||||
private System.DateTime _lastStartedPresetDateTime = System.DateTime.MinValue;
|
||||
private string _lastStartedProcessPath;
|
||||
private string _configFilename;
|
||||
|
||||
public GameServiceConfig Config { get; private set; }
|
||||
|
||||
public GameService(AppContextProvider appContextProvider, ServiceManager serviceManager, ProcessEventDispatcher processEventDispatcher, WinApiAdminService winApiAdminService, WinApiService winApiService) : base(appContextProvider)
|
||||
{
|
||||
LoadConfig();
|
||||
LoadPresets();
|
||||
_serviceManager = serviceManager;
|
||||
_processEventDispatcher = processEventDispatcher;
|
||||
_winApiAdminService = winApiAdminService;
|
||||
_winApiService = winApiService;
|
||||
_processEventDispatcher.RegisterAsyncEventHandler(ProcessEventDispatcher.Event_ProcessChanged, ProcessChanged);
|
||||
}
|
||||
|
||||
private async Task ProcessChanged(object sender, ProcessChangedEventArgs e, CancellationToken token)
|
||||
{
|
||||
if (e.StartedProcesses?.Any() != true || !Config.ApplyExternallyLaunched)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (_lastStartedPresetDateTime > System.DateTime.Now.AddSeconds(-5))
|
||||
{
|
||||
return;
|
||||
}
|
||||
_lastStartedProcessId = 0;
|
||||
|
||||
var startedProcesses = e.StartedProcesses;
|
||||
|
||||
foreach (var startedProcess in startedProcesses)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (await HandleStartedProcess(startedProcess))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
catch (System.Exception) { }
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<bool> HandleStartedProcess(Process process)
|
||||
{
|
||||
GamePreset preset;
|
||||
|
||||
if (_winApiService.IsAdministrator())
|
||||
{
|
||||
var fileName = process.MainModule.FileName;
|
||||
|
||||
preset = _presets.FirstOrDefault(p => fileName.Contains(Path.GetDirectoryName(p.Path), System.StringComparison.OrdinalIgnoreCase));
|
||||
}
|
||||
else
|
||||
{
|
||||
var name = process.ProcessName.Replace("-Win64-Shipping", "");
|
||||
preset = _presets.FirstOrDefault(p => Path.GetFileName(p.Path).Contains(name, System.StringComparison.OrdinalIgnoreCase));
|
||||
}
|
||||
|
||||
if (preset == null || !preset.AutoSettings.AllowAutoApply)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (_lastStartedProcessId != process.Id)
|
||||
{
|
||||
Logger.Debug($"Auto-starting preset {preset.name} for process {process.ProcessName}");
|
||||
|
||||
var mainThreadId = 0;
|
||||
var suspended = false;
|
||||
if (preset.AutoSettings.ProcessAutoAction == ProcessAutoAction.Suspend)
|
||||
{
|
||||
mainThreadId = _winApiAdminService.SuspendMainThread(process.Id);
|
||||
suspended = true;
|
||||
}
|
||||
else if (preset.AutoSettings.ProcessAutoAction == ProcessAutoAction.Restart)
|
||||
{
|
||||
_winApiAdminService.StopProcess(process.Id);
|
||||
process = null;
|
||||
}
|
||||
|
||||
var _ = ExecutePreset(preset, process, suspended ? mainThreadId : 0);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
protected override List<GamePreset> GetDefaultPresets()
|
||||
{
|
||||
return new List<GamePreset>();
|
||||
}
|
||||
|
||||
private void SavePresets()
|
||||
{
|
||||
Utils.WriteObject(_presetsFilename, _presets);
|
||||
}
|
||||
|
||||
public void GlobalSave()
|
||||
{
|
||||
SavePresets();
|
||||
SaveConfig();
|
||||
}
|
||||
|
||||
public async Task<bool> ApplyPreset(string idOrName)
|
||||
{
|
||||
var preset = GetPresetByIdOrName(idOrName);
|
||||
if (preset != null)
|
||||
{
|
||||
return await ApplyPreset(preset, Program.AppContext);
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public override async Task<bool> ApplyPreset(GamePreset preset)
|
||||
{
|
||||
return await ApplyPreset(preset, Program.AppContext);
|
||||
}
|
||||
|
||||
public async Task<bool> ApplyPreset(GamePreset preset, GlobalContext _)
|
||||
{
|
||||
var result = await ExecutePreset(preset);
|
||||
|
||||
_lastAppliedPreset = preset;
|
||||
|
||||
PresetApplied();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private async Task<bool> ExecutePreset(GamePreset preset, Process process = null, int resumeThreadId = default)
|
||||
{
|
||||
var result = true;
|
||||
|
||||
await ExecuteSteps(preset.PreLaunchSteps);
|
||||
|
||||
if (process == null && !string.IsNullOrEmpty(preset.Path))
|
||||
{
|
||||
process = _winApiAdminService.StartProcess(preset.Path, preset.Parameters, setWorkingDir: true, elevate: preset.RunAsAdministrator, affinityMask: preset.ProcessAffinityMask, priorityClass: preset.ProcessPriorityClass);
|
||||
|
||||
_lastStartedPresetDateTime = System.DateTime.Now;
|
||||
_lastStartedProcessId = process.Id;
|
||||
_lastStartedProcessPath = Path.GetDirectoryName(preset.Path);
|
||||
}
|
||||
else if (resumeThreadId != default)
|
||||
{
|
||||
_winApiAdminService.ResumeThread((uint)resumeThreadId);
|
||||
}
|
||||
|
||||
await ExecuteSteps(preset.PostLaunchSteps);
|
||||
|
||||
if (process != null && preset.FinalizeSteps?.Any() == true)
|
||||
{
|
||||
await ExecuteFinalizationStepsAsync(process, preset.FinalizeSteps);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private async Task ExecuteFinalizationStepsAsync(Process process, List<string> finalizeSteps)
|
||||
{
|
||||
await Task.Delay(1000);
|
||||
|
||||
try
|
||||
{
|
||||
if (process.HasExited)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
await process.WaitForExitAsync();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Error(ex);
|
||||
return;
|
||||
}
|
||||
|
||||
await ExecuteSteps(finalizeSteps);
|
||||
}
|
||||
|
||||
private async Task ExecuteSteps(List<string> steps)
|
||||
{
|
||||
if (steps?.Any() != true)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var step in steps)
|
||||
{
|
||||
var keySpec = step.Split(':');
|
||||
|
||||
var delay = 0;
|
||||
var key = step;
|
||||
if (keySpec.Length == 2)
|
||||
{
|
||||
delay = Utils.ParseInt(keySpec[1]);
|
||||
if (delay > 0)
|
||||
{
|
||||
key = keySpec[0];
|
||||
}
|
||||
}
|
||||
|
||||
var index = key.IndexOf("(");
|
||||
string[] parameters = null;
|
||||
if (index > -1)
|
||||
{
|
||||
var keyValue = key.Split('(');
|
||||
key = keyValue[0];
|
||||
parameters = keyValue[1].Substring(0, keyValue[1].Length - 1).Trim().Split(';');
|
||||
}
|
||||
|
||||
var handled = false;
|
||||
|
||||
if (parameters != null)
|
||||
{
|
||||
handled = await _serviceManager.HandleExternalServiceAsync(key, parameters);
|
||||
}
|
||||
|
||||
if (!handled)
|
||||
{
|
||||
}
|
||||
|
||||
if (delay > 0)
|
||||
{
|
||||
await Task.Delay(delay);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private void LoadConfig()
|
||||
{
|
||||
_configFilename = Path.Combine(_dataPath, "GameConfig.json");
|
||||
try
|
||||
{
|
||||
if (File.Exists(_configFilename))
|
||||
{
|
||||
Config = JsonConvert.DeserializeObject<GameServiceConfig>(File.ReadAllText(_configFilename));
|
||||
}
|
||||
}
|
||||
catch (System.Exception ex)
|
||||
{
|
||||
Logger.Error($"LoadConfig: {ex.Message}");
|
||||
}
|
||||
Config ??= new GameServiceConfig();
|
||||
}
|
||||
|
||||
private void SaveConfig()
|
||||
{
|
||||
Utils.WriteObject(_configFilename, Config);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
namespace ColorControl.Services.GameLauncher
|
||||
{
|
||||
class GameServiceConfig
|
||||
{
|
||||
public bool ApplyExternallyLaunched { get; set; }
|
||||
|
||||
public GameServiceConfig()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large.
Load diff
+139
@@ -0,0 +1,139 @@
|
||||
|
||||
namespace ColorControl.Services.LG
|
||||
{
|
||||
partial class LgGameBar
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Windows Form Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.components = new System.ComponentModel.Container();
|
||||
this.flowPanel = new System.Windows.Forms.FlowLayoutPanel();
|
||||
this.btnClose = new System.Windows.Forms.Button();
|
||||
this.lblTvName = new System.Windows.Forms.Label();
|
||||
this.tmrHide = new System.Windows.Forms.Timer(this.components);
|
||||
this.lblProcessName = new System.Windows.Forms.Label();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// flowPanel
|
||||
//
|
||||
this.flowPanel.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.flowPanel.Location = new System.Drawing.Point(14, 47);
|
||||
this.flowPanel.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
this.flowPanel.Name = "flowPanel";
|
||||
this.flowPanel.Size = new System.Drawing.Size(270, 325);
|
||||
this.flowPanel.TabIndex = 0;
|
||||
this.flowPanel.MouseDown += new System.Windows.Forms.MouseEventHandler(this.RemoteControlForm_MouseDown);
|
||||
this.flowPanel.MouseMove += new System.Windows.Forms.MouseEventHandler(this.flowPanel_MouseMove);
|
||||
this.flowPanel.PreviewKeyDown += new System.Windows.Forms.PreviewKeyDownEventHandler(this.flowPanel_PreviewKeyDown);
|
||||
//
|
||||
// btnClose
|
||||
//
|
||||
this.btnClose.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.btnClose.FlatAppearance.BorderColor = System.Drawing.Color.DarkGray;
|
||||
this.btnClose.FlatAppearance.BorderSize = 0;
|
||||
this.btnClose.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
|
||||
this.btnClose.ForeColor = System.Drawing.Color.White;
|
||||
this.btnClose.Location = new System.Drawing.Point(280, 0);
|
||||
this.btnClose.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
this.btnClose.Name = "btnClose";
|
||||
this.btnClose.Size = new System.Drawing.Size(16, 27);
|
||||
this.btnClose.TabIndex = 1;
|
||||
this.btnClose.TabStop = false;
|
||||
this.btnClose.Text = "x";
|
||||
this.btnClose.UseVisualStyleBackColor = true;
|
||||
this.btnClose.Click += new System.EventHandler(this.btnClose_Click);
|
||||
//
|
||||
// lblTvName
|
||||
//
|
||||
this.lblTvName.AutoSize = true;
|
||||
this.lblTvName.ForeColor = System.Drawing.Color.White;
|
||||
this.lblTvName.Location = new System.Drawing.Point(14, 0);
|
||||
this.lblTvName.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
|
||||
this.lblTvName.Name = "lblTvName";
|
||||
this.lblTvName.Size = new System.Drawing.Size(25, 15);
|
||||
this.lblTvName.TabIndex = 0;
|
||||
this.lblTvName.Text = " ";
|
||||
//
|
||||
// tmrHide
|
||||
//
|
||||
this.tmrHide.Interval = 5000;
|
||||
this.tmrHide.Tick += new System.EventHandler(this.tmrHide_Tick);
|
||||
//
|
||||
// lblProcessName
|
||||
//
|
||||
this.lblProcessName.AutoSize = true;
|
||||
this.lblProcessName.ForeColor = System.Drawing.Color.White;
|
||||
this.lblProcessName.Location = new System.Drawing.Point(14, 23);
|
||||
this.lblProcessName.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
|
||||
this.lblProcessName.Name = "lblProcessName";
|
||||
this.lblProcessName.Size = new System.Drawing.Size(25, 15);
|
||||
this.lblProcessName.TabIndex = 2;
|
||||
this.lblProcessName.Text = " ";
|
||||
//
|
||||
// LgGameBar
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.BackColor = System.Drawing.Color.Black;
|
||||
this.ClientSize = new System.Drawing.Size(298, 387);
|
||||
this.Controls.Add(this.lblProcessName);
|
||||
this.Controls.Add(this.lblTvName);
|
||||
this.Controls.Add(this.btnClose);
|
||||
this.Controls.Add(this.flowPanel);
|
||||
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
|
||||
this.KeyPreview = true;
|
||||
this.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
this.MaximizeBox = false;
|
||||
this.MinimizeBox = false;
|
||||
this.Name = "LgGameBar";
|
||||
this.Opacity = 0.7D;
|
||||
this.StartPosition = System.Windows.Forms.FormStartPosition.Manual;
|
||||
this.Text = "RemoteControlForm";
|
||||
this.TopMost = true;
|
||||
this.Activated += new System.EventHandler(this.LgGameBar_Activated);
|
||||
this.Deactivate += new System.EventHandler(this.LgGameBar_Deactivate);
|
||||
this.Load += new System.EventHandler(this.RemoteControlForm_Load);
|
||||
this.Shown += new System.EventHandler(this.RemoteControlForm_Shown);
|
||||
this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.RemoteControlForm_KeyDown);
|
||||
this.KeyUp += new System.Windows.Forms.KeyEventHandler(this.RemoteControlForm_KeyUp);
|
||||
this.MouseDown += new System.Windows.Forms.MouseEventHandler(this.RemoteControlForm_MouseDown);
|
||||
this.Move += new System.EventHandler(this.LgGameBar_Move);
|
||||
this.PreviewKeyDown += new System.Windows.Forms.PreviewKeyDownEventHandler(this.RemoteControlForm_PreviewKeyDown);
|
||||
this.ResumeLayout(false);
|
||||
this.PerformLayout();
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.FlowLayoutPanel flowPanel;
|
||||
private System.Windows.Forms.Button btnClose;
|
||||
private System.Windows.Forms.Label lblTvName;
|
||||
private System.Windows.Forms.Timer tmrHide;
|
||||
private System.Windows.Forms.Label lblProcessName;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,330 @@
|
||||
using ColorControl.Shared.Common;
|
||||
using ColorControl.Shared.Forms;
|
||||
using NWin32;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace ColorControl.Services.LG
|
||||
{
|
||||
partial class LgGameBar : Form
|
||||
{
|
||||
private class TbSetting
|
||||
{
|
||||
public TrackBar TrackBar { get; set; }
|
||||
public string Name { get; set; }
|
||||
public Type EnumType { get; set; }
|
||||
public string PropertyName { get; set; }
|
||||
}
|
||||
|
||||
private LgService _lgService;
|
||||
private LgDevice _lgDevice;
|
||||
private ToolTip _toolTip;
|
||||
private bool _settingChanged = false;
|
||||
private List<TrackBar> _trackBars = new List<TrackBar>();
|
||||
private List<string> _lastActions = new List<string>();
|
||||
|
||||
public LgGameBar(LgService lgService)
|
||||
{
|
||||
_lgService = lgService;
|
||||
|
||||
_lgDevice = _lgService.SelectedDevice;
|
||||
|
||||
_lgDevice.PictureSettingsChangedEvent += LgDevice_PictureSettingsChangedEvent;
|
||||
|
||||
InitializeComponent();
|
||||
|
||||
_toolTip = new ToolTip();
|
||||
}
|
||||
|
||||
private void GenerateComponents()
|
||||
{
|
||||
var actions = _lgDevice.GetActionsForGameBar();
|
||||
var actionNames = actions.Select(a => a.Name).ToList();
|
||||
|
||||
if (_lastActions.Count == actions.Count && _lastActions.All(a => actionNames.Contains(a)))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
flowPanel.Controls.Clear();
|
||||
_trackBars.Clear();
|
||||
|
||||
foreach (var action in actions)
|
||||
{
|
||||
CreateGroup(action.Title, action.Name, (int)action.MinValue, (int)action.MaxValue, action.EnumType);
|
||||
}
|
||||
|
||||
_lastActions.Clear();
|
||||
_lastActions.AddRange(actionNames);
|
||||
|
||||
Width = 28 + (_trackBars.Count() * 56);
|
||||
}
|
||||
|
||||
private TrackBar CreateGroup(string title, string settingName = null, int min = 0, int max = 100, Type enumType = null)
|
||||
{
|
||||
if (settingName == null)
|
||||
{
|
||||
settingName = title.ToLowerInvariant();
|
||||
}
|
||||
|
||||
var panel = new Panel();
|
||||
panel.Width = 50;
|
||||
panel.Height = flowPanel.Height;
|
||||
var label = new Label();
|
||||
label.Text = title;
|
||||
label.ForeColor = Color.White;
|
||||
label.Parent = panel;
|
||||
|
||||
if (min == 0 && max == 0 && enumType != null)
|
||||
{
|
||||
max = Enum.GetValues(enumType).Length - 1;
|
||||
}
|
||||
|
||||
var trackBar = CreateTrackBar(min, max);
|
||||
trackBar.Top = label.Height;
|
||||
trackBar.Height = panel.Height - trackBar.Top - 4;
|
||||
trackBar.Parent = panel;
|
||||
trackBar.Scroll += tbTrackBar_Scroll;
|
||||
var margin = trackBar.Margin;
|
||||
margin.Top = 0;
|
||||
margin.Bottom = 0;
|
||||
trackBar.Margin = margin;
|
||||
trackBar.ValueChanged += TrackBar_ValueChanged;
|
||||
|
||||
var setting = new TbSetting
|
||||
{
|
||||
TrackBar = trackBar,
|
||||
Name = settingName,
|
||||
EnumType = enumType,
|
||||
PropertyName = Utils.FirstCharUpperCase(settingName)
|
||||
};
|
||||
|
||||
trackBar.Tag = setting;
|
||||
|
||||
panel.Parent = flowPanel;
|
||||
|
||||
_trackBars.Add(trackBar);
|
||||
|
||||
return trackBar;
|
||||
}
|
||||
|
||||
private void TrackBar_ValueChanged(object sender, EventArgs e)
|
||||
{
|
||||
//var trackBar = sender as TrackBar;
|
||||
|
||||
//if (_toolTip != null)
|
||||
//{
|
||||
// _toolTip.SetToolTip(trackBar, trackBar.Value.ToString());
|
||||
//}
|
||||
}
|
||||
|
||||
private TrackBar CreateTrackBar(int min, int max)
|
||||
{
|
||||
var trackBar = new TrackBar();
|
||||
trackBar.BackColor = Color.Black;
|
||||
trackBar.Orientation = Orientation.Vertical;
|
||||
trackBar.TickFrequency = (max >= 50) ? 5 : 1;
|
||||
trackBar.TickStyle = TickStyle.Both;
|
||||
trackBar.Minimum = min;
|
||||
trackBar.Maximum = max;
|
||||
|
||||
return trackBar;
|
||||
}
|
||||
|
||||
private void LgDevice_PictureSettingsChangedEvent(object sender, EventArgs e)
|
||||
{
|
||||
if (_settingChanged)
|
||||
{
|
||||
_settingChanged = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!Visible)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
FormUtils.BeginInvokeCheck(this, UpdateValues);
|
||||
}
|
||||
|
||||
private void UpdateValues()
|
||||
{
|
||||
var dynType = _lgDevice.PictureSettings.GetType();
|
||||
var actions = _lgDevice.GetInvokableActions();
|
||||
foreach (var trackbar in _trackBars.Where(t => !t.Focused))
|
||||
{
|
||||
var setting = (TbSetting)trackbar.Tag;
|
||||
|
||||
if (setting.PropertyName == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var prop = dynType.GetProperty(setting.PropertyName);
|
||||
|
||||
if (prop != null)
|
||||
{
|
||||
var value = prop.GetValue(_lgDevice.PictureSettings);
|
||||
|
||||
if (value is int intValue)
|
||||
{
|
||||
trackbar.Value = intValue;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var action = actions.FirstOrDefault(a => a.Name == setting.Name);
|
||||
if (action != null)
|
||||
{
|
||||
trackbar.Value = action.CurrentValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void RemoteControlForm_Load(object sender, EventArgs e)
|
||||
{
|
||||
Left = _lgService.Config.GameBarLeft;
|
||||
Top = _lgService.Config.GameBarTop;
|
||||
}
|
||||
|
||||
private void ButtonClick(object sender, EventArgs e)
|
||||
{
|
||||
if (e is MouseEventArgs)
|
||||
{
|
||||
var preset = (LgPreset)(sender as Button).Tag;
|
||||
|
||||
var _ = _lgService.ApplyPreset(preset);
|
||||
}
|
||||
}
|
||||
|
||||
private void btnClose_Click(object sender, EventArgs e)
|
||||
{
|
||||
Hide();
|
||||
}
|
||||
|
||||
private void RemoteControlForm_MouseDown(object sender, MouseEventArgs e)
|
||||
{
|
||||
if (e.Button == MouseButtons.Left)
|
||||
{
|
||||
NativeMethods.ReleaseCapture();
|
||||
var intPtr = new UIntPtr(2);
|
||||
NativeMethods.SendMessageW(Handle, NativeConstants.WM_NCLBUTTONDOWN, intPtr, IntPtr.Zero);
|
||||
}
|
||||
}
|
||||
|
||||
private void RemoteControlForm_KeyDown(object sender, KeyEventArgs e)
|
||||
{
|
||||
//var key = e.KeyCode;
|
||||
//HandleKey(key);
|
||||
}
|
||||
|
||||
private void flowPanel_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
|
||||
{
|
||||
//HandleKey(e.KeyCode);
|
||||
}
|
||||
|
||||
private void HandleKey(Keys key)
|
||||
{
|
||||
var cvt = new KeysConverter();
|
||||
var shortcut = (string)cvt.ConvertTo(key, typeof(string));
|
||||
}
|
||||
|
||||
private void RemoteControlForm_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
|
||||
{
|
||||
//HandleKey(e.KeyCode);
|
||||
}
|
||||
|
||||
private void RemoteControlForm_KeyUp(object sender, KeyEventArgs e)
|
||||
{
|
||||
if (e.KeyCode == Keys.F1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
HandleKey(e.KeyCode);
|
||||
}
|
||||
|
||||
private void flowPanel_MouseMove(object sender, MouseEventArgs e)
|
||||
{
|
||||
ResetAutoHide();
|
||||
}
|
||||
|
||||
private void RemoteControlForm_Shown(object sender, EventArgs e)
|
||||
{
|
||||
GenerateComponents();
|
||||
UpdateInfo();
|
||||
ResetAutoHide();
|
||||
}
|
||||
|
||||
private void UpdateInfo()
|
||||
{
|
||||
lblTvName.Text = $"Device: {_lgDevice?.Name ?? "No tv selected"}";
|
||||
lblProcessName.Text = $"Current process: {_lgService.CurrentProcessEvent?.ForegroundProcess?.ProcessName ?? _lgService.CurrentProcessEvent?.LastFullScreenProcessName ?? "No full screen process"}";
|
||||
|
||||
UpdateValues();
|
||||
}
|
||||
|
||||
private void LgGameBar_Deactivate(object sender, EventArgs e)
|
||||
{
|
||||
_lgService.Config.GameBarLeft = Left;
|
||||
_lgService.Config.GameBarTop = Top;
|
||||
Hide();
|
||||
}
|
||||
|
||||
private void tmrHide_Tick(object sender, EventArgs e)
|
||||
{
|
||||
_lgService.Config.GameBarLeft = Left;
|
||||
_lgService.Config.GameBarTop = Top;
|
||||
Hide();
|
||||
}
|
||||
|
||||
private async void tbTrackBar_Scroll(object sender, EventArgs e)
|
||||
{
|
||||
_settingChanged = true;
|
||||
ResetAutoHide();
|
||||
|
||||
var trackBar = sender as TrackBar;
|
||||
var setting = (TbSetting)trackBar.Tag;
|
||||
|
||||
string value;
|
||||
if (setting.EnumType == null)
|
||||
{
|
||||
value = trackBar.Value.ToString();
|
||||
}
|
||||
else
|
||||
{
|
||||
var enumValue = Enum.Parse(setting.EnumType, trackBar.Value.ToString());
|
||||
value = enumValue.ToString();
|
||||
}
|
||||
|
||||
await _lgDevice.SetSystemSettings(setting.Name, value);
|
||||
|
||||
if (_toolTip != null)
|
||||
{
|
||||
_toolTip.Show(value, trackBar, 10, 50, 1500);
|
||||
}
|
||||
}
|
||||
|
||||
private void LgGameBar_Activated(object sender, EventArgs e)
|
||||
{
|
||||
GenerateComponents();
|
||||
UpdateInfo();
|
||||
ResetAutoHide();
|
||||
}
|
||||
|
||||
private void LgGameBar_Move(object sender, EventArgs e)
|
||||
{
|
||||
ResetAutoHide();
|
||||
}
|
||||
|
||||
private void ResetAutoHide()
|
||||
{
|
||||
tmrHide.Enabled = false;
|
||||
tmrHide.Enabled = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
<root>
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<metadata name="tmrHide.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>17, 17</value>
|
||||
</metadata>
|
||||
</root>
|
||||
+939
@@ -0,0 +1,939 @@
|
||||
namespace ColorControl.Services.LG
|
||||
{
|
||||
partial class LgPanel
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Component Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
components = new System.ComponentModel.Container();
|
||||
scLgController = new System.Windows.Forms.SplitContainer();
|
||||
btnLgDeviceOptionsSettings = new System.Windows.Forms.Button();
|
||||
btnLgSettings = new System.Windows.Forms.Button();
|
||||
chkLgQuickAccess = new System.Windows.Forms.CheckBox();
|
||||
cbxLgPcHdmiPort = new System.Windows.Forms.ComboBox();
|
||||
lblLgPcHdmiPort = new System.Windows.Forms.Label();
|
||||
edtLgPresetDescription = new System.Windows.Forms.TextBox();
|
||||
lblLgPresetDescription = new System.Windows.Forms.Label();
|
||||
btnLgDeviceOptionsHelp = new System.Windows.Forms.Button();
|
||||
btnLgGameBar = new System.Windows.Forms.Button();
|
||||
btnLgPresetEditTriggerConditions = new System.Windows.Forms.Button();
|
||||
edtLgPresetTriggerConditions = new System.Windows.Forms.TextBox();
|
||||
lblLgPresetExcludedProcesses = new System.Windows.Forms.Label();
|
||||
edtLgPresetExcludedProcesses = new System.Windows.Forms.TextBox();
|
||||
lblLgPresetIncludedProcesses = new System.Windows.Forms.Label();
|
||||
edtLgPresetIncludedProcesses = new System.Windows.Forms.TextBox();
|
||||
lblLgPresetTriggerCondition = new System.Windows.Forms.Label();
|
||||
cbxLgPresetTrigger = new System.Windows.Forms.ComboBox();
|
||||
lblLgPresetTrigger = new System.Windows.Forms.Label();
|
||||
btnLgExpert = new System.Windows.Forms.Button();
|
||||
mnuLgExpert = new System.Windows.Forms.ContextMenuStrip(components);
|
||||
mnuLgOLEDMotionPro = new System.Windows.Forms.ToolStripMenuItem();
|
||||
miLgEnableMotionPro = new System.Windows.Forms.ToolStripMenuItem();
|
||||
miLgDisableMotionPro = new System.Windows.Forms.ToolStripMenuItem();
|
||||
mnuLgSetSvcMenuFlag = new System.Windows.Forms.ToolStripMenuItem();
|
||||
miLgFullServiceMenuEnable = new System.Windows.Forms.ToolStripMenuItem();
|
||||
miLgFullServiceMenuDisable = new System.Windows.Forms.ToolStripMenuItem();
|
||||
miLgExpertSeparator1 = new System.Windows.Forms.ToolStripSeparator();
|
||||
chkLgRemoteControlShow = new System.Windows.Forms.CheckBox();
|
||||
label3 = new System.Windows.Forms.Label();
|
||||
cbxLgDevices = new System.Windows.Forms.ComboBox();
|
||||
btnLgDeviceConvertToCustom = new System.Windows.Forms.Button();
|
||||
cbxLgApps = new System.Windows.Forms.ComboBox();
|
||||
lvLgPresets = new System.Windows.Forms.ListView();
|
||||
label5 = new System.Windows.Forms.Label();
|
||||
cbxLgPresetDevice = new System.Windows.Forms.ComboBox();
|
||||
btnDeleteLg = new System.Windows.Forms.Button();
|
||||
btnApplyLg = new System.Windows.Forms.Button();
|
||||
lblDeviceFilter = new System.Windows.Forms.Label();
|
||||
lblLgPresetDevice = new System.Windows.Forms.Label();
|
||||
btnAddLg = new System.Windows.Forms.Button();
|
||||
edtShortcutLg = new System.Windows.Forms.TextBox();
|
||||
edtLgDeviceFilter = new System.Windows.Forms.TextBox();
|
||||
btnLgRemoveDevice = new System.Windows.Forms.Button();
|
||||
btnLgRefreshApps = new System.Windows.Forms.Button();
|
||||
label2 = new System.Windows.Forms.Label();
|
||||
label1 = new System.Windows.Forms.Label();
|
||||
btnLgAddDevice = new System.Windows.Forms.Button();
|
||||
edtNameLg = new System.Windows.Forms.TextBox();
|
||||
btnSetShortcutLg = new System.Windows.Forms.Button();
|
||||
edtStepsLg = new System.Windows.Forms.TextBox();
|
||||
btnLgAddButton = new System.Windows.Forms.Button();
|
||||
mnuLgButtons = new System.Windows.Forms.ContextMenuStrip(components);
|
||||
mnuLgRcButtons = new System.Windows.Forms.ToolStripMenuItem();
|
||||
mnuLgActions = new System.Windows.Forms.ToolStripMenuItem();
|
||||
mnuLgNvPresets = new System.Windows.Forms.ToolStripMenuItem();
|
||||
mnuLgAmdPresets = new System.Windows.Forms.ToolStripMenuItem();
|
||||
mnuLgProgram = new System.Windows.Forms.ToolStripMenuItem();
|
||||
btnCloneLg = new System.Windows.Forms.Button();
|
||||
lblStepsLg = new System.Windows.Forms.Label();
|
||||
btnLgDeviceFilterRefresh = new System.Windows.Forms.Button();
|
||||
clbLgPower = new System.Windows.Forms.CheckedListBox();
|
||||
lblLgError = new System.Windows.Forms.Label();
|
||||
mnuLgSettings = new System.Windows.Forms.ContextMenuStrip(components);
|
||||
miTestPowerOffOn = new System.Windows.Forms.ToolStripMenuItem();
|
||||
miNvSettings = new System.Windows.Forms.ToolStripMenuItem();
|
||||
((System.ComponentModel.ISupportInitialize)scLgController).BeginInit();
|
||||
scLgController.Panel1.SuspendLayout();
|
||||
scLgController.SuspendLayout();
|
||||
mnuLgExpert.SuspendLayout();
|
||||
mnuLgButtons.SuspendLayout();
|
||||
mnuLgSettings.SuspendLayout();
|
||||
SuspendLayout();
|
||||
//
|
||||
// scLgController
|
||||
//
|
||||
scLgController.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
scLgController.Location = new System.Drawing.Point(0, 0);
|
||||
scLgController.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
scLgController.Name = "scLgController";
|
||||
//
|
||||
// scLgController.Panel1
|
||||
//
|
||||
scLgController.Panel1.Controls.Add(btnLgDeviceOptionsSettings);
|
||||
scLgController.Panel1.Controls.Add(btnLgSettings);
|
||||
scLgController.Panel1.Controls.Add(chkLgQuickAccess);
|
||||
scLgController.Panel1.Controls.Add(cbxLgPcHdmiPort);
|
||||
scLgController.Panel1.Controls.Add(lblLgPcHdmiPort);
|
||||
scLgController.Panel1.Controls.Add(edtLgPresetDescription);
|
||||
scLgController.Panel1.Controls.Add(lblLgPresetDescription);
|
||||
scLgController.Panel1.Controls.Add(btnLgDeviceOptionsHelp);
|
||||
scLgController.Panel1.Controls.Add(btnLgGameBar);
|
||||
scLgController.Panel1.Controls.Add(btnLgPresetEditTriggerConditions);
|
||||
scLgController.Panel1.Controls.Add(edtLgPresetTriggerConditions);
|
||||
scLgController.Panel1.Controls.Add(lblLgPresetExcludedProcesses);
|
||||
scLgController.Panel1.Controls.Add(edtLgPresetExcludedProcesses);
|
||||
scLgController.Panel1.Controls.Add(lblLgPresetIncludedProcesses);
|
||||
scLgController.Panel1.Controls.Add(edtLgPresetIncludedProcesses);
|
||||
scLgController.Panel1.Controls.Add(lblLgPresetTriggerCondition);
|
||||
scLgController.Panel1.Controls.Add(cbxLgPresetTrigger);
|
||||
scLgController.Panel1.Controls.Add(lblLgPresetTrigger);
|
||||
scLgController.Panel1.Controls.Add(btnLgExpert);
|
||||
scLgController.Panel1.Controls.Add(chkLgRemoteControlShow);
|
||||
scLgController.Panel1.Controls.Add(label3);
|
||||
scLgController.Panel1.Controls.Add(cbxLgDevices);
|
||||
scLgController.Panel1.Controls.Add(btnLgDeviceConvertToCustom);
|
||||
scLgController.Panel1.Controls.Add(cbxLgApps);
|
||||
scLgController.Panel1.Controls.Add(lvLgPresets);
|
||||
scLgController.Panel1.Controls.Add(label5);
|
||||
scLgController.Panel1.Controls.Add(cbxLgPresetDevice);
|
||||
scLgController.Panel1.Controls.Add(btnDeleteLg);
|
||||
scLgController.Panel1.Controls.Add(btnApplyLg);
|
||||
scLgController.Panel1.Controls.Add(lblDeviceFilter);
|
||||
scLgController.Panel1.Controls.Add(lblLgPresetDevice);
|
||||
scLgController.Panel1.Controls.Add(btnAddLg);
|
||||
scLgController.Panel1.Controls.Add(edtShortcutLg);
|
||||
scLgController.Panel1.Controls.Add(edtLgDeviceFilter);
|
||||
scLgController.Panel1.Controls.Add(btnLgRemoveDevice);
|
||||
scLgController.Panel1.Controls.Add(btnLgRefreshApps);
|
||||
scLgController.Panel1.Controls.Add(label2);
|
||||
scLgController.Panel1.Controls.Add(label1);
|
||||
scLgController.Panel1.Controls.Add(btnLgAddDevice);
|
||||
scLgController.Panel1.Controls.Add(edtNameLg);
|
||||
scLgController.Panel1.Controls.Add(btnSetShortcutLg);
|
||||
scLgController.Panel1.Controls.Add(edtStepsLg);
|
||||
scLgController.Panel1.Controls.Add(btnLgAddButton);
|
||||
scLgController.Panel1.Controls.Add(btnCloneLg);
|
||||
scLgController.Panel1.Controls.Add(lblStepsLg);
|
||||
scLgController.Panel1.Controls.Add(btnLgDeviceFilterRefresh);
|
||||
scLgController.Panel1.Controls.Add(clbLgPower);
|
||||
scLgController.Panel1.Controls.Add(lblLgError);
|
||||
scLgController.Panel1MinSize = 750;
|
||||
scLgController.Panel2MinSize = 150;
|
||||
scLgController.Size = new System.Drawing.Size(1114, 539);
|
||||
scLgController.SplitterDistance = 899;
|
||||
scLgController.SplitterWidth = 5;
|
||||
scLgController.TabIndex = 43;
|
||||
//
|
||||
// btnLgDeviceOptionsSettings
|
||||
//
|
||||
btnLgDeviceOptionsSettings.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right;
|
||||
btnLgDeviceOptionsSettings.Enabled = false;
|
||||
btnLgDeviceOptionsSettings.Location = new System.Drawing.Point(872, 103);
|
||||
btnLgDeviceOptionsSettings.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
btnLgDeviceOptionsSettings.Name = "btnLgDeviceOptionsSettings";
|
||||
btnLgDeviceOptionsSettings.Size = new System.Drawing.Size(22, 27);
|
||||
btnLgDeviceOptionsSettings.TabIndex = 65;
|
||||
btnLgDeviceOptionsSettings.Text = "S";
|
||||
btnLgDeviceOptionsSettings.UseVisualStyleBackColor = true;
|
||||
btnLgDeviceOptionsSettings.Click += btnLgDeviceOptionsSettings_Click;
|
||||
//
|
||||
// btnLgSettings
|
||||
//
|
||||
btnLgSettings.Anchor = System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right;
|
||||
btnLgSettings.Location = new System.Drawing.Point(807, 284);
|
||||
btnLgSettings.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
btnLgSettings.Name = "btnLgSettings";
|
||||
btnLgSettings.Size = new System.Drawing.Size(88, 27);
|
||||
btnLgSettings.TabIndex = 64;
|
||||
btnLgSettings.Text = "Settings...";
|
||||
btnLgSettings.UseVisualStyleBackColor = true;
|
||||
btnLgSettings.Click += btnLgSettings_Click;
|
||||
//
|
||||
// chkLgQuickAccess
|
||||
//
|
||||
chkLgQuickAccess.Anchor = System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left;
|
||||
chkLgQuickAccess.AutoSize = true;
|
||||
chkLgQuickAccess.Enabled = false;
|
||||
chkLgQuickAccess.Location = new System.Drawing.Point(341, 320);
|
||||
chkLgQuickAccess.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
chkLgQuickAccess.Name = "chkLgQuickAccess";
|
||||
chkLgQuickAccess.Size = new System.Drawing.Size(96, 19);
|
||||
chkLgQuickAccess.TabIndex = 63;
|
||||
chkLgQuickAccess.Text = "Quick Access";
|
||||
chkLgQuickAccess.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// cbxLgPcHdmiPort
|
||||
//
|
||||
cbxLgPcHdmiPort.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
|
||||
cbxLgPcHdmiPort.FormattingEnabled = true;
|
||||
cbxLgPcHdmiPort.Items.AddRange(new object[] { "None", "HDMI1", "HDMI2", "HDMI3", "HDMI4" });
|
||||
cbxLgPcHdmiPort.Location = new System.Drawing.Point(667, 42);
|
||||
cbxLgPcHdmiPort.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
cbxLgPcHdmiPort.Name = "cbxLgPcHdmiPort";
|
||||
cbxLgPcHdmiPort.Size = new System.Drawing.Size(86, 23);
|
||||
cbxLgPcHdmiPort.TabIndex = 62;
|
||||
cbxLgPcHdmiPort.SelectedIndexChanged += cbxLgPcHdmiPort_SelectedIndexChanged;
|
||||
//
|
||||
// lblLgPcHdmiPort
|
||||
//
|
||||
lblLgPcHdmiPort.AutoSize = true;
|
||||
lblLgPcHdmiPort.Location = new System.Drawing.Point(577, 45);
|
||||
lblLgPcHdmiPort.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
|
||||
lblLgPcHdmiPort.Name = "lblLgPcHdmiPort";
|
||||
lblLgPcHdmiPort.Size = new System.Drawing.Size(84, 15);
|
||||
lblLgPcHdmiPort.TabIndex = 61;
|
||||
lblLgPcHdmiPort.Text = "PC HDMI port:";
|
||||
//
|
||||
// edtLgPresetDescription
|
||||
//
|
||||
edtLgPresetDescription.Anchor = System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right;
|
||||
edtLgPresetDescription.Enabled = false;
|
||||
edtLgPresetDescription.Location = new System.Drawing.Point(100, 489);
|
||||
edtLgPresetDescription.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
edtLgPresetDescription.Multiline = true;
|
||||
edtLgPresetDescription.Name = "edtLgPresetDescription";
|
||||
edtLgPresetDescription.Size = new System.Drawing.Size(699, 43);
|
||||
edtLgPresetDescription.TabIndex = 60;
|
||||
//
|
||||
// lblLgPresetDescription
|
||||
//
|
||||
lblLgPresetDescription.Anchor = System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left;
|
||||
lblLgPresetDescription.AutoSize = true;
|
||||
lblLgPresetDescription.Location = new System.Drawing.Point(6, 494);
|
||||
lblLgPresetDescription.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
|
||||
lblLgPresetDescription.Name = "lblLgPresetDescription";
|
||||
lblLgPresetDescription.Size = new System.Drawing.Size(70, 15);
|
||||
lblLgPresetDescription.TabIndex = 59;
|
||||
lblLgPresetDescription.Text = "Description:";
|
||||
//
|
||||
// btnLgDeviceOptionsHelp
|
||||
//
|
||||
btnLgDeviceOptionsHelp.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right;
|
||||
btnLgDeviceOptionsHelp.Location = new System.Drawing.Point(872, 70);
|
||||
btnLgDeviceOptionsHelp.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
btnLgDeviceOptionsHelp.Name = "btnLgDeviceOptionsHelp";
|
||||
btnLgDeviceOptionsHelp.Size = new System.Drawing.Size(22, 27);
|
||||
btnLgDeviceOptionsHelp.TabIndex = 58;
|
||||
btnLgDeviceOptionsHelp.Text = "?";
|
||||
btnLgDeviceOptionsHelp.UseVisualStyleBackColor = true;
|
||||
btnLgDeviceOptionsHelp.Click += btnLgDeviceOptionsHelp_Click;
|
||||
//
|
||||
// btnLgGameBar
|
||||
//
|
||||
btnLgGameBar.Location = new System.Drawing.Point(478, 40);
|
||||
btnLgGameBar.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
btnLgGameBar.Name = "btnLgGameBar";
|
||||
btnLgGameBar.Size = new System.Drawing.Size(88, 27);
|
||||
btnLgGameBar.TabIndex = 55;
|
||||
btnLgGameBar.Text = "Game Bar";
|
||||
btnLgGameBar.UseVisualStyleBackColor = true;
|
||||
btnLgGameBar.Click += btnLgGameBar_Click;
|
||||
//
|
||||
// btnLgPresetEditTriggerConditions
|
||||
//
|
||||
btnLgPresetEditTriggerConditions.Anchor = System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left;
|
||||
btnLgPresetEditTriggerConditions.Enabled = false;
|
||||
btnLgPresetEditTriggerConditions.Location = new System.Drawing.Point(804, 347);
|
||||
btnLgPresetEditTriggerConditions.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
btnLgPresetEditTriggerConditions.Name = "btnLgPresetEditTriggerConditions";
|
||||
btnLgPresetEditTriggerConditions.Size = new System.Drawing.Size(88, 27);
|
||||
btnLgPresetEditTriggerConditions.TabIndex = 54;
|
||||
btnLgPresetEditTriggerConditions.Text = "Edit...";
|
||||
btnLgPresetEditTriggerConditions.UseVisualStyleBackColor = true;
|
||||
btnLgPresetEditTriggerConditions.Click += btnLgPresetEditTriggerConditions_Click;
|
||||
//
|
||||
// edtLgPresetTriggerConditions
|
||||
//
|
||||
edtLgPresetTriggerConditions.Anchor = System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left;
|
||||
edtLgPresetTriggerConditions.Enabled = false;
|
||||
edtLgPresetTriggerConditions.Location = new System.Drawing.Point(601, 349);
|
||||
edtLgPresetTriggerConditions.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
edtLgPresetTriggerConditions.Name = "edtLgPresetTriggerConditions";
|
||||
edtLgPresetTriggerConditions.ReadOnly = true;
|
||||
edtLgPresetTriggerConditions.Size = new System.Drawing.Size(194, 23);
|
||||
edtLgPresetTriggerConditions.TabIndex = 53;
|
||||
//
|
||||
// lblLgPresetExcludedProcesses
|
||||
//
|
||||
lblLgPresetExcludedProcesses.Anchor = System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left;
|
||||
lblLgPresetExcludedProcesses.AutoSize = true;
|
||||
lblLgPresetExcludedProcesses.Location = new System.Drawing.Point(475, 414);
|
||||
lblLgPresetExcludedProcesses.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
|
||||
lblLgPresetExcludedProcesses.Name = "lblLgPresetExcludedProcesses";
|
||||
lblLgPresetExcludedProcesses.Size = new System.Drawing.Size(112, 15);
|
||||
lblLgPresetExcludedProcesses.TabIndex = 52;
|
||||
lblLgPresetExcludedProcesses.Text = "Excluded processes:";
|
||||
//
|
||||
// edtLgPresetExcludedProcesses
|
||||
//
|
||||
edtLgPresetExcludedProcesses.Anchor = System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left;
|
||||
edtLgPresetExcludedProcesses.Enabled = false;
|
||||
edtLgPresetExcludedProcesses.Location = new System.Drawing.Point(601, 411);
|
||||
edtLgPresetExcludedProcesses.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
edtLgPresetExcludedProcesses.Name = "edtLgPresetExcludedProcesses";
|
||||
edtLgPresetExcludedProcesses.Size = new System.Drawing.Size(289, 23);
|
||||
edtLgPresetExcludedProcesses.TabIndex = 51;
|
||||
//
|
||||
// lblLgPresetIncludedProcesses
|
||||
//
|
||||
lblLgPresetIncludedProcesses.Anchor = System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left;
|
||||
lblLgPresetIncludedProcesses.AutoSize = true;
|
||||
lblLgPresetIncludedProcesses.Location = new System.Drawing.Point(475, 384);
|
||||
lblLgPresetIncludedProcesses.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
|
||||
lblLgPresetIncludedProcesses.Name = "lblLgPresetIncludedProcesses";
|
||||
lblLgPresetIncludedProcesses.Size = new System.Drawing.Size(110, 15);
|
||||
lblLgPresetIncludedProcesses.TabIndex = 50;
|
||||
lblLgPresetIncludedProcesses.Text = "Included processes:";
|
||||
//
|
||||
// edtLgPresetIncludedProcesses
|
||||
//
|
||||
edtLgPresetIncludedProcesses.Anchor = System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left;
|
||||
edtLgPresetIncludedProcesses.Enabled = false;
|
||||
edtLgPresetIncludedProcesses.Location = new System.Drawing.Point(601, 381);
|
||||
edtLgPresetIncludedProcesses.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
edtLgPresetIncludedProcesses.Name = "edtLgPresetIncludedProcesses";
|
||||
edtLgPresetIncludedProcesses.Size = new System.Drawing.Size(289, 23);
|
||||
edtLgPresetIncludedProcesses.TabIndex = 49;
|
||||
//
|
||||
// lblLgPresetTriggerCondition
|
||||
//
|
||||
lblLgPresetTriggerCondition.Anchor = System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left;
|
||||
lblLgPresetTriggerCondition.AutoSize = true;
|
||||
lblLgPresetTriggerCondition.Location = new System.Drawing.Point(475, 353);
|
||||
lblLgPresetTriggerCondition.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
|
||||
lblLgPresetTriggerCondition.Name = "lblLgPresetTriggerCondition";
|
||||
lblLgPresetTriggerCondition.Size = new System.Drawing.Size(63, 15);
|
||||
lblLgPresetTriggerCondition.TabIndex = 47;
|
||||
lblLgPresetTriggerCondition.Text = "Condition:";
|
||||
//
|
||||
// cbxLgPresetTrigger
|
||||
//
|
||||
cbxLgPresetTrigger.Anchor = System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left;
|
||||
cbxLgPresetTrigger.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
|
||||
cbxLgPresetTrigger.Enabled = false;
|
||||
cbxLgPresetTrigger.FormattingEnabled = true;
|
||||
cbxLgPresetTrigger.Location = new System.Drawing.Point(601, 318);
|
||||
cbxLgPresetTrigger.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
cbxLgPresetTrigger.Name = "cbxLgPresetTrigger";
|
||||
cbxLgPresetTrigger.Size = new System.Drawing.Size(289, 23);
|
||||
cbxLgPresetTrigger.TabIndex = 46;
|
||||
//
|
||||
// lblLgPresetTrigger
|
||||
//
|
||||
lblLgPresetTrigger.Anchor = System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left;
|
||||
lblLgPresetTrigger.AutoSize = true;
|
||||
lblLgPresetTrigger.Location = new System.Drawing.Point(475, 321);
|
||||
lblLgPresetTrigger.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
|
||||
lblLgPresetTrigger.Name = "lblLgPresetTrigger";
|
||||
lblLgPresetTrigger.Size = new System.Drawing.Size(46, 15);
|
||||
lblLgPresetTrigger.TabIndex = 45;
|
||||
lblLgPresetTrigger.Text = "Trigger:";
|
||||
//
|
||||
// btnLgExpert
|
||||
//
|
||||
btnLgExpert.ContextMenuStrip = mnuLgExpert;
|
||||
btnLgExpert.Location = new System.Drawing.Point(368, 39);
|
||||
btnLgExpert.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
btnLgExpert.Name = "btnLgExpert";
|
||||
btnLgExpert.Size = new System.Drawing.Size(88, 27);
|
||||
btnLgExpert.TabIndex = 44;
|
||||
btnLgExpert.Text = "Expert...";
|
||||
btnLgExpert.UseVisualStyleBackColor = true;
|
||||
btnLgExpert.Click += btnLgExpert_Click;
|
||||
//
|
||||
// mnuLgExpert
|
||||
//
|
||||
mnuLgExpert.ImageScalingSize = new System.Drawing.Size(20, 20);
|
||||
mnuLgExpert.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { mnuLgOLEDMotionPro, mnuLgSetSvcMenuFlag, miLgExpertSeparator1 });
|
||||
mnuLgExpert.Name = "mnuLgButtons";
|
||||
mnuLgExpert.Size = new System.Drawing.Size(321, 76);
|
||||
mnuLgExpert.Opening += mnuLgExpert_Opening;
|
||||
//
|
||||
// mnuLgOLEDMotionPro
|
||||
//
|
||||
mnuLgOLEDMotionPro.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { miLgEnableMotionPro, miLgDisableMotionPro });
|
||||
mnuLgOLEDMotionPro.Name = "mnuLgOLEDMotionPro";
|
||||
mnuLgOLEDMotionPro.Size = new System.Drawing.Size(320, 22);
|
||||
mnuLgOLEDMotionPro.Text = "Activate OLED Motion Pro (B9/C9/E9/W9 only)";
|
||||
//
|
||||
// miLgEnableMotionPro
|
||||
//
|
||||
miLgEnableMotionPro.Name = "miLgEnableMotionPro";
|
||||
miLgEnableMotionPro.Size = new System.Drawing.Size(207, 22);
|
||||
miLgEnableMotionPro.Text = "Enable OLED Motion Pro";
|
||||
miLgEnableMotionPro.Click += miLgEnableMotionPro_Click;
|
||||
//
|
||||
// miLgDisableMotionPro
|
||||
//
|
||||
miLgDisableMotionPro.Name = "miLgDisableMotionPro";
|
||||
miLgDisableMotionPro.Size = new System.Drawing.Size(207, 22);
|
||||
miLgDisableMotionPro.Text = "Disable OLED Motion Pro";
|
||||
miLgDisableMotionPro.Click += miLgDisableMotionPro_Click;
|
||||
//
|
||||
// mnuLgSetSvcMenuFlag
|
||||
//
|
||||
mnuLgSetSvcMenuFlag.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { miLgFullServiceMenuEnable, miLgFullServiceMenuDisable });
|
||||
mnuLgSetSvcMenuFlag.Name = "mnuLgSetSvcMenuFlag";
|
||||
mnuLgSetSvcMenuFlag.Size = new System.Drawing.Size(320, 22);
|
||||
mnuLgSetSvcMenuFlag.Text = "Enable Full Service Menu (B3/C3/G3 only)";
|
||||
//
|
||||
// miLgFullServiceMenuEnable
|
||||
//
|
||||
miLgFullServiceMenuEnable.Name = "miLgFullServiceMenuEnable";
|
||||
miLgFullServiceMenuEnable.Size = new System.Drawing.Size(180, 22);
|
||||
miLgFullServiceMenuEnable.Text = "Enable";
|
||||
miLgFullServiceMenuEnable.Click += miLgFullServiceMenuEnable_Click;
|
||||
//
|
||||
// miLgFullServiceMenuDisable
|
||||
//
|
||||
miLgFullServiceMenuDisable.Name = "miLgFullServiceMenuDisable";
|
||||
miLgFullServiceMenuDisable.Size = new System.Drawing.Size(180, 22);
|
||||
miLgFullServiceMenuDisable.Text = "Disable";
|
||||
miLgFullServiceMenuDisable.Click += miLgFullServiceMenuDisable_Click;
|
||||
//
|
||||
// miLgExpertSeparator1
|
||||
//
|
||||
miLgExpertSeparator1.Name = "miLgExpertSeparator1";
|
||||
miLgExpertSeparator1.Size = new System.Drawing.Size(317, 6);
|
||||
//
|
||||
// chkLgRemoteControlShow
|
||||
//
|
||||
chkLgRemoteControlShow.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right;
|
||||
chkLgRemoteControlShow.Appearance = System.Windows.Forms.Appearance.Button;
|
||||
chkLgRemoteControlShow.AutoSize = true;
|
||||
chkLgRemoteControlShow.Location = new System.Drawing.Point(793, 8);
|
||||
chkLgRemoteControlShow.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
chkLgRemoteControlShow.Name = "chkLgRemoteControlShow";
|
||||
chkLgRemoteControlShow.Size = new System.Drawing.Size(101, 25);
|
||||
chkLgRemoteControlShow.TabIndex = 43;
|
||||
chkLgRemoteControlShow.Text = "Remote Control";
|
||||
chkLgRemoteControlShow.UseVisualStyleBackColor = true;
|
||||
chkLgRemoteControlShow.CheckedChanged += chkLgRemoteControlShow_CheckedChanged;
|
||||
//
|
||||
// label3
|
||||
//
|
||||
label3.AutoSize = true;
|
||||
label3.Location = new System.Drawing.Point(6, 14);
|
||||
label3.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
|
||||
label3.Name = "label3";
|
||||
label3.Size = new System.Drawing.Size(45, 15);
|
||||
label3.TabIndex = 31;
|
||||
label3.Text = "Device:";
|
||||
//
|
||||
// cbxLgDevices
|
||||
//
|
||||
cbxLgDevices.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
|
||||
cbxLgDevices.DropDownWidth = 400;
|
||||
cbxLgDevices.FormattingEnabled = true;
|
||||
cbxLgDevices.Location = new System.Drawing.Point(100, 9);
|
||||
cbxLgDevices.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
cbxLgDevices.Name = "cbxLgDevices";
|
||||
cbxLgDevices.Size = new System.Drawing.Size(370, 23);
|
||||
cbxLgDevices.TabIndex = 30;
|
||||
cbxLgDevices.SelectedIndexChanged += cbxLgDevices_SelectedIndexChanged;
|
||||
//
|
||||
// btnLgDeviceConvertToCustom
|
||||
//
|
||||
btnLgDeviceConvertToCustom.Location = new System.Drawing.Point(667, 8);
|
||||
btnLgDeviceConvertToCustom.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
btnLgDeviceConvertToCustom.Name = "btnLgDeviceConvertToCustom";
|
||||
btnLgDeviceConvertToCustom.Size = new System.Drawing.Size(88, 27);
|
||||
btnLgDeviceConvertToCustom.TabIndex = 41;
|
||||
btnLgDeviceConvertToCustom.Text = "To custom...";
|
||||
btnLgDeviceConvertToCustom.UseVisualStyleBackColor = true;
|
||||
btnLgDeviceConvertToCustom.Click += btnLgDeviceConvertToCustom_Click;
|
||||
//
|
||||
// cbxLgApps
|
||||
//
|
||||
cbxLgApps.Anchor = System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left;
|
||||
cbxLgApps.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
|
||||
cbxLgApps.Enabled = false;
|
||||
cbxLgApps.FormattingEnabled = true;
|
||||
cbxLgApps.Location = new System.Drawing.Point(100, 380);
|
||||
cbxLgApps.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
cbxLgApps.Name = "cbxLgApps";
|
||||
cbxLgApps.Size = new System.Drawing.Size(233, 23);
|
||||
cbxLgApps.TabIndex = 26;
|
||||
cbxLgApps.KeyPress += cbxLgApps_KeyPress;
|
||||
//
|
||||
// lvLgPresets
|
||||
//
|
||||
lvLgPresets.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right;
|
||||
lvLgPresets.CheckBoxes = true;
|
||||
lvLgPresets.FullRowSelect = true;
|
||||
lvLgPresets.Location = new System.Drawing.Point(6, 152);
|
||||
lvLgPresets.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
lvLgPresets.MultiSelect = false;
|
||||
lvLgPresets.Name = "lvLgPresets";
|
||||
lvLgPresets.ShowItemToolTips = true;
|
||||
lvLgPresets.Size = new System.Drawing.Size(888, 126);
|
||||
lvLgPresets.TabIndex = 8;
|
||||
lvLgPresets.UseCompatibleStateImageBehavior = false;
|
||||
lvLgPresets.View = System.Windows.Forms.View.Details;
|
||||
lvLgPresets.ColumnClick += lvLgPresets_ColumnClick;
|
||||
lvLgPresets.ItemChecked += lvLgPresets_ItemChecked;
|
||||
lvLgPresets.SelectedIndexChanged += lvLgPresets_SelectedIndexChanged;
|
||||
lvLgPresets.DoubleClick += lvLgPresets_DoubleClick;
|
||||
//
|
||||
// label5
|
||||
//
|
||||
label5.Anchor = System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left;
|
||||
label5.AutoSize = true;
|
||||
label5.Location = new System.Drawing.Point(6, 384);
|
||||
label5.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
|
||||
label5.Name = "label5";
|
||||
label5.Size = new System.Drawing.Size(32, 15);
|
||||
label5.TabIndex = 25;
|
||||
label5.Text = "App:";
|
||||
//
|
||||
// cbxLgPresetDevice
|
||||
//
|
||||
cbxLgPresetDevice.Anchor = System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left;
|
||||
cbxLgPresetDevice.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
|
||||
cbxLgPresetDevice.Enabled = false;
|
||||
cbxLgPresetDevice.FormattingEnabled = true;
|
||||
cbxLgPresetDevice.Location = new System.Drawing.Point(100, 348);
|
||||
cbxLgPresetDevice.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
cbxLgPresetDevice.Name = "cbxLgPresetDevice";
|
||||
cbxLgPresetDevice.Size = new System.Drawing.Size(370, 23);
|
||||
cbxLgPresetDevice.TabIndex = 40;
|
||||
//
|
||||
// btnDeleteLg
|
||||
//
|
||||
btnDeleteLg.Anchor = System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left;
|
||||
btnDeleteLg.Enabled = false;
|
||||
btnDeleteLg.Location = new System.Drawing.Point(289, 284);
|
||||
btnDeleteLg.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
btnDeleteLg.Name = "btnDeleteLg";
|
||||
btnDeleteLg.Size = new System.Drawing.Size(88, 27);
|
||||
btnDeleteLg.TabIndex = 27;
|
||||
btnDeleteLg.Text = "Delete";
|
||||
btnDeleteLg.UseVisualStyleBackColor = true;
|
||||
btnDeleteLg.Click += btnDeleteLg_Click;
|
||||
//
|
||||
// btnApplyLg
|
||||
//
|
||||
btnApplyLg.Anchor = System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left;
|
||||
btnApplyLg.Enabled = false;
|
||||
btnApplyLg.Location = new System.Drawing.Point(6, 284);
|
||||
btnApplyLg.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
btnApplyLg.Name = "btnApplyLg";
|
||||
btnApplyLg.Size = new System.Drawing.Size(88, 27);
|
||||
btnApplyLg.TabIndex = 9;
|
||||
btnApplyLg.Text = "Apply";
|
||||
btnApplyLg.UseVisualStyleBackColor = true;
|
||||
btnApplyLg.Click += btnApplyLg_Click;
|
||||
//
|
||||
// lblDeviceFilter
|
||||
//
|
||||
lblDeviceFilter.AutoSize = true;
|
||||
lblDeviceFilter.Location = new System.Drawing.Point(6, 45);
|
||||
lblDeviceFilter.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
|
||||
lblDeviceFilter.Name = "lblDeviceFilter";
|
||||
lblDeviceFilter.Size = new System.Drawing.Size(72, 15);
|
||||
lblDeviceFilter.TabIndex = 24;
|
||||
lblDeviceFilter.Text = "Device filter:";
|
||||
//
|
||||
// lblLgPresetDevice
|
||||
//
|
||||
lblLgPresetDevice.Anchor = System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left;
|
||||
lblLgPresetDevice.AutoSize = true;
|
||||
lblLgPresetDevice.Location = new System.Drawing.Point(6, 351);
|
||||
lblLgPresetDevice.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
|
||||
lblLgPresetDevice.Name = "lblLgPresetDevice";
|
||||
lblLgPresetDevice.Size = new System.Drawing.Size(45, 15);
|
||||
lblLgPresetDevice.TabIndex = 39;
|
||||
lblLgPresetDevice.Text = "Device:";
|
||||
//
|
||||
// btnAddLg
|
||||
//
|
||||
btnAddLg.Anchor = System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left;
|
||||
btnAddLg.Location = new System.Drawing.Point(195, 284);
|
||||
btnAddLg.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
btnAddLg.Name = "btnAddLg";
|
||||
btnAddLg.Size = new System.Drawing.Size(88, 27);
|
||||
btnAddLg.TabIndex = 28;
|
||||
btnAddLg.Text = "Add";
|
||||
btnAddLg.UseVisualStyleBackColor = true;
|
||||
btnAddLg.Click += btnAddLg_Click;
|
||||
//
|
||||
// edtShortcutLg
|
||||
//
|
||||
edtShortcutLg.Anchor = System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left;
|
||||
edtShortcutLg.Enabled = false;
|
||||
edtShortcutLg.Location = new System.Drawing.Point(100, 411);
|
||||
edtShortcutLg.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
edtShortcutLg.Name = "edtShortcutLg";
|
||||
edtShortcutLg.ReadOnly = true;
|
||||
edtShortcutLg.Size = new System.Drawing.Size(233, 23);
|
||||
edtShortcutLg.TabIndex = 11;
|
||||
edtShortcutLg.TextChanged += edtShortcutLg_TextChanged;
|
||||
edtShortcutLg.KeyDown += edtShortcut_KeyDown;
|
||||
edtShortcutLg.KeyUp += edtShortcut_KeyUp;
|
||||
//
|
||||
// edtLgDeviceFilter
|
||||
//
|
||||
edtLgDeviceFilter.Location = new System.Drawing.Point(100, 40);
|
||||
edtLgDeviceFilter.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
edtLgDeviceFilter.Name = "edtLgDeviceFilter";
|
||||
edtLgDeviceFilter.Size = new System.Drawing.Size(165, 23);
|
||||
edtLgDeviceFilter.TabIndex = 23;
|
||||
edtLgDeviceFilter.TextChanged += edtLgDeviceFilter_TextChanged;
|
||||
//
|
||||
// btnLgRemoveDevice
|
||||
//
|
||||
btnLgRemoveDevice.Location = new System.Drawing.Point(573, 8);
|
||||
btnLgRemoveDevice.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
btnLgRemoveDevice.Name = "btnLgRemoveDevice";
|
||||
btnLgRemoveDevice.Size = new System.Drawing.Size(88, 27);
|
||||
btnLgRemoveDevice.TabIndex = 38;
|
||||
btnLgRemoveDevice.Text = "Remove";
|
||||
btnLgRemoveDevice.UseVisualStyleBackColor = true;
|
||||
btnLgRemoveDevice.Click += btnLgRemoveDevice_Click;
|
||||
//
|
||||
// btnLgRefreshApps
|
||||
//
|
||||
btnLgRefreshApps.Anchor = System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left;
|
||||
btnLgRefreshApps.Enabled = false;
|
||||
btnLgRefreshApps.Location = new System.Drawing.Point(341, 378);
|
||||
btnLgRefreshApps.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
btnLgRefreshApps.Name = "btnLgRefreshApps";
|
||||
btnLgRefreshApps.Size = new System.Drawing.Size(88, 27);
|
||||
btnLgRefreshApps.TabIndex = 29;
|
||||
btnLgRefreshApps.Text = "Refresh";
|
||||
btnLgRefreshApps.UseVisualStyleBackColor = true;
|
||||
btnLgRefreshApps.Click += btnLgRefreshApps_Click;
|
||||
//
|
||||
// label2
|
||||
//
|
||||
label2.Anchor = System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left;
|
||||
label2.AutoSize = true;
|
||||
label2.Location = new System.Drawing.Point(6, 415);
|
||||
label2.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
|
||||
label2.Name = "label2";
|
||||
label2.Size = new System.Drawing.Size(55, 15);
|
||||
label2.TabIndex = 12;
|
||||
label2.Text = "Shortcut:";
|
||||
//
|
||||
// label1
|
||||
//
|
||||
label1.Anchor = System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left;
|
||||
label1.AutoSize = true;
|
||||
label1.Location = new System.Drawing.Point(6, 321);
|
||||
label1.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
|
||||
label1.Name = "label1";
|
||||
label1.Size = new System.Drawing.Size(42, 15);
|
||||
label1.TabIndex = 20;
|
||||
label1.Text = "Name:";
|
||||
//
|
||||
// btnLgAddDevice
|
||||
//
|
||||
btnLgAddDevice.Location = new System.Drawing.Point(478, 8);
|
||||
btnLgAddDevice.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
btnLgAddDevice.Name = "btnLgAddDevice";
|
||||
btnLgAddDevice.Size = new System.Drawing.Size(88, 27);
|
||||
btnLgAddDevice.TabIndex = 37;
|
||||
btnLgAddDevice.Text = "Add";
|
||||
btnLgAddDevice.UseVisualStyleBackColor = true;
|
||||
btnLgAddDevice.Click += btnLgAddDevice_Click;
|
||||
//
|
||||
// edtNameLg
|
||||
//
|
||||
edtNameLg.Anchor = System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left;
|
||||
edtNameLg.Enabled = false;
|
||||
edtNameLg.Location = new System.Drawing.Point(100, 318);
|
||||
edtNameLg.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
edtNameLg.Name = "edtNameLg";
|
||||
edtNameLg.Size = new System.Drawing.Size(233, 23);
|
||||
edtNameLg.TabIndex = 19;
|
||||
//
|
||||
// btnSetShortcutLg
|
||||
//
|
||||
btnSetShortcutLg.Anchor = System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left;
|
||||
btnSetShortcutLg.Enabled = false;
|
||||
btnSetShortcutLg.Location = new System.Drawing.Point(384, 284);
|
||||
btnSetShortcutLg.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
btnSetShortcutLg.Name = "btnSetShortcutLg";
|
||||
btnSetShortcutLg.Size = new System.Drawing.Size(88, 27);
|
||||
btnSetShortcutLg.TabIndex = 13;
|
||||
btnSetShortcutLg.Text = "Save";
|
||||
btnSetShortcutLg.UseVisualStyleBackColor = true;
|
||||
btnSetShortcutLg.Click += btnSetShortcutLg_Click;
|
||||
//
|
||||
// edtStepsLg
|
||||
//
|
||||
edtStepsLg.Anchor = System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right;
|
||||
edtStepsLg.Enabled = false;
|
||||
edtStepsLg.Location = new System.Drawing.Point(100, 440);
|
||||
edtStepsLg.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
edtStepsLg.Multiline = true;
|
||||
edtStepsLg.Name = "edtStepsLg";
|
||||
edtStepsLg.Size = new System.Drawing.Size(699, 43);
|
||||
edtStepsLg.TabIndex = 17;
|
||||
//
|
||||
// btnLgAddButton
|
||||
//
|
||||
btnLgAddButton.Anchor = System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right;
|
||||
btnLgAddButton.ContextMenuStrip = mnuLgButtons;
|
||||
btnLgAddButton.Enabled = false;
|
||||
btnLgAddButton.Location = new System.Drawing.Point(807, 439);
|
||||
btnLgAddButton.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
btnLgAddButton.Name = "btnLgAddButton";
|
||||
btnLgAddButton.Size = new System.Drawing.Size(88, 27);
|
||||
btnLgAddButton.TabIndex = 32;
|
||||
btnLgAddButton.Text = "Add step";
|
||||
btnLgAddButton.UseVisualStyleBackColor = true;
|
||||
btnLgAddButton.Click += btnLgAddButton_Click;
|
||||
//
|
||||
// mnuLgButtons
|
||||
//
|
||||
mnuLgButtons.ImageScalingSize = new System.Drawing.Size(20, 20);
|
||||
mnuLgButtons.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { mnuLgRcButtons, mnuLgActions, mnuLgNvPresets, mnuLgAmdPresets, mnuLgProgram });
|
||||
mnuLgButtons.Name = "mnuLgButtons";
|
||||
mnuLgButtons.Size = new System.Drawing.Size(153, 114);
|
||||
mnuLgButtons.Opening += mnuLgButtons_Opening;
|
||||
//
|
||||
// mnuLgRcButtons
|
||||
//
|
||||
mnuLgRcButtons.Name = "mnuLgRcButtons";
|
||||
mnuLgRcButtons.Size = new System.Drawing.Size(152, 22);
|
||||
mnuLgRcButtons.Text = "Buttons";
|
||||
//
|
||||
// mnuLgActions
|
||||
//
|
||||
mnuLgActions.Name = "mnuLgActions";
|
||||
mnuLgActions.Size = new System.Drawing.Size(152, 22);
|
||||
mnuLgActions.Text = "Actions";
|
||||
//
|
||||
// mnuLgNvPresets
|
||||
//
|
||||
mnuLgNvPresets.Name = "mnuLgNvPresets";
|
||||
mnuLgNvPresets.Size = new System.Drawing.Size(152, 22);
|
||||
mnuLgNvPresets.Text = "NVIDIA presets";
|
||||
//
|
||||
// mnuLgAmdPresets
|
||||
//
|
||||
mnuLgAmdPresets.Name = "mnuLgAmdPresets";
|
||||
mnuLgAmdPresets.Size = new System.Drawing.Size(152, 22);
|
||||
mnuLgAmdPresets.Text = "AMD presets";
|
||||
//
|
||||
// mnuLgProgram
|
||||
//
|
||||
mnuLgProgram.Name = "mnuLgProgram";
|
||||
mnuLgProgram.Size = new System.Drawing.Size(152, 22);
|
||||
mnuLgProgram.Text = "Start Program";
|
||||
mnuLgProgram.Click += mnuLgProgram_Click;
|
||||
//
|
||||
// btnCloneLg
|
||||
//
|
||||
btnCloneLg.Anchor = System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left;
|
||||
btnCloneLg.Enabled = false;
|
||||
btnCloneLg.Location = new System.Drawing.Point(100, 284);
|
||||
btnCloneLg.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
btnCloneLg.Name = "btnCloneLg";
|
||||
btnCloneLg.Size = new System.Drawing.Size(88, 27);
|
||||
btnCloneLg.TabIndex = 14;
|
||||
btnCloneLg.Text = "Clone";
|
||||
btnCloneLg.UseVisualStyleBackColor = true;
|
||||
btnCloneLg.Click += btnCloneLg_Click;
|
||||
//
|
||||
// lblStepsLg
|
||||
//
|
||||
lblStepsLg.Anchor = System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left;
|
||||
lblStepsLg.AutoSize = true;
|
||||
lblStepsLg.Location = new System.Drawing.Point(6, 445);
|
||||
lblStepsLg.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
|
||||
lblStepsLg.Name = "lblStepsLg";
|
||||
lblStepsLg.Size = new System.Drawing.Size(38, 15);
|
||||
lblStepsLg.TabIndex = 16;
|
||||
lblStepsLg.Text = "Steps:";
|
||||
//
|
||||
// btnLgDeviceFilterRefresh
|
||||
//
|
||||
btnLgDeviceFilterRefresh.Location = new System.Drawing.Point(273, 39);
|
||||
btnLgDeviceFilterRefresh.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
btnLgDeviceFilterRefresh.Name = "btnLgDeviceFilterRefresh";
|
||||
btnLgDeviceFilterRefresh.Size = new System.Drawing.Size(88, 27);
|
||||
btnLgDeviceFilterRefresh.TabIndex = 35;
|
||||
btnLgDeviceFilterRefresh.Text = "Refresh";
|
||||
btnLgDeviceFilterRefresh.UseVisualStyleBackColor = true;
|
||||
btnLgDeviceFilterRefresh.Click += btnLgDeviceFilterRefresh_Click;
|
||||
//
|
||||
// clbLgPower
|
||||
//
|
||||
clbLgPower.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right;
|
||||
clbLgPower.ColumnWidth = 240;
|
||||
clbLgPower.FormattingEnabled = true;
|
||||
clbLgPower.Items.AddRange(new object[] { "Power on after startup", "Power on after resume from standby", "Power off on shutdown", "Power off on standby", "Power off when screensaver activates", "Power on when screensaver deactivates", "Power on even after manual power off", "Allow triggers to be fired for this device", "Use Windows power settings to power on", "Use Windows power settings to power off", "Use secure connection" });
|
||||
clbLgPower.Location = new System.Drawing.Point(6, 70);
|
||||
clbLgPower.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
clbLgPower.MultiColumn = true;
|
||||
clbLgPower.Name = "clbLgPower";
|
||||
clbLgPower.Size = new System.Drawing.Size(861, 76);
|
||||
clbLgPower.TabIndex = 34;
|
||||
clbLgPower.ItemCheck += clbLgPower_ItemCheck;
|
||||
clbLgPower.SelectedIndexChanged += clbLgPower_SelectedIndexChanged;
|
||||
//
|
||||
// lblLgError
|
||||
//
|
||||
lblLgError.AutoSize = true;
|
||||
lblLgError.Location = new System.Drawing.Point(6, 9);
|
||||
lblLgError.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
|
||||
lblLgError.Name = "lblLgError";
|
||||
lblLgError.Size = new System.Drawing.Size(53, 15);
|
||||
lblLgError.TabIndex = 15;
|
||||
lblLgError.Text = "ErrorText";
|
||||
lblLgError.Visible = false;
|
||||
//
|
||||
// mnuLgSettings
|
||||
//
|
||||
mnuLgSettings.ImageScalingSize = new System.Drawing.Size(20, 20);
|
||||
mnuLgSettings.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { miTestPowerOffOn, miNvSettings });
|
||||
mnuLgSettings.Name = "mnuLgButtons";
|
||||
mnuLgSettings.Size = new System.Drawing.Size(168, 48);
|
||||
//
|
||||
// miTestPowerOffOn
|
||||
//
|
||||
miTestPowerOffOn.Name = "miTestPowerOffOn";
|
||||
miTestPowerOffOn.Size = new System.Drawing.Size(167, 22);
|
||||
miTestPowerOffOn.Text = "Test power off/on";
|
||||
miTestPowerOffOn.Click += miTestPowerOffOn_Click;
|
||||
//
|
||||
// miNvSettings
|
||||
//
|
||||
miNvSettings.Name = "miNvSettings";
|
||||
miNvSettings.Size = new System.Drawing.Size(167, 22);
|
||||
miNvSettings.Text = "Settings";
|
||||
miNvSettings.Click += miNvSettings_Click;
|
||||
//
|
||||
// LgPanel
|
||||
//
|
||||
AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
|
||||
AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
Controls.Add(scLgController);
|
||||
Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
Name = "LgPanel";
|
||||
Size = new System.Drawing.Size(1114, 539);
|
||||
scLgController.Panel1.ResumeLayout(false);
|
||||
scLgController.Panel1.PerformLayout();
|
||||
((System.ComponentModel.ISupportInitialize)scLgController).EndInit();
|
||||
scLgController.ResumeLayout(false);
|
||||
mnuLgExpert.ResumeLayout(false);
|
||||
mnuLgButtons.ResumeLayout(false);
|
||||
mnuLgSettings.ResumeLayout(false);
|
||||
ResumeLayout(false);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuLgRcButtons;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuLgActions;
|
||||
private System.Windows.Forms.ContextMenuStrip mnuLgButtons;
|
||||
private System.Windows.Forms.SplitContainer scLgController;
|
||||
private System.Windows.Forms.Label label3;
|
||||
private System.Windows.Forms.ComboBox cbxLgDevices;
|
||||
private System.Windows.Forms.Button btnLgDeviceConvertToCustom;
|
||||
private System.Windows.Forms.ComboBox cbxLgApps;
|
||||
private System.Windows.Forms.ListView lvLgPresets;
|
||||
private System.Windows.Forms.Label label5;
|
||||
private System.Windows.Forms.ComboBox cbxLgPresetDevice;
|
||||
private System.Windows.Forms.Button btnDeleteLg;
|
||||
private System.Windows.Forms.Button btnApplyLg;
|
||||
private System.Windows.Forms.Label lblDeviceFilter;
|
||||
private System.Windows.Forms.Label lblLgPresetDevice;
|
||||
private System.Windows.Forms.Button btnAddLg;
|
||||
private System.Windows.Forms.TextBox edtShortcutLg;
|
||||
private System.Windows.Forms.TextBox edtLgDeviceFilter;
|
||||
private System.Windows.Forms.Button btnLgRemoveDevice;
|
||||
private System.Windows.Forms.Button btnLgRefreshApps;
|
||||
private System.Windows.Forms.Label label2;
|
||||
private System.Windows.Forms.Label label1;
|
||||
private System.Windows.Forms.Button btnLgAddDevice;
|
||||
private System.Windows.Forms.TextBox edtNameLg;
|
||||
private System.Windows.Forms.Button btnSetShortcutLg;
|
||||
private System.Windows.Forms.TextBox edtStepsLg;
|
||||
private System.Windows.Forms.Button btnLgAddButton;
|
||||
private System.Windows.Forms.Button btnCloneLg;
|
||||
private System.Windows.Forms.Label lblStepsLg;
|
||||
private System.Windows.Forms.Button btnLgDeviceFilterRefresh;
|
||||
private System.Windows.Forms.CheckedListBox clbLgPower;
|
||||
private System.Windows.Forms.Label lblLgError;
|
||||
private System.Windows.Forms.CheckBox chkLgRemoteControlShow;
|
||||
private System.Windows.Forms.Button btnLgExpert;
|
||||
private System.Windows.Forms.ContextMenuStrip mnuLgExpert;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuLgOLEDMotionPro;
|
||||
private System.Windows.Forms.ToolStripMenuItem miLgEnableMotionPro;
|
||||
private System.Windows.Forms.ToolStripMenuItem miLgDisableMotionPro;
|
||||
private System.Windows.Forms.ToolStripSeparator miLgExpertSeparator1;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuLgNvPresets;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuLgAmdPresets;
|
||||
private System.Windows.Forms.ComboBox cbxLgPresetTrigger;
|
||||
private System.Windows.Forms.Label lblLgPresetTrigger;
|
||||
private System.Windows.Forms.Label lblLgPresetTriggerCondition;
|
||||
private System.Windows.Forms.Label lblLgPresetExcludedProcesses;
|
||||
private System.Windows.Forms.TextBox edtLgPresetExcludedProcesses;
|
||||
private System.Windows.Forms.Label lblLgPresetIncludedProcesses;
|
||||
private System.Windows.Forms.TextBox edtLgPresetIncludedProcesses;
|
||||
private System.Windows.Forms.Button btnLgPresetEditTriggerConditions;
|
||||
private System.Windows.Forms.TextBox edtLgPresetTriggerConditions;
|
||||
private System.Windows.Forms.Button btnLgGameBar;
|
||||
private System.Windows.Forms.Button btnLgDeviceOptionsHelp;
|
||||
private System.Windows.Forms.TextBox edtLgPresetDescription;
|
||||
private System.Windows.Forms.Label lblLgPresetDescription;
|
||||
private System.Windows.Forms.ComboBox cbxLgPcHdmiPort;
|
||||
private System.Windows.Forms.Label lblLgPcHdmiPort;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuLgProgram;
|
||||
private System.Windows.Forms.CheckBox chkLgQuickAccess;
|
||||
private System.Windows.Forms.Button btnLgSettings;
|
||||
private System.Windows.Forms.ContextMenuStrip mnuLgSettings;
|
||||
private System.Windows.Forms.ToolStripMenuItem miTestPowerOffOn;
|
||||
private System.Windows.Forms.ToolStripMenuItem miNvSettings;
|
||||
private System.Windows.Forms.Button btnLgDeviceOptionsSettings;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuLgSetSvcMenuFlag;
|
||||
private System.Windows.Forms.ToolStripMenuItem miLgFullServiceMenuEnable;
|
||||
private System.Windows.Forms.ToolStripMenuItem miLgFullServiceMenuDisable;
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,129 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<metadata name="mnuLgExpert.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>17, 17</value>
|
||||
</metadata>
|
||||
<metadata name="mnuLgButtons.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>288, 16</value>
|
||||
</metadata>
|
||||
<metadata name="mnuLgSettings.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>147, 17</value>
|
||||
</metadata>
|
||||
</root>
|
||||
@@ -0,0 +1,118 @@
|
||||
using ColorControl.Services.Common;
|
||||
using ColorControl.Shared.Contracts;
|
||||
using LgTv;
|
||||
using Newtonsoft.Json;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace ColorControl.Services.LG
|
||||
{
|
||||
class LgPreset : PresetBase
|
||||
{
|
||||
public static List<LgApp> LgApps { get; set; }
|
||||
public static List<LgDevice> LgDevices { get; set; }
|
||||
public string appId { get; set; }
|
||||
public List<string> steps { get; set; }
|
||||
public string DeviceMacAddress { get; set; }
|
||||
public dynamic AppParams { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
public int X { get; set; }
|
||||
[JsonIgnore]
|
||||
public int Y { get; set; }
|
||||
|
||||
public LgPreset() : base()
|
||||
{
|
||||
steps = new List<string>();
|
||||
}
|
||||
|
||||
public LgPreset(LgPreset preset) : this()
|
||||
{
|
||||
id = GetNewId();
|
||||
name = preset.name + " (copy)";
|
||||
appId = preset.appId;
|
||||
|
||||
foreach (var step in preset.steps)
|
||||
{
|
||||
steps.Add(step);
|
||||
}
|
||||
}
|
||||
|
||||
public LgPreset(string name, string appId, IEnumerable<string> steps = null, dynamic appParams = null) : this()
|
||||
{
|
||||
this.name = name;
|
||||
this.appId = appId;
|
||||
if (steps != null)
|
||||
{
|
||||
this.steps.AddRange(steps);
|
||||
}
|
||||
AppParams = appParams;
|
||||
}
|
||||
|
||||
public LgPreset Clone()
|
||||
{
|
||||
var preset = new LgPreset(this);
|
||||
|
||||
return preset;
|
||||
}
|
||||
|
||||
public static List<string> GetColumnNames()
|
||||
{
|
||||
return new List<string>() { "Name", "Device|140", "App|200", "Steps|400", "Shortcut", "Trigger" };
|
||||
}
|
||||
|
||||
public override List<string> GetDisplayValues(Config config = null)
|
||||
{
|
||||
var values = new List<string>();
|
||||
|
||||
values.Add(name);
|
||||
|
||||
var deviceString = "Global";
|
||||
if (!string.IsNullOrEmpty(DeviceMacAddress))
|
||||
{
|
||||
if (LgDevices != null)
|
||||
{
|
||||
var device = LgDevices.FirstOrDefault(d => !string.IsNullOrEmpty(d.MacAddress) && d.MacAddress.Equals(DeviceMacAddress));
|
||||
if (device != null)
|
||||
{
|
||||
deviceString = device.Name;
|
||||
}
|
||||
else
|
||||
{
|
||||
deviceString = "Unknown: device not found";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
deviceString = DeviceMacAddress;
|
||||
}
|
||||
}
|
||||
values.Add(deviceString);
|
||||
|
||||
var app = appId;
|
||||
if (LgApps != null)
|
||||
{
|
||||
var item = LgApps.FirstOrDefault(x => x.appId.Equals(appId));
|
||||
if (item != null)
|
||||
{
|
||||
app = item.title + " (" + appId + ")";
|
||||
}
|
||||
}
|
||||
values.Add(app);
|
||||
values.Add(GetStepsDisplay());
|
||||
values.Add(shortcut);
|
||||
|
||||
if (Triggers.Any())
|
||||
{
|
||||
values.Add(Triggers.First().ToString());
|
||||
}
|
||||
|
||||
return values;
|
||||
}
|
||||
|
||||
public string GetStepsDisplay()
|
||||
{
|
||||
return steps.Aggregate("", (a, b) => (string.IsNullOrEmpty(a) ? "" : a + ", ") + b);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,928 @@
|
||||
using ColorControl.Services.Common;
|
||||
using ColorControl.Services.EventDispatcher;
|
||||
using ColorControl.Shared.Common;
|
||||
using ColorControl.Shared.Contracts;
|
||||
using ColorControl.Shared.Native;
|
||||
using ColorControl.Shared.Services;
|
||||
using LgTv;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Win32;
|
||||
using Newtonsoft.Json;
|
||||
using NWin32;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace ColorControl.Services.LG
|
||||
{
|
||||
class LgService : ServiceBase<LgPreset>
|
||||
{
|
||||
protected static readonly NLog.Logger Logger = NLog.LogManager.GetCurrentClassLogger();
|
||||
|
||||
public static string LgListAppsJson = "listApps.json";
|
||||
|
||||
public override string ServiceName => "LG";
|
||||
|
||||
public List<LgDevice> Devices { get; private set; }
|
||||
public LgDevice SelectedDevice
|
||||
{
|
||||
get { return _selectedDevice; }
|
||||
set
|
||||
{
|
||||
_selectedDevice = value;
|
||||
Config.PreferredMacAddress = _selectedDevice != null ? _selectedDevice.MacAddress : null;
|
||||
|
||||
SelectedDeviceChangedEvent?.Invoke(_selectedDevice, EventArgs.Empty);
|
||||
}
|
||||
}
|
||||
public event EventHandler SelectedDeviceChangedEvent;
|
||||
|
||||
public LgServiceConfig Config { get; private set; }
|
||||
|
||||
protected override string PresetsBaseFilename => "LgPresets.json";
|
||||
|
||||
private string _configFilename;
|
||||
private bool _allowPowerOn;
|
||||
private readonly PowerEventDispatcher _powerEventDispatcher;
|
||||
private readonly SessionSwitchDispatcher _sessionSwitchDispatcher;
|
||||
private readonly ProcessEventDispatcher _processEventDispatcher;
|
||||
private readonly ServiceManager _serviceManager;
|
||||
private LgDevice _selectedDevice;
|
||||
private string _rcButtonsFilename;
|
||||
private List<LgPreset> _remoteControlButtons;
|
||||
private List<LgApp> _lgApps = new List<LgApp>();
|
||||
|
||||
private bool _poweredOffByScreenSaver;
|
||||
private int _poweredOffByScreenSaverProcessId;
|
||||
private LgPreset _lastTriggeredPreset;
|
||||
private RestartDetector _restartDetector;
|
||||
private readonly WinApiService _winApiService;
|
||||
private readonly WinApiAdminService _winApiAdminService;
|
||||
private SynchronizationContext _syncContext;
|
||||
|
||||
public ProcessChangedEventArgs CurrentProcessEvent => _processEventDispatcher?.MonitorContext;
|
||||
|
||||
public LgService(AppContextProvider appContextProvider, PowerEventDispatcher powerEventDispatcher, SessionSwitchDispatcher sessionSwitchDispatcher, ProcessEventDispatcher processEventDispatcher, ServiceManager serviceManager, RestartDetector restartDetector, WinApiService winApiService, WinApiAdminService winApiAdminService) : base(appContextProvider)
|
||||
{
|
||||
_allowPowerOn = appContextProvider.GetAppContext().StartUpParams.RunningFromScheduledTask;
|
||||
_powerEventDispatcher = powerEventDispatcher;
|
||||
_sessionSwitchDispatcher = sessionSwitchDispatcher;
|
||||
_processEventDispatcher = processEventDispatcher;
|
||||
_serviceManager = serviceManager;
|
||||
LgPreset.LgApps = _lgApps;
|
||||
|
||||
_restartDetector = restartDetector;
|
||||
_winApiService = winApiService;
|
||||
_winApiAdminService = winApiAdminService;
|
||||
_syncContext = appContextProvider.GetAppContext().SynchronizationContext;
|
||||
LgTvApiCore.SyncContext = _syncContext;
|
||||
|
||||
LoadConfig();
|
||||
LoadPresets();
|
||||
LoadRemoteControlButtons();
|
||||
}
|
||||
|
||||
~LgService()
|
||||
{
|
||||
GlobalSave();
|
||||
}
|
||||
|
||||
public static async Task<bool> ExecutePresetAsync(string presetName)
|
||||
{
|
||||
try
|
||||
{
|
||||
var lgService = Program.ServiceProvider.GetRequiredService<LgService>();
|
||||
|
||||
await lgService.RefreshDevices(afterStartUp: true);
|
||||
|
||||
var result = await lgService.ApplyPreset(presetName);
|
||||
|
||||
if (!result)
|
||||
{
|
||||
Console.WriteLine("Preset not found or error while executing.");
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine("Error executing preset: " + ex.ToLogString());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public void GlobalSave()
|
||||
{
|
||||
SaveConfig();
|
||||
SavePresets();
|
||||
SaveRemoteControlButtons();
|
||||
|
||||
SendConfigToService();
|
||||
}
|
||||
|
||||
protected override List<LgPreset> GetDefaultPresets()
|
||||
{
|
||||
List<LgPreset> presets = null;
|
||||
|
||||
var defaultPresetsFileName = Path.Combine(Directory.GetCurrentDirectory(), "LgPresets.json");
|
||||
if (File.Exists(defaultPresetsFileName))
|
||||
{
|
||||
var json = File.ReadAllText(defaultPresetsFileName);
|
||||
|
||||
presets = JsonConvert.DeserializeObject<List<LgPreset>>(json);
|
||||
}
|
||||
|
||||
return presets;
|
||||
}
|
||||
|
||||
private void LoadConfig()
|
||||
{
|
||||
_configFilename = Path.Combine(_dataPath, "LgConfig.json");
|
||||
try
|
||||
{
|
||||
if (File.Exists(_configFilename))
|
||||
{
|
||||
Config = JsonConvert.DeserializeObject<LgServiceConfig>(File.ReadAllText(_configFilename));
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Error($"LoadConfig: {ex.Message}");
|
||||
}
|
||||
Config ??= new LgServiceConfig();
|
||||
|
||||
LgPreset.LgDevices = Config.Devices;
|
||||
}
|
||||
|
||||
private void LoadRemoteControlButtons()
|
||||
{
|
||||
var defaultButtons = GenerateDefaultRemoteControlButtons();
|
||||
|
||||
_rcButtonsFilename = Path.Combine(_dataPath, "LgRemoteControlButtons.json");
|
||||
//if (File.Exists(_rcButtonsFilename))
|
||||
//{
|
||||
// var json = File.ReadAllText(_rcButtonsFilename);
|
||||
|
||||
// _remoteControlButtons = _JsonDeserializer.Deserialize<List<LgPreset>>(json);
|
||||
|
||||
// var missingButtons = defaultButtons.Where(b => !_remoteControlButtons.Any(x => x.name.Equals(b.name)));
|
||||
// _remoteControlButtons.AddRange(missingButtons);
|
||||
//}
|
||||
//else
|
||||
{
|
||||
_remoteControlButtons = defaultButtons;
|
||||
}
|
||||
}
|
||||
|
||||
public List<LgPreset> GetRemoteControlButtons()
|
||||
{
|
||||
return _remoteControlButtons;
|
||||
}
|
||||
|
||||
private List<LgPreset> GenerateDefaultRemoteControlButtons()
|
||||
{
|
||||
var list = new List<LgPreset>();
|
||||
|
||||
for (var i = 1; i < 11; i++)
|
||||
{
|
||||
var button = i < 10 ? i : 0;
|
||||
list.Add(GeneratePreset(button.ToString()));
|
||||
}
|
||||
|
||||
list.Add(GeneratePreset("Power", step: "POWER"));
|
||||
list.Add(GeneratePreset("Wol", step: "WOL"));
|
||||
list.Add(GeneratePreset("Home", appId: "com.webos.app.home", key: Keys.H));
|
||||
list.Add(GeneratePreset("Settings", appId: "com.palm.app.settings", key: Keys.S));
|
||||
list.Add(GeneratePreset("TV Guide", appId: "com.webos.app.livemenu"));
|
||||
list.Add(GeneratePreset("List", step: "LIST"));
|
||||
list.Add(GeneratePreset("SAP", step: "SAP"));
|
||||
|
||||
list.Add(GeneratePreset("Vol +", step: "VOLUMEUP", key: Keys.VolumeUp));
|
||||
list.Add(GeneratePreset("Vol -", step: "VOLUMEDOWN", key: Keys.VolumeDown));
|
||||
list.Add(GeneratePreset("Mute", step: "MUTE", key: Keys.VolumeMute));
|
||||
list.Add(GeneratePreset("Channel +", step: "CHANNELUP", key: Keys.MediaNextTrack));
|
||||
list.Add(GeneratePreset("Channel -", step: "CHANNELDOWN", key: Keys.MediaPreviousTrack));
|
||||
|
||||
list.Add(GeneratePreset("Up", step: "UP", key: Keys.Up));
|
||||
list.Add(GeneratePreset("Down", step: "DOWN", key: Keys.Down));
|
||||
list.Add(GeneratePreset("Left", step: "LEFT", key: Keys.Left));
|
||||
list.Add(GeneratePreset("Right", step: "RIGHT", key: Keys.Right));
|
||||
|
||||
list.Add(GeneratePreset("Enter", step: "ENTER", key: Keys.Enter));
|
||||
list.Add(GeneratePreset("Back", step: "BACK", key: Keys.Back));
|
||||
list.Add(GeneratePreset("Exit", step: "EXIT", key: Keys.Escape));
|
||||
|
||||
list.Add(GeneratePreset("Netflix", appId: "netflix"));
|
||||
list.Add(GeneratePreset("Inputs", appId: "com.webos.app.homeconnect"));
|
||||
list.Add(GeneratePreset("Amazon Prime", appId: "amazon"));
|
||||
|
||||
list.Add(GeneratePreset("Red", step: "RED"));
|
||||
list.Add(GeneratePreset("Green", step: "GREEN"));
|
||||
list.Add(GeneratePreset("Yellow", step: "YELLOW"));
|
||||
list.Add(GeneratePreset("Blue", step: "BLUE"));
|
||||
|
||||
list.Add(GeneratePreset("Rakuten TV", appId: "ui30"));
|
||||
list.Add(GeneratePreset("Play", step: "PLAY"));
|
||||
list.Add(GeneratePreset("Pause", step: "PAUSE"));
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
private LgPreset GeneratePreset(string name, string step = null, string appId = null, Keys key = Keys.None)
|
||||
{
|
||||
var preset = new LgPreset();
|
||||
|
||||
var cvt = new KeysConverter();
|
||||
var shortcut = key != Keys.None ? (string)cvt.ConvertTo(key, typeof(string)) : null;
|
||||
|
||||
preset.name = name;
|
||||
preset.appId = appId;
|
||||
preset.shortcut = shortcut;
|
||||
if (appId == null)
|
||||
{
|
||||
preset.steps.Add(step == null ? name : step);
|
||||
}
|
||||
|
||||
return preset;
|
||||
}
|
||||
|
||||
private void SavePresets()
|
||||
{
|
||||
Utils.WriteObject(_presetsFilename, _presets);
|
||||
}
|
||||
|
||||
private void SaveConfig()
|
||||
{
|
||||
Config.PowerOnAfterStartup = Devices?.Any(d => d.PowerOnAfterStartup) ?? false;
|
||||
|
||||
Utils.WriteObject(_configFilename, Config);
|
||||
}
|
||||
|
||||
private void SaveRemoteControlButtons()
|
||||
{
|
||||
Utils.WriteObject(_rcButtonsFilename, _remoteControlButtons);
|
||||
}
|
||||
|
||||
public async Task RefreshDevices(bool connect = true, bool afterStartUp = false)
|
||||
{
|
||||
Devices = Config.Devices;
|
||||
|
||||
if (!_appContextProvider.GetAppContext().StartUpParams.NoDeviceRefresh)
|
||||
{
|
||||
var customIpAddresses = Devices.Where(d => d.IsCustom).Select(d => d.IpAddress);
|
||||
|
||||
var pnpDevices = await Utils.GetPnpDevices(Config.DeviceSearchKey);
|
||||
|
||||
var autoDevices = pnpDevices.Where(p => !customIpAddresses.Contains(p.IpAddress)).Select(d => new LgDevice(d.Name, d.IpAddress, d.MacAddress, false)).ToList();
|
||||
var autoIpAddresses = pnpDevices.Select(d => d.IpAddress);
|
||||
|
||||
Devices.RemoveAll(d => !d.IsCustom && !autoIpAddresses.Contains(d.IpAddress));
|
||||
|
||||
var newAutoDevices = autoDevices.Where(ad => ad.IpAddress != null && !Devices.Any(d => d.IpAddress != null && d.IpAddress.Equals(ad.IpAddress)));
|
||||
Devices.AddRange(newAutoDevices);
|
||||
}
|
||||
|
||||
if (Devices.Any())
|
||||
{
|
||||
var preferredDevice = Devices.FirstOrDefault(x => x.MacAddress != null && x.MacAddress.Equals(Config.PreferredMacAddress)) ?? Devices[0];
|
||||
|
||||
SelectedDevice = preferredDevice;
|
||||
}
|
||||
else
|
||||
{
|
||||
SelectedDevice = null;
|
||||
}
|
||||
|
||||
if (afterStartUp && SelectedDevice == null && Config.PowerOnAfterStartup && !string.IsNullOrEmpty(Config.PreferredMacAddress))
|
||||
{
|
||||
Logger.Debug("No device has been found, trying to wake it first...");
|
||||
|
||||
var tempDevice = new LgDevice("Test", string.Empty, Config.PreferredMacAddress);
|
||||
tempDevice.Wake();
|
||||
|
||||
await Task.Delay(4000);
|
||||
await RefreshDevices();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var device in Devices)
|
||||
{
|
||||
device.PowerStateChangedEvent += LgDevice_PowerStateChangedEvent;
|
||||
device.PictureSettingsChangedEvent += Device_PictureSettingsChangedEvent;
|
||||
}
|
||||
|
||||
if (connect && SelectedDevice != null)
|
||||
{
|
||||
if (_allowPowerOn)
|
||||
{
|
||||
WakeAfterStartupOrResume();
|
||||
}
|
||||
else
|
||||
{
|
||||
var _ = SelectedDevice.Connect();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void Device_PictureSettingsChangedEvent(object sender, EventArgs e)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
public async Task<bool> ApplyPreset(string presetName)
|
||||
{
|
||||
var preset = _presets.FirstOrDefault(p => p.name.Equals(presetName, StringComparison.OrdinalIgnoreCase));
|
||||
if (preset != null)
|
||||
{
|
||||
return await ApplyPreset(preset);
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public override async Task<bool> ApplyPreset(LgPreset preset)
|
||||
{
|
||||
return await ApplyPreset(preset, false);
|
||||
}
|
||||
|
||||
public async Task<bool> ApplyPreset(LgPreset preset, bool reconnect = false)
|
||||
{
|
||||
var device = GetPresetDevice(preset);
|
||||
|
||||
if (device == null)
|
||||
{
|
||||
Logger.Debug("Cannot apply preset: no device has been selected");
|
||||
return false;
|
||||
}
|
||||
|
||||
var result = await device.ExecutePreset(preset, reconnect, Config);
|
||||
|
||||
_lastAppliedPreset = preset;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public LgDevice GetPresetDevice(LgPreset preset)
|
||||
{
|
||||
var device = string.IsNullOrEmpty(preset.DeviceMacAddress)
|
||||
? SelectedDevice
|
||||
: Devices.FirstOrDefault(d => d.MacAddress?.Equals(preset.DeviceMacAddress, StringComparison.OrdinalIgnoreCase) ?? false);
|
||||
return device;
|
||||
}
|
||||
|
||||
public async Task<LgWebOsMouseService> GetMouseAsync()
|
||||
{
|
||||
return await SelectedDevice?.GetMouseAsync();
|
||||
}
|
||||
|
||||
public async Task RefreshApps(bool force = false)
|
||||
{
|
||||
if (SelectedDevice == null)
|
||||
{
|
||||
Logger.Debug("Cannot refresh apps: no device has been selected");
|
||||
return;
|
||||
}
|
||||
|
||||
var apps = await SelectedDevice.GetApps(force);
|
||||
|
||||
if (apps.Any())
|
||||
{
|
||||
_lgApps.Clear();
|
||||
_lgApps.AddRange(apps);
|
||||
}
|
||||
}
|
||||
|
||||
public List<LgApp> GetApps()
|
||||
{
|
||||
return _lgApps;
|
||||
}
|
||||
|
||||
internal async Task<bool> PowerOff()
|
||||
{
|
||||
return await SelectedDevice?.PowerOff();
|
||||
}
|
||||
|
||||
internal bool WakeSelectedDevice()
|
||||
{
|
||||
return SelectedDevice?.Wake() ?? false;
|
||||
}
|
||||
|
||||
internal void WakeAfterStartupOrResume(PowerOnOffState state = PowerOnOffState.StartUp, bool checkUserSession = true)
|
||||
{
|
||||
Devices.ForEach(d => d.ClearPowerOffTask());
|
||||
|
||||
var wakeDevices = Devices.Where(d => state == PowerOnOffState.StartUp && d.PowerOnAfterStartup ||
|
||||
state == PowerOnOffState.Resume && d.PowerOnAfterResume ||
|
||||
state == PowerOnOffState.ScreenSaver && d.PowerOnAfterScreenSaver);
|
||||
|
||||
PowerOnDevicesTask(wakeDevices, state, checkUserSession);
|
||||
}
|
||||
|
||||
public void InstallEventHandlers()
|
||||
{
|
||||
_powerEventDispatcher.RegisterEventHandler(PowerEventDispatcher.Event_Suspend, PowerModeChanged);
|
||||
_powerEventDispatcher.RegisterEventHandler(PowerEventDispatcher.Event_Resume, PowerModeChanged);
|
||||
_powerEventDispatcher.RegisterEventHandler(PowerEventDispatcher.Event_Shutdown, PowerModeChanged);
|
||||
_powerEventDispatcher.RegisterEventHandler(PowerEventDispatcher.Event_MonitorOff, PowerModeChanged);
|
||||
_powerEventDispatcher.RegisterEventHandler(PowerEventDispatcher.Event_MonitorOn, PowerModeChanged);
|
||||
|
||||
//SystemEvents.SessionEnded -= SessionEnded;
|
||||
//SystemEvents.SessionEnded += SessionEnded;
|
||||
|
||||
_sessionSwitchDispatcher.RegisterEventHandler(SessionSwitchDispatcher.Event_SessionSwitch, SessionSwitched);
|
||||
|
||||
_processEventDispatcher.RegisterAsyncEventHandler(ProcessEventDispatcher.Event_ProcessChanged, ProcessChanged);
|
||||
}
|
||||
|
||||
private void SessionSwitched(object sender, SessionSwitchEventArgs e)
|
||||
{
|
||||
if (!_sessionSwitchDispatcher.UserLocalSession)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (_poweredOffByScreenSaver)
|
||||
{
|
||||
Logger.Debug("User switched to local and screen was powered off due to screensaver: waking up");
|
||||
_poweredOffByScreenSaver = false;
|
||||
_poweredOffByScreenSaverProcessId = 0;
|
||||
WakeAfterStartupOrResume();
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger.Debug("User switched to local but screen was not powered off by screensaver: NOT waking up");
|
||||
}
|
||||
}
|
||||
|
||||
private void PowerModeChanged(object sender, PowerStateChangedEventArgs e)
|
||||
{
|
||||
Logger.Debug($"PowerModeChanged: {e.State}");
|
||||
|
||||
switch (e.State)
|
||||
{
|
||||
case PowerOnOffState.Resume:
|
||||
{
|
||||
WakeAfterStartupOrResume(PowerOnOffState.Resume);
|
||||
break;
|
||||
}
|
||||
case PowerOnOffState.StandBy:
|
||||
{
|
||||
var devices = Devices.Where(d => d.PowerOffOnStandby);
|
||||
PowerOffDevices(devices, PowerOnOffState.StandBy);
|
||||
break;
|
||||
}
|
||||
case PowerOnOffState.ShutDown:
|
||||
{
|
||||
var devices = Devices.Where(d => d.PowerOffOnShutdown);
|
||||
|
||||
PowerOffDevices(devices);
|
||||
break;
|
||||
}
|
||||
|
||||
case PowerOnOffState.MonitorOff:
|
||||
{
|
||||
var devices = Devices.Where(d => d.PowerOffByWindows).ToList();
|
||||
PowerOffDevices(devices, PowerOnOffState.MonitorOff);
|
||||
break;
|
||||
}
|
||||
case PowerOnOffState.MonitorOn:
|
||||
{
|
||||
var devices = Devices.Where(d => d.PowerOnByWindows).ToList();
|
||||
PowerOnDevicesTask(devices);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void SessionEnded(object sender, SessionEndedEventArgs e)
|
||||
{
|
||||
//if (e.Reason == SessionEndReasons.SystemShutdown)
|
||||
//{
|
||||
// Logger.Debug($"SessionEnded: {e.Reason}");
|
||||
|
||||
// if (Config.PowerOffOnShutdown)
|
||||
// {
|
||||
// PowerOff();
|
||||
// }
|
||||
//}
|
||||
}
|
||||
|
||||
private void LgDevice_PowerStateChangedEvent(object sender, EventArgs e)
|
||||
{
|
||||
if (!(sender is LgDevice device))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (device.CurrentState == LgDevice.PowerState.Active)
|
||||
{
|
||||
if (Config.SetSelectedDeviceByPowerOn)
|
||||
{
|
||||
SelectedDevice = device;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public async Task ProcessChanged(object sender, ProcessChangedEventArgs args, CancellationToken token)
|
||||
{
|
||||
try
|
||||
{
|
||||
var wasConnected = Devices.Any(d => (d.PowerOffOnScreenSaver || d.PowerOnAfterScreenSaver) && d.IsConnected());
|
||||
|
||||
var applicableDevices = Devices.Where(d => d.PowerOffOnScreenSaver || d.PowerOnAfterScreenSaver || d.TriggersEnabled && _presets.Any(p => p.Triggers.Any(t => t.Trigger != PresetTriggerType.None) &&
|
||||
((string.IsNullOrEmpty(p.DeviceMacAddress) && d == SelectedDevice) || p.DeviceMacAddress.Equals(d.MacAddress, StringComparison.OrdinalIgnoreCase))));
|
||||
|
||||
if (!applicableDevices.Any())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (_poweredOffByScreenSaver && !_sessionSwitchDispatcher.UserLocalSession)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var processes = args.RunningProcesses;
|
||||
|
||||
if (_poweredOffByScreenSaver)
|
||||
{
|
||||
if (processes.Any(p => p.Id == _poweredOffByScreenSaverProcessId))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var process = processes.FirstOrDefault(p => p.ProcessName.ToLowerInvariant().EndsWith(".scr"));
|
||||
|
||||
if (process != null)
|
||||
{
|
||||
Logger.Debug($"Detected screen saver process switch from {_poweredOffByScreenSaverProcessId} to {process.Id}");
|
||||
|
||||
_poweredOffByScreenSaverProcessId = process.Id;
|
||||
return;
|
||||
}
|
||||
|
||||
Logger.Debug("Screensaver stopped, waking");
|
||||
_poweredOffByScreenSaver = false;
|
||||
_poweredOffByScreenSaverProcessId = 0;
|
||||
|
||||
WakeAfterStartupOrResume(PowerOnOffState.ScreenSaver);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
var connectedDevices = applicableDevices.Where(d => d.IsConnected()).ToList();
|
||||
|
||||
if (!connectedDevices.Any())
|
||||
{
|
||||
if (wasConnected)
|
||||
{
|
||||
Logger.Debug("Process monitor: TV(s) where connected, but not any longer");
|
||||
wasConnected = false;
|
||||
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
var devices = applicableDevices.ToList();
|
||||
foreach (var device in devices)
|
||||
{
|
||||
Logger.Debug($"Process monitor: test connection with {device.Name}...");
|
||||
|
||||
var test = await device.TestConnection();
|
||||
Logger.Debug("Process monitor: test connection result: " + test);
|
||||
}
|
||||
|
||||
connectedDevices = applicableDevices.Where(d => d.IsConnected()).ToList();
|
||||
|
||||
if (!connectedDevices.Any())
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!wasConnected)
|
||||
{
|
||||
Logger.Debug("Process monitor: TV(s) where not connected, but connection has now been established");
|
||||
wasConnected = true;
|
||||
}
|
||||
|
||||
if (connectedDevices.Any(d => d.PowerOffOnScreenSaver || d.PowerOnAfterScreenSaver))
|
||||
{
|
||||
await HandleScreenSaverProcessAsync(processes, connectedDevices);
|
||||
}
|
||||
|
||||
await ExecuteProcessPresets(args, connectedDevices);
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Error("ProcessChanged: " + ex.ToLogString());
|
||||
}
|
||||
}
|
||||
|
||||
private async Task ExecuteProcessPresets(ProcessChangedEventArgs context, IList<LgDevice> connectedDevices)
|
||||
{
|
||||
var triggerDevices = connectedDevices.Where(d => d.TriggersEnabled).ToList();
|
||||
|
||||
if (context.IsScreenSaverActive)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var selectedDevice = SelectedDevice;
|
||||
|
||||
var presets = _presets.Where(p => p.Triggers.Any(t => t.Trigger == PresetTriggerType.ProcessSwitch) &&
|
||||
((string.IsNullOrEmpty(p.DeviceMacAddress) && selectedDevice?.TriggersEnabled == true)
|
||||
|| Devices.Any(d => d.TriggersEnabled && p.DeviceMacAddress.Equals(d.MacAddress, StringComparison.OrdinalIgnoreCase))));
|
||||
if (!presets.Any())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var changedProcesses = new List<Process>();
|
||||
if (context.ForegroundProcess != null)
|
||||
{
|
||||
changedProcesses.Add(context.ForegroundProcess);
|
||||
}
|
||||
|
||||
if (context.ForegroundProcess != null && context.ForegroundProcessIsFullScreen)
|
||||
{
|
||||
presets = presets.Where(p => p.Triggers.Any(t => t.Conditions.HasFlag(PresetConditionType.FullScreen)));
|
||||
}
|
||||
else if (context.StoppedFullScreen)
|
||||
{
|
||||
presets = presets.Where(p => p.Triggers.Any(t => !t.Conditions.HasFlag(PresetConditionType.FullScreen)));
|
||||
}
|
||||
|
||||
var isHDRActive = triggerDevices.Any(d => d.IsUsingHDRPictureMode());
|
||||
|
||||
var isGsyncActive = await _serviceManager.HandleExternalServiceAsync("GsyncEnabled", new[] { "" });
|
||||
|
||||
var triggerContext = new PresetTriggerContext
|
||||
{
|
||||
IsHDRActive = isHDRActive,
|
||||
IsGsyncActive = isGsyncActive,
|
||||
ForegroundProcess = context.ForegroundProcess,
|
||||
ForegroundProcessIsFullScreen = context.ForegroundProcessIsFullScreen,
|
||||
ChangedProcesses = changedProcesses,
|
||||
IsNotificationDisabled = context.IsNotificationDisabled
|
||||
};
|
||||
|
||||
var toApplyPresets = presets.Where(p => p.Triggers.Any(t => t.TriggerActive(triggerContext))).ToList();
|
||||
|
||||
if (toApplyPresets.Any())
|
||||
{
|
||||
var toApplyPreset = toApplyPresets.FirstOrDefault(p => toApplyPresets.Count == 1 || p.Triggers.Any(t => !t.IncludedProcesses.Contains("*"))) ?? toApplyPresets.First();
|
||||
|
||||
if (_lastTriggeredPreset != toApplyPreset)
|
||||
{
|
||||
Logger.Debug($"Applying triggered preset: {toApplyPreset.name} because trigger conditions are met");
|
||||
|
||||
await ApplyPreset(toApplyPreset);
|
||||
|
||||
_lastTriggeredPreset = toApplyPreset;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async Task HandleScreenSaverProcessAsync(IList<Process> processes, List<LgDevice> connectedDevices)
|
||||
{
|
||||
var process = processes.FirstOrDefault(p => p.ProcessName.ToLowerInvariant().EndsWith(".scr"));
|
||||
|
||||
var powerOffDevices = connectedDevices.Where(d => d.PowerOffOnScreenSaver).ToList();
|
||||
|
||||
if (process == null)
|
||||
{
|
||||
powerOffDevices.ForEach(d => d.ClearPowerOffTask());
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
var parent = process.Parent(processes);
|
||||
|
||||
// Ignore manually started screen savers if no devices prefer this
|
||||
if (parent?.ProcessName.Contains("winlogon") != true && !connectedDevices.Any(d => d.HandleManualScreenSaver))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Logger.Debug($"Screensaver started: {process.ProcessName}, parent: {parent.ProcessName}");
|
||||
try
|
||||
{
|
||||
foreach (var device in powerOffDevices)
|
||||
{
|
||||
Logger.Debug($"Screensaver check: test connection with {device.Name}...");
|
||||
|
||||
var test = await device.TestConnection();
|
||||
Logger.Debug("Screensaver check: test connection result: " + test);
|
||||
if (!test)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (device.ScreenSaverMinimalDuration > 0)
|
||||
{
|
||||
Logger.Debug($"Screensaver check: powering off tv {device.Name} in {device.ScreenSaverMinimalDuration} seconds because of screensaver");
|
||||
|
||||
_poweredOffByScreenSaver = true;
|
||||
|
||||
device.PowerOffIn(device.ScreenSaverMinimalDuration);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
Logger.Debug($"Screensaver check: powering off tv {device.Name} because of screensaver");
|
||||
try
|
||||
{
|
||||
_poweredOffByScreenSaver = await device.PerformActionOnScreenSaver().WaitAsync(TimeSpan.FromSeconds(5));
|
||||
}
|
||||
catch (TimeoutException)
|
||||
{
|
||||
// Assume powering off was successful
|
||||
_poweredOffByScreenSaver = true;
|
||||
Logger.Error($"Screensaver check: timeout exception while powering off (probably connection closed)");
|
||||
}
|
||||
catch (Exception pex)
|
||||
{
|
||||
// Assume powering off was successful
|
||||
_poweredOffByScreenSaver = true;
|
||||
Logger.Error($"Screensaver check: exception while powering off (probably connection closed): " + pex.Message);
|
||||
}
|
||||
Logger.Debug($"Screensaver check: powered off tv {device.Name}");
|
||||
}
|
||||
|
||||
_poweredOffByScreenSaverProcessId = process.Id;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.Error($"Screensaver check: can't power off: " + e.ToLogString());
|
||||
}
|
||||
}
|
||||
|
||||
internal void AddCustomDevice(LgDevice device)
|
||||
{
|
||||
Devices.Add(device);
|
||||
}
|
||||
|
||||
internal void RemoveCustomDevice(LgDevice device)
|
||||
{
|
||||
Devices.Remove(device);
|
||||
|
||||
if (!string.IsNullOrEmpty(device.MacAddress))
|
||||
{
|
||||
var presets = _presets.Where(p => !string.IsNullOrEmpty(p.DeviceMacAddress) && p.DeviceMacAddress.Equals(device.MacAddress, StringComparison.OrdinalIgnoreCase)).ToList();
|
||||
presets.ForEach(preset =>
|
||||
{
|
||||
preset.DeviceMacAddress = null;
|
||||
});
|
||||
}
|
||||
|
||||
if (SelectedDevice == device)
|
||||
{
|
||||
SelectedDevice = Devices.Any() ? Devices.First() : null;
|
||||
}
|
||||
}
|
||||
|
||||
public void PowerOffDevices(IEnumerable<LgDevice> devices, PowerOnOffState state = PowerOnOffState.ShutDown)
|
||||
{
|
||||
if (!devices.Any())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (NativeMethods.GetAsyncKeyState(NativeConstants.VK_CONTROL) < 0 || NativeMethods.GetAsyncKeyState(NativeConstants.VK_RCONTROL) < 0)
|
||||
{
|
||||
Logger.Debug("Not powering off because CONTROL-key is down");
|
||||
return;
|
||||
}
|
||||
|
||||
var error = NativeMethods.SetThreadExecutionState(NativeConstants.ES_CONTINUOUS | NativeConstants.ES_SYSTEM_REQUIRED | NativeConstants.ES_AWAYMODE_REQUIRED);
|
||||
try
|
||||
{
|
||||
Logger.Debug($"SetThreadExecutionState: {error}, Thread#: {Environment.CurrentManagedThreadId}");
|
||||
if (state == PowerOnOffState.ShutDown)
|
||||
{
|
||||
var sleep = Config.ShutdownDelay;
|
||||
|
||||
Logger.Debug($"PowerOffDevices: Waiting for a maximum of {sleep} milliseconds...");
|
||||
|
||||
while (sleep > 0 && _restartDetector?.PowerOffDetected == false)
|
||||
{
|
||||
Thread.Sleep(100);
|
||||
|
||||
if (_restartDetector != null && (_restartDetector.RestartDetected || _restartDetector.IsRebootInProgress()))
|
||||
{
|
||||
Logger.Debug("Not powering off because of a restart");
|
||||
return;
|
||||
}
|
||||
|
||||
sleep -= 100;
|
||||
}
|
||||
}
|
||||
|
||||
Logger.Debug("Powering off tv(s)...");
|
||||
var tasks = new List<Task>();
|
||||
foreach (var device in devices)
|
||||
{
|
||||
var task = device.PowerOff(true, false);
|
||||
|
||||
tasks.Add(task);
|
||||
}
|
||||
|
||||
if (state == PowerOnOffState.StandBy)
|
||||
{
|
||||
var standByScript = Path.Combine(Program.DataDir, "StandByScript.bat");
|
||||
if (File.Exists(standByScript))
|
||||
{
|
||||
_winApiAdminService.StartProcess(standByScript, hidden: true, wait: true);
|
||||
}
|
||||
}
|
||||
|
||||
// We can't use async here because we need to stay on the main thread...
|
||||
var _ = Task.WhenAll(tasks.ToArray()).ConfigureAwait(true);
|
||||
|
||||
Logger.Debug("Done powering off tv(s)");
|
||||
}
|
||||
finally
|
||||
{
|
||||
var error2 = NativeMethods.SetThreadExecutionState(NativeConstants.ES_CONTINUOUS);
|
||||
Logger.Debug($"SetThreadExecutionState (reset): {error2}, Thread#: {Environment.CurrentManagedThreadId}");
|
||||
}
|
||||
}
|
||||
|
||||
public void PowerOnDevicesTask(IEnumerable<LgDevice> devices, PowerOnOffState state = PowerOnOffState.StartUp, bool checkUserSession = true)
|
||||
{
|
||||
Task.Run(async () => await PowerOnDevices(devices, state, checkUserSession));
|
||||
}
|
||||
|
||||
public async Task PowerOnDevices(IEnumerable<LgDevice> devices, PowerOnOffState state = PowerOnOffState.StartUp, bool checkUserSession = true)
|
||||
{
|
||||
if (!devices.Any())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (checkUserSession && !_sessionSwitchDispatcher.UserLocalSession)
|
||||
{
|
||||
Logger.Debug($"WakeAfterStartupOrResume: not waking because session info indicates no local session");
|
||||
return;
|
||||
}
|
||||
|
||||
var resumeScript = Path.Combine(Program.DataDir, "ResumeScript.bat");
|
||||
|
||||
var tasks = new List<Task>();
|
||||
|
||||
foreach (var device in devices)
|
||||
{
|
||||
if (!device.PowerOnAfterManualPowerOff && device.PoweredOffBy == LgDevice.PowerOffSource.Manually)
|
||||
{
|
||||
Logger.Debug($"[{device.Name}]: device was manually powered off by user, not powering on");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (state == PowerOnOffState.ScreenSaver)
|
||||
{
|
||||
tasks.Add(device.PerformActionAfterScreenSaver(Config.PowerOnRetries));
|
||||
continue;
|
||||
}
|
||||
|
||||
var task = device.WakeAndConnectWithRetries(Config.PowerOnRetries);
|
||||
tasks.Add(task);
|
||||
}
|
||||
|
||||
await Task.WhenAll(tasks.ToArray());
|
||||
|
||||
if (File.Exists(resumeScript))
|
||||
{
|
||||
_winApiAdminService.StartProcess(resumeScript, hidden: true);
|
||||
}
|
||||
}
|
||||
|
||||
private void SendConfigToService()
|
||||
{
|
||||
if (!_winApiService.IsServiceRunning())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var json = JsonConvert.SerializeObject(Config);
|
||||
|
||||
var message = new SvcMessage
|
||||
{
|
||||
MessageType = SvcMessageType.SetLgConfig,
|
||||
Data = json
|
||||
};
|
||||
|
||||
PipeUtils.SendMessage(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace ColorControl.Services.LG
|
||||
{
|
||||
class LgServiceConfig
|
||||
{
|
||||
public bool PowerOnAfterStartup { get; set; }
|
||||
public int PowerOnDelayAfterResume { get; set; }
|
||||
public int PowerOnRetries { get; set; }
|
||||
public string PreferredMacAddress { get; set; }
|
||||
public string DeviceSearchKey { get; set; }
|
||||
public List<LgDevice> Devices { get; set; }
|
||||
public bool ShowRemoteControl { get; set; }
|
||||
public bool ShowAdvancedActions { get; set; }
|
||||
public string GameBarShortcut { get; set; }
|
||||
public int GameBarTop { get; set; }
|
||||
public int GameBarLeft { get; set; }
|
||||
public int ShutdownDelay { get; set; }
|
||||
public bool SetSelectedDeviceByPowerOn { get; set; }
|
||||
public string QuickAccessShortcut { get; set; }
|
||||
public int DefaultButtonDelay { get; set; }
|
||||
|
||||
public LgServiceConfig()
|
||||
{
|
||||
PowerOnDelayAfterResume = 5000;
|
||||
ShutdownDelay = 1000;
|
||||
DeviceSearchKey = "[LG]";
|
||||
PowerOnRetries = 10;
|
||||
Devices = new List<LgDevice>();
|
||||
GameBarTop = 100;
|
||||
GameBarLeft = 100;
|
||||
DefaultButtonDelay = 200;
|
||||
}
|
||||
}
|
||||
}
|
||||
+197
@@ -0,0 +1,197 @@
|
||||
|
||||
namespace ColorControl.Services.LG
|
||||
{
|
||||
partial class RemoteControlForm
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Windows Form Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(RemoteControlForm));
|
||||
this.flowPanel = new System.Windows.Forms.FlowLayoutPanel();
|
||||
this.btnClose = new System.Windows.Forms.Button();
|
||||
this.lblUC = new System.Windows.Forms.Label();
|
||||
this.chkDirectMode = new System.Windows.Forms.CheckBox();
|
||||
this.pnlMouse = new System.Windows.Forms.Panel();
|
||||
this.lblPos = new System.Windows.Forms.Label();
|
||||
this.label1 = new System.Windows.Forms.Label();
|
||||
this.label2 = new System.Windows.Forms.Label();
|
||||
this.label3 = new System.Windows.Forms.Label();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// flowPanel
|
||||
//
|
||||
this.flowPanel.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.flowPanel.Location = new System.Drawing.Point(12, 185);
|
||||
this.flowPanel.Name = "flowPanel";
|
||||
this.flowPanel.Size = new System.Drawing.Size(817, 120);
|
||||
this.flowPanel.TabIndex = 0;
|
||||
this.flowPanel.MouseDown += new System.Windows.Forms.MouseEventHandler(this.RemoteControlForm_MouseDown);
|
||||
this.flowPanel.MouseMove += new System.Windows.Forms.MouseEventHandler(this.flowPanel_MouseMove);
|
||||
this.flowPanel.PreviewKeyDown += new System.Windows.Forms.PreviewKeyDownEventHandler(this.flowPanel_PreviewKeyDown);
|
||||
//
|
||||
// btnClose
|
||||
//
|
||||
this.btnClose.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.btnClose.FlatAppearance.BorderColor = System.Drawing.Color.DarkGray;
|
||||
this.btnClose.FlatAppearance.BorderSize = 0;
|
||||
this.btnClose.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
|
||||
this.btnClose.ForeColor = System.Drawing.Color.White;
|
||||
this.btnClose.Location = new System.Drawing.Point(826, 0);
|
||||
this.btnClose.Name = "btnClose";
|
||||
this.btnClose.Size = new System.Drawing.Size(14, 23);
|
||||
this.btnClose.TabIndex = 1;
|
||||
this.btnClose.Text = "x";
|
||||
this.btnClose.UseVisualStyleBackColor = true;
|
||||
this.btnClose.Click += new System.EventHandler(this.btnClose_Click);
|
||||
//
|
||||
// lblUC
|
||||
//
|
||||
this.lblUC.AutoSize = true;
|
||||
this.lblUC.ForeColor = System.Drawing.Color.Maroon;
|
||||
this.lblUC.Location = new System.Drawing.Point(12, 0);
|
||||
this.lblUC.Name = "lblUC";
|
||||
this.lblUC.Size = new System.Drawing.Size(100, 13);
|
||||
this.lblUC.TabIndex = 0;
|
||||
this.lblUC.Text = "Under construction!";
|
||||
//
|
||||
// chkDirectMode
|
||||
//
|
||||
this.chkDirectMode.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
|
||||
this.chkDirectMode.AutoSize = true;
|
||||
this.chkDirectMode.ForeColor = System.Drawing.Color.White;
|
||||
this.chkDirectMode.Location = new System.Drawing.Point(12, 718);
|
||||
this.chkDirectMode.Name = "chkDirectMode";
|
||||
this.chkDirectMode.Size = new System.Drawing.Size(105, 17);
|
||||
this.chkDirectMode.TabIndex = 2;
|
||||
this.chkDirectMode.Text = "Direct Mode (F1)";
|
||||
this.chkDirectMode.UseVisualStyleBackColor = true;
|
||||
this.chkDirectMode.CheckedChanged += new System.EventHandler(this.chkDirectMode_CheckedChanged);
|
||||
//
|
||||
// pnlMouse
|
||||
//
|
||||
this.pnlMouse.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
|
||||
| System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.pnlMouse.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
|
||||
this.pnlMouse.Location = new System.Drawing.Point(12, 311);
|
||||
this.pnlMouse.Name = "pnlMouse";
|
||||
this.pnlMouse.Size = new System.Drawing.Size(817, 401);
|
||||
this.pnlMouse.TabIndex = 3;
|
||||
this.pnlMouse.MouseEnter += new System.EventHandler(this.pnlMouse_MouseEnter);
|
||||
this.pnlMouse.MouseMove += new System.Windows.Forms.MouseEventHandler(this.pnlMouse_MouseMove);
|
||||
this.pnlMouse.MouseUp += new System.Windows.Forms.MouseEventHandler(this.pnlMouse_MouseUp);
|
||||
//
|
||||
// lblPos
|
||||
//
|
||||
this.lblPos.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.lblPos.AutoSize = true;
|
||||
this.lblPos.ForeColor = System.Drawing.Color.Maroon;
|
||||
this.lblPos.Location = new System.Drawing.Point(749, 718);
|
||||
this.lblPos.Name = "lblPos";
|
||||
this.lblPos.Size = new System.Drawing.Size(0, 13);
|
||||
this.lblPos.TabIndex = 1;
|
||||
//
|
||||
// label1
|
||||
//
|
||||
this.label1.AutoSize = true;
|
||||
this.label1.ForeColor = System.Drawing.Color.White;
|
||||
this.label1.Location = new System.Drawing.Point(12, 26);
|
||||
this.label1.Name = "label1";
|
||||
this.label1.Size = new System.Drawing.Size(538, 52);
|
||||
this.label1.TabIndex = 4;
|
||||
this.label1.Text = resources.GetString("label1.Text");
|
||||
//
|
||||
// label2
|
||||
//
|
||||
this.label2.AutoSize = true;
|
||||
this.label2.ForeColor = System.Drawing.Color.White;
|
||||
this.label2.Location = new System.Drawing.Point(231, 91);
|
||||
this.label2.Name = "label2";
|
||||
this.label2.Size = new System.Drawing.Size(216, 52);
|
||||
this.label2.TabIndex = 5;
|
||||
this.label2.Text = "Mouse:\r\n- left button: activate/open item\r\n- right button: go back\r\n- wheel: scro" +
|
||||
"ll through menus (only vertically)";
|
||||
//
|
||||
// label3
|
||||
//
|
||||
this.label3.AutoSize = true;
|
||||
this.label3.ForeColor = System.Drawing.Color.White;
|
||||
this.label3.Location = new System.Drawing.Point(12, 91);
|
||||
this.label3.Name = "label3";
|
||||
this.label3.Size = new System.Drawing.Size(180, 91);
|
||||
this.label3.TabIndex = 6;
|
||||
this.label3.Text = "Keyboard keys:\r\n- arrow keys: navigate the menu\r\n- backspace: go back\r\n- escape: " +
|
||||
"exit\r\n- S: open picture settings\r\n- H: open Home\r\n- media keys: volume up/down/m" +
|
||||
"ute";
|
||||
//
|
||||
// RemoteControlForm
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.BackColor = System.Drawing.Color.Black;
|
||||
this.ClientSize = new System.Drawing.Size(841, 735);
|
||||
this.Controls.Add(this.label3);
|
||||
this.Controls.Add(this.label2);
|
||||
this.Controls.Add(this.label1);
|
||||
this.Controls.Add(this.lblPos);
|
||||
this.Controls.Add(this.pnlMouse);
|
||||
this.Controls.Add(this.chkDirectMode);
|
||||
this.Controls.Add(this.lblUC);
|
||||
this.Controls.Add(this.btnClose);
|
||||
this.Controls.Add(this.flowPanel);
|
||||
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
|
||||
this.KeyPreview = true;
|
||||
this.MaximizeBox = false;
|
||||
this.MinimizeBox = false;
|
||||
this.Name = "RemoteControlForm";
|
||||
this.Opacity = 0.8D;
|
||||
this.Text = "RemoteControlForm";
|
||||
this.FormClosed += new System.Windows.Forms.FormClosedEventHandler(this.RemoteControlForm_FormClosed);
|
||||
this.Load += new System.EventHandler(this.RemoteControlForm_Load);
|
||||
this.Shown += new System.EventHandler(this.RemoteControlForm_Shown);
|
||||
this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.RemoteControlForm_KeyDown);
|
||||
this.KeyUp += new System.Windows.Forms.KeyEventHandler(this.RemoteControlForm_KeyUp);
|
||||
this.MouseDown += new System.Windows.Forms.MouseEventHandler(this.RemoteControlForm_MouseDown);
|
||||
this.PreviewKeyDown += new System.Windows.Forms.PreviewKeyDownEventHandler(this.RemoteControlForm_PreviewKeyDown);
|
||||
this.ResumeLayout(false);
|
||||
this.PerformLayout();
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.FlowLayoutPanel flowPanel;
|
||||
private System.Windows.Forms.Button btnClose;
|
||||
private System.Windows.Forms.Label lblUC;
|
||||
private System.Windows.Forms.CheckBox chkDirectMode;
|
||||
private System.Windows.Forms.Panel pnlMouse;
|
||||
private System.Windows.Forms.Label lblPos;
|
||||
private System.Windows.Forms.Label label1;
|
||||
private System.Windows.Forms.Label label2;
|
||||
private System.Windows.Forms.Label label3;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,242 @@
|
||||
using LgTv;
|
||||
using NWin32;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace ColorControl.Services.LG
|
||||
{
|
||||
partial class RemoteControlForm : Form
|
||||
{
|
||||
private LgService _lgService;
|
||||
private List<LgPreset> _buttons;
|
||||
private LgWebOsMouseService _mouseService;
|
||||
private int _maxX, _maxY;
|
||||
private int _posX, _posY;
|
||||
|
||||
public RemoteControlForm(LgService lgService, List<LgPreset> buttons)
|
||||
{
|
||||
_lgService = lgService;
|
||||
_buttons = buttons;
|
||||
|
||||
InitializeComponent();
|
||||
|
||||
pnlMouse.MouseWheel += new MouseEventHandler(pnlMouse_MouseWheel);
|
||||
}
|
||||
|
||||
private void RemoteControlForm_Load(object sender, EventArgs e)
|
||||
{
|
||||
foreach (var preset in _buttons)
|
||||
{
|
||||
var button = new Button();
|
||||
button.ForeColor = Color.White;
|
||||
button.FlatStyle = FlatStyle.Flat;
|
||||
button.FlatAppearance.BorderColor = Color.DarkGray;
|
||||
button.FlatAppearance.MouseOverBackColor = Color.DarkGray;
|
||||
button.Text = preset.name;
|
||||
button.Click += ButtonClick;
|
||||
button.Tag = preset;
|
||||
|
||||
button.Parent = flowPanel;
|
||||
}
|
||||
}
|
||||
|
||||
private void ButtonClick(object sender, EventArgs e)
|
||||
{
|
||||
if (e is MouseEventArgs)
|
||||
{
|
||||
var preset = (LgPreset)(sender as Button).Tag;
|
||||
|
||||
var _ = _lgService.ApplyPreset(preset);
|
||||
}
|
||||
}
|
||||
|
||||
private void btnClose_Click(object sender, EventArgs e)
|
||||
{
|
||||
Close();
|
||||
}
|
||||
|
||||
private void RemoteControlForm_MouseDown(object sender, MouseEventArgs e)
|
||||
{
|
||||
if (e.Button == MouseButtons.Left)
|
||||
{
|
||||
NativeMethods.ReleaseCapture();
|
||||
var intPtr = new UIntPtr(2);
|
||||
NativeMethods.SendMessageW(Handle, NativeConstants.WM_NCLBUTTONDOWN, intPtr, IntPtr.Zero);
|
||||
}
|
||||
}
|
||||
|
||||
private void RemoteControlForm_KeyDown(object sender, KeyEventArgs e)
|
||||
{
|
||||
//var key = e.KeyCode;
|
||||
//HandleKey(key);
|
||||
}
|
||||
|
||||
private void flowPanel_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
|
||||
{
|
||||
//HandleKey(e.KeyCode);
|
||||
}
|
||||
|
||||
private void HandleKey(Keys key)
|
||||
{
|
||||
if (!chkDirectMode.Checked)
|
||||
{
|
||||
return;
|
||||
}
|
||||
var cvt = new KeysConverter();
|
||||
var shortcut = (string)cvt.ConvertTo(key, typeof(string));
|
||||
|
||||
var preset = _buttons.FirstOrDefault(p => p.shortcut != null && p.shortcut.Equals(shortcut));
|
||||
if (preset != null)
|
||||
{
|
||||
var _ = _lgService.ApplyPreset(preset);
|
||||
}
|
||||
}
|
||||
|
||||
private void RemoteControlForm_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
|
||||
{
|
||||
//HandleKey(e.KeyCode);
|
||||
}
|
||||
|
||||
private void RemoteControlForm_KeyUp(object sender, KeyEventArgs e)
|
||||
{
|
||||
if (e.KeyCode == Keys.F1)
|
||||
{
|
||||
chkDirectMode.Checked = !chkDirectMode.Checked;
|
||||
return;
|
||||
}
|
||||
|
||||
HandleKey(e.KeyCode);
|
||||
}
|
||||
|
||||
private async void chkDirectMode_CheckedChanged(object sender, EventArgs e)
|
||||
{
|
||||
if (chkDirectMode.Checked)
|
||||
{
|
||||
// MessageForms.InfoOk(
|
||||
//@"If you enable Direct Mode you will be able to control the TV directly via your keyboard and mouse.
|
||||
//Note that your mouse will be captured in a box and that due to pointer accelaration the control will not be perfect.
|
||||
|
||||
//Keyboard keys:
|
||||
//- arrow keys: navigate the menu
|
||||
//- backspace: go back
|
||||
//- escape: exit
|
||||
//- S: open picture settings
|
||||
//- media keys: volume up/down/mute
|
||||
|
||||
//Mouse:
|
||||
//- left button: activate/open item
|
||||
//- right button: go back
|
||||
//- wheel: scroll through menus (only vertically)
|
||||
|
||||
//Press F1 to stop Direct Mode."
|
||||
// );
|
||||
|
||||
if (_mouseService == null)
|
||||
{
|
||||
await _lgService.GetMouseAsync().ContinueWith((task) => BeginInvoke(SetMouseService, new[] { task }));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Cursor.Clip = Rectangle.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
private void SetMouseService(Task<LgWebOsMouseService> mouseServiceTask)
|
||||
{
|
||||
_mouseService = mouseServiceTask.Result;
|
||||
|
||||
_maxX = 1920;
|
||||
_maxY = 1080;
|
||||
_posX = _maxX / 2;
|
||||
_posY = _maxY / 2;
|
||||
}
|
||||
|
||||
private void flowPanel_MouseMove(object sender, MouseEventArgs e)
|
||||
{
|
||||
}
|
||||
|
||||
private void pnlMouse_MouseEnter(object sender, EventArgs e)
|
||||
{
|
||||
if (chkDirectMode.Checked)
|
||||
{
|
||||
Cursor.Clip = RectangleToScreen(pnlMouse.Bounds);
|
||||
}
|
||||
}
|
||||
|
||||
private void RemoteControlForm_FormClosed(object sender, FormClosedEventArgs e)
|
||||
{
|
||||
Cursor.Clip = Rectangle.Empty;
|
||||
}
|
||||
|
||||
private void pnlMouse_MouseUp(object sender, MouseEventArgs e)
|
||||
{
|
||||
if (chkDirectMode.Checked && _mouseService != null)
|
||||
{
|
||||
if (e.Button == MouseButtons.Left)
|
||||
{
|
||||
_mouseService.Click();
|
||||
}
|
||||
else
|
||||
{
|
||||
HandleKey(Keys.Back);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void HandleMouse(MouseEventArgs e)
|
||||
{
|
||||
if (chkDirectMode.Checked && _mouseService != null)
|
||||
{
|
||||
var scaleX = (double)e.X / pnlMouse.Width;
|
||||
var scaleY = (double)e.Y / pnlMouse.Height;
|
||||
|
||||
var relX = scaleX * _maxX;
|
||||
var relY = scaleY * _maxY;
|
||||
|
||||
var dx = (int)relX - _posX;
|
||||
var dy = (int)relY - _posY;
|
||||
|
||||
_posX = Math.Min(_posX + dx, _maxX);
|
||||
_posY = Math.Min(_posY + dy, _maxY);
|
||||
|
||||
lblPos.Text = $"Pos: {_posX}, {_posY}";
|
||||
|
||||
//var cx = flowPanel.Width / 2;
|
||||
//var cy = flowPanel.Height / 2;
|
||||
|
||||
//var dx = (e.X - cx) / 10;
|
||||
//var dy = (e.Y - cy) / 10;
|
||||
|
||||
_mouseService.Move(dx, dy);
|
||||
}
|
||||
}
|
||||
|
||||
private void RemoteControlForm_Shown(object sender, EventArgs e)
|
||||
{
|
||||
chkDirectMode.Checked = true;
|
||||
}
|
||||
|
||||
private void pnlMouse_MouseMove(object sender, MouseEventArgs e)
|
||||
{
|
||||
HandleMouse(e);
|
||||
}
|
||||
|
||||
private void pnlMouse_MouseWheel(object sender, MouseEventArgs e)
|
||||
{
|
||||
if (chkDirectMode.Checked && _mouseService != null)
|
||||
{
|
||||
var dy = e.Delta * SystemInformation.MouseWheelScrollLines / 120;
|
||||
|
||||
if (dy != 0)
|
||||
{
|
||||
_mouseService.Scroll(0, dy);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,126 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="label1.Text" xml:space="preserve">
|
||||
<value>This form allows you to control the TV directly via your keyboard and mouse.
|
||||
Note that your mouse will be captured in a box and that due to pointer acceleration the control will not be perfect.
|
||||
|
||||
Press F1 to stop Direct Mode.</value>
|
||||
</data>
|
||||
</root>
|
||||
@@ -0,0 +1,84 @@
|
||||
|
||||
namespace ColorControl.Services.LG
|
||||
{
|
||||
partial class RemoteControlPanel
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Component Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
pbRemote = new System.Windows.Forms.PictureBox();
|
||||
btnRcDirect = new System.Windows.Forms.Button();
|
||||
((System.ComponentModel.ISupportInitialize)pbRemote).BeginInit();
|
||||
SuspendLayout();
|
||||
//
|
||||
// pbRemote
|
||||
//
|
||||
pbRemote.BackColor = System.Drawing.Color.Transparent;
|
||||
pbRemote.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
pbRemote.Image = Properties.Resources.LG_remote;
|
||||
pbRemote.Location = new System.Drawing.Point(0, 0);
|
||||
pbRemote.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
pbRemote.Name = "pbRemote";
|
||||
pbRemote.Size = new System.Drawing.Size(150, 540);
|
||||
pbRemote.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom;
|
||||
pbRemote.TabIndex = 0;
|
||||
pbRemote.TabStop = false;
|
||||
pbRemote.Click += pbRemote_Click;
|
||||
pbRemote.MouseMove += pbRemote_MouseMove;
|
||||
//
|
||||
// btnRcDirect
|
||||
//
|
||||
btnRcDirect.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right;
|
||||
btnRcDirect.Location = new System.Drawing.Point(83, 8);
|
||||
btnRcDirect.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
btnRcDirect.Name = "btnRcDirect";
|
||||
btnRcDirect.Size = new System.Drawing.Size(64, 27);
|
||||
btnRcDirect.TabIndex = 3;
|
||||
btnRcDirect.Text = "Direct";
|
||||
btnRcDirect.UseVisualStyleBackColor = true;
|
||||
btnRcDirect.Click += button1_Click;
|
||||
//
|
||||
// RemoteControlPanel
|
||||
//
|
||||
AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
|
||||
AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
BackColor = System.Drawing.Color.White;
|
||||
Controls.Add(btnRcDirect);
|
||||
Controls.Add(pbRemote);
|
||||
Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
Name = "RemoteControlPanel";
|
||||
Size = new System.Drawing.Size(150, 540);
|
||||
Load += RemoteControlPanel_Load;
|
||||
((System.ComponentModel.ISupportInitialize)pbRemote).EndInit();
|
||||
ResumeLayout(false);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.PictureBox pbRemote;
|
||||
private System.Windows.Forms.Button btnRcDirect;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,188 @@
|
||||
using ColorControl.Shared.Common;
|
||||
using NLog;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace ColorControl.Services.LG
|
||||
{
|
||||
partial class RemoteControlPanel : UserControl
|
||||
{
|
||||
private static int Range = 35;
|
||||
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
|
||||
|
||||
private LgService _lgService;
|
||||
private List<LgPreset> _buttons;
|
||||
private RemoteControlForm _remoteControlForm;
|
||||
private Bitmap _backupImage;
|
||||
private LgPreset _lastHoveredPreset;
|
||||
|
||||
public RemoteControlPanel(LgService lgService, List<LgPreset> buttons)
|
||||
{
|
||||
_lgService = lgService;
|
||||
_buttons = buttons;
|
||||
|
||||
InitializeComponent();
|
||||
|
||||
_backupImage = new Bitmap(pbRemote.Image);
|
||||
|
||||
var txtCoords = Utils.GetResourceFile("RC_coords.txt");
|
||||
|
||||
foreach (var line in txtCoords.Split('\n'))
|
||||
{
|
||||
var columns = line.Split(';');
|
||||
|
||||
var name = columns[0];
|
||||
var preset = _buttons.FirstOrDefault(p => p.name.Equals(name));
|
||||
if (preset != null)
|
||||
{
|
||||
preset.X = int.Parse(columns[1]);
|
||||
preset.Y = int.Parse(columns[2]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void RemoteControlPanel_Load(object sender, EventArgs e)
|
||||
{
|
||||
}
|
||||
|
||||
private void ButtonClick(object sender, EventArgs e)
|
||||
{
|
||||
if (e is MouseEventArgs)
|
||||
{
|
||||
var preset = (LgPreset)(sender as Button).Tag;
|
||||
|
||||
var _ = _lgService.ApplyPreset(preset);
|
||||
}
|
||||
}
|
||||
|
||||
private void pbRemote_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (e is MouseEventArgs mouseArgs)
|
||||
{
|
||||
var (posX, posY) = GetCoordsInImage(mouseArgs.X, mouseArgs.Y);
|
||||
|
||||
var preset = _buttons.FirstOrDefault(p => posX >= (p.X - Range) && posX <= (p.X + Range) && posY >= (p.Y - Range) && posY <= (p.Y + Range));
|
||||
|
||||
if (preset != null)
|
||||
{
|
||||
if (preset.steps.Contains("POWER") && _lgService.SelectedDevice?.CurrentState != LgDevice.PowerState.Active)
|
||||
{
|
||||
Logger.Debug("Executing WOL instead of POWER");
|
||||
|
||||
var wolPreset = _buttons.FirstOrDefault(p => p.name.Equals("Wol"));
|
||||
if (wolPreset != null)
|
||||
{
|
||||
preset = wolPreset;
|
||||
}
|
||||
}
|
||||
|
||||
var _ = _lgService.ApplyPreset(preset);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private (int, int) GetCoordsInImage(int curX, int curY)
|
||||
{
|
||||
var width = pbRemote.Width;
|
||||
var aspect = 0.27D;
|
||||
var currentAspect = (double)pbRemote.Width / pbRemote.Height;
|
||||
if (currentAspect > aspect)
|
||||
{
|
||||
width = (int)(aspect * pbRemote.Height);
|
||||
curX = curX - ((pbRemote.Width - width) / 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
var height = (int)(pbRemote.Width / aspect);
|
||||
curY = curY - ((pbRemote.Height - height) / 2);
|
||||
}
|
||||
|
||||
var factor = 405D / width;
|
||||
|
||||
var posX = (int)(curX * factor);
|
||||
var posY = (int)(curY * factor);
|
||||
|
||||
return (posX, posY);
|
||||
}
|
||||
|
||||
private void btnRcDirect_Click(object sender, EventArgs e)
|
||||
{
|
||||
}
|
||||
|
||||
private void pbRemote_MouseMove(object sender, MouseEventArgs mouseArgs)
|
||||
{
|
||||
var (posX, posY) = GetCoordsInImage(mouseArgs.X, mouseArgs.Y);
|
||||
|
||||
var preset = _buttons.FirstOrDefault(p => posX >= (p.X - Range) && posX <= (p.X + Range) && posY >= (p.Y - Range) && posY <= (p.Y + Range));
|
||||
|
||||
var refresh = false;
|
||||
|
||||
if (_lastHoveredPreset != null && (preset == null || preset != _lastHoveredPreset))
|
||||
{
|
||||
var image = (Bitmap)pbRemote.Image;
|
||||
|
||||
for (var y = Math.Max(0, _lastHoveredPreset.Y - Range); y < _lastHoveredPreset.Y + Range; y++)
|
||||
{
|
||||
for (var x = Math.Max(0, _lastHoveredPreset.X - Range); x < _lastHoveredPreset.X + Range; x++)
|
||||
{
|
||||
image.SetPixel(x, y, _backupImage.GetPixel(x, y));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
refresh = true;
|
||||
}
|
||||
|
||||
if (preset != null && preset != _lastHoveredPreset)
|
||||
{
|
||||
var image = (Bitmap)pbRemote.Image;
|
||||
var rec = new Rectangle(Math.Max(0, preset.X - Range), Math.Max(0, preset.Y - Range), Range * 2, Range * 2);
|
||||
|
||||
using (var g = Graphics.FromImage(image))
|
||||
{
|
||||
using (var cloud_brush = new SolidBrush(Color.FromArgb(128, Color.White)))
|
||||
{
|
||||
g.FillEllipse(cloud_brush, rec);
|
||||
}
|
||||
}
|
||||
|
||||
//for (var y = preset.Y - 30; y < preset.Y + 30; y++)
|
||||
//{
|
||||
// for (var x = preset.X - 30; x < preset.X + 30; x++)
|
||||
// {
|
||||
// var pixel = image.GetPixel(x, y);
|
||||
|
||||
// image.SetPixel(x, y, Color.FromArgb(150, 0, 0));
|
||||
|
||||
// }
|
||||
//}
|
||||
|
||||
refresh = true;
|
||||
}
|
||||
|
||||
if (refresh)
|
||||
{
|
||||
pbRemote.Refresh();
|
||||
}
|
||||
|
||||
_lastHoveredPreset = preset;
|
||||
}
|
||||
|
||||
private void button1_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (_remoteControlForm == null || _remoteControlForm.IsDisposed)
|
||||
{
|
||||
var buttons = _lgService.GetRemoteControlButtons();
|
||||
_remoteControlForm = new RemoteControlForm(_lgService, buttons);
|
||||
_remoteControlForm.Show();
|
||||
}
|
||||
else
|
||||
{
|
||||
_remoteControlForm.Show();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
<root>
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
</root>
|
||||
@@ -0,0 +1,40 @@
|
||||
using Newtonsoft.Json;
|
||||
using NvAPIWrapper.Display;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace ColorControl.Services.NVIDIA
|
||||
{
|
||||
public class ColorDataConverter : JsonConverter<ColorData>
|
||||
{
|
||||
public override bool CanWrite { get { return false; } }
|
||||
|
||||
public override ColorData ReadJson(JsonReader reader, Type objectType, ColorData existingValue, bool hasExistingValue, JsonSerializer serializer)
|
||||
{
|
||||
var result = new Dictionary<string, object>();
|
||||
|
||||
if (reader.TokenType == JsonToken.StartObject)
|
||||
{
|
||||
reader.Read();
|
||||
while (reader.TokenType == JsonToken.PropertyName)
|
||||
{
|
||||
var propertyName = reader.Value;
|
||||
|
||||
reader.Read();
|
||||
var value = reader.Value;
|
||||
|
||||
result.Add(propertyName.ToString(), value);
|
||||
|
||||
reader.Read();
|
||||
}
|
||||
}
|
||||
|
||||
return NvPreset.GenerateColorData(result);
|
||||
}
|
||||
|
||||
public override void WriteJson(JsonWriter writer, ColorData value, JsonSerializer serializer)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,29 @@
|
||||
using NvAPIWrapper.Display;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace ColorControl.Services.NVIDIA
|
||||
{
|
||||
class NvDisplayInfo
|
||||
{
|
||||
public Display Display { get; }
|
||||
|
||||
public List<string> Values { get; }
|
||||
|
||||
public string InfoLine { get; }
|
||||
|
||||
public string Name { get; }
|
||||
|
||||
public NvDisplayInfo(Display display, List<string> values, string infoLine, string name)
|
||||
{
|
||||
Display = display;
|
||||
Values = values;
|
||||
InfoLine = infoLine;
|
||||
Name = name;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return Name;
|
||||
}
|
||||
}
|
||||
}
|
||||
+184
@@ -0,0 +1,184 @@
|
||||
namespace ColorControl.Services.NVIDIA
|
||||
{
|
||||
partial class NvDitherPanel
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Component Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.grpNvidiaOptions = new System.Windows.Forms.GroupBox();
|
||||
this.lblDitheringDisplay = new System.Windows.Forms.Label();
|
||||
this.cbxDitheringDisplay = new System.Windows.Forms.ComboBox();
|
||||
this.lblDitheringMode = new System.Windows.Forms.Label();
|
||||
this.cbxDitheringMode = new System.Windows.Forms.ComboBox();
|
||||
this.lblDitheringBitDepth = new System.Windows.Forms.Label();
|
||||
this.cbxDitheringBitDepth = new System.Windows.Forms.ComboBox();
|
||||
this.chkDitheringEnabled = new System.Windows.Forms.CheckBox();
|
||||
this.pbGradient = new System.Windows.Forms.PictureBox();
|
||||
this.grpNvidiaOptions.SuspendLayout();
|
||||
((System.ComponentModel.ISupportInitialize)(this.pbGradient)).BeginInit();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// grpNvidiaOptions
|
||||
//
|
||||
this.grpNvidiaOptions.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
|
||||
| System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.grpNvidiaOptions.Controls.Add(this.lblDitheringDisplay);
|
||||
this.grpNvidiaOptions.Controls.Add(this.cbxDitheringDisplay);
|
||||
this.grpNvidiaOptions.Controls.Add(this.lblDitheringMode);
|
||||
this.grpNvidiaOptions.Controls.Add(this.cbxDitheringMode);
|
||||
this.grpNvidiaOptions.Controls.Add(this.lblDitheringBitDepth);
|
||||
this.grpNvidiaOptions.Controls.Add(this.cbxDitheringBitDepth);
|
||||
this.grpNvidiaOptions.Controls.Add(this.chkDitheringEnabled);
|
||||
this.grpNvidiaOptions.Controls.Add(this.pbGradient);
|
||||
this.grpNvidiaOptions.Location = new System.Drawing.Point(4, 3);
|
||||
this.grpNvidiaOptions.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
this.grpNvidiaOptions.Name = "grpNvidiaOptions";
|
||||
this.grpNvidiaOptions.Padding = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
this.grpNvidiaOptions.Size = new System.Drawing.Size(856, 479);
|
||||
this.grpNvidiaOptions.TabIndex = 6;
|
||||
this.grpNvidiaOptions.TabStop = false;
|
||||
this.grpNvidiaOptions.Text = "NVIDIA options - test dithering";
|
||||
//
|
||||
// lblDitheringDisplay
|
||||
//
|
||||
this.lblDitheringDisplay.AutoSize = true;
|
||||
this.lblDitheringDisplay.Location = new System.Drawing.Point(8, 23);
|
||||
this.lblDitheringDisplay.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
|
||||
this.lblDitheringDisplay.Name = "lblDitheringDisplay";
|
||||
this.lblDitheringDisplay.Size = new System.Drawing.Size(48, 15);
|
||||
this.lblDitheringDisplay.TabIndex = 9;
|
||||
this.lblDitheringDisplay.Text = "Display:";
|
||||
//
|
||||
// cbxDitheringDisplay
|
||||
//
|
||||
this.cbxDitheringDisplay.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
|
||||
this.cbxDitheringDisplay.FormattingEnabled = true;
|
||||
this.cbxDitheringDisplay.Location = new System.Drawing.Point(75, 17);
|
||||
this.cbxDitheringDisplay.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
this.cbxDitheringDisplay.Name = "cbxDitheringDisplay";
|
||||
this.cbxDitheringDisplay.Size = new System.Drawing.Size(212, 23);
|
||||
this.cbxDitheringDisplay.TabIndex = 8;
|
||||
this.cbxDitheringDisplay.SelectedIndexChanged += new System.EventHandler(this.cbxDitheringDisplay_SelectedIndexChanged);
|
||||
//
|
||||
// lblDitheringMode
|
||||
//
|
||||
this.lblDitheringMode.AutoSize = true;
|
||||
this.lblDitheringMode.Location = new System.Drawing.Point(8, 105);
|
||||
this.lblDitheringMode.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
|
||||
this.lblDitheringMode.Name = "lblDitheringMode";
|
||||
this.lblDitheringMode.Size = new System.Drawing.Size(41, 15);
|
||||
this.lblDitheringMode.TabIndex = 7;
|
||||
this.lblDitheringMode.Text = "Mode:";
|
||||
//
|
||||
// cbxDitheringMode
|
||||
//
|
||||
this.cbxDitheringMode.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
|
||||
this.cbxDitheringMode.FormattingEnabled = true;
|
||||
this.cbxDitheringMode.Location = new System.Drawing.Point(75, 99);
|
||||
this.cbxDitheringMode.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
this.cbxDitheringMode.Name = "cbxDitheringMode";
|
||||
this.cbxDitheringMode.Size = new System.Drawing.Size(136, 23);
|
||||
this.cbxDitheringMode.TabIndex = 6;
|
||||
this.cbxDitheringMode.SelectedIndexChanged += new System.EventHandler(this.cbxDitheringMode_SelectedIndexChanged);
|
||||
//
|
||||
// lblDitheringBitDepth
|
||||
//
|
||||
this.lblDitheringBitDepth.AutoSize = true;
|
||||
this.lblDitheringBitDepth.Location = new System.Drawing.Point(8, 74);
|
||||
this.lblDitheringBitDepth.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
|
||||
this.lblDitheringBitDepth.Name = "lblDitheringBitDepth";
|
||||
this.lblDitheringBitDepth.Size = new System.Drawing.Size(60, 15);
|
||||
this.lblDitheringBitDepth.TabIndex = 5;
|
||||
this.lblDitheringBitDepth.Text = "Bit-depth:";
|
||||
//
|
||||
// cbxDitheringBitDepth
|
||||
//
|
||||
this.cbxDitheringBitDepth.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
|
||||
this.cbxDitheringBitDepth.FormattingEnabled = true;
|
||||
this.cbxDitheringBitDepth.Location = new System.Drawing.Point(75, 68);
|
||||
this.cbxDitheringBitDepth.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
this.cbxDitheringBitDepth.Name = "cbxDitheringBitDepth";
|
||||
this.cbxDitheringBitDepth.Size = new System.Drawing.Size(136, 23);
|
||||
this.cbxDitheringBitDepth.TabIndex = 4;
|
||||
this.cbxDitheringBitDepth.SelectedIndexChanged += new System.EventHandler(this.cbxDitheringBitDepth_SelectedIndexChanged);
|
||||
//
|
||||
// chkDitheringEnabled
|
||||
//
|
||||
this.chkDitheringEnabled.AutoSize = true;
|
||||
this.chkDitheringEnabled.Checked = true;
|
||||
this.chkDitheringEnabled.CheckState = System.Windows.Forms.CheckState.Checked;
|
||||
this.chkDitheringEnabled.Location = new System.Drawing.Point(8, 46);
|
||||
this.chkDitheringEnabled.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
this.chkDitheringEnabled.Name = "chkDitheringEnabled";
|
||||
this.chkDitheringEnabled.Size = new System.Drawing.Size(120, 19);
|
||||
this.chkDitheringEnabled.TabIndex = 3;
|
||||
this.chkDitheringEnabled.Text = "Dithering enabled";
|
||||
this.chkDitheringEnabled.ThreeState = true;
|
||||
this.chkDitheringEnabled.UseVisualStyleBackColor = true;
|
||||
this.chkDitheringEnabled.CheckStateChanged += new System.EventHandler(this.chkDitheringEnabled_CheckStateChanged);
|
||||
//
|
||||
// pbGradient
|
||||
//
|
||||
this.pbGradient.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
|
||||
| System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.pbGradient.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
|
||||
this.pbGradient.Location = new System.Drawing.Point(8, 128);
|
||||
this.pbGradient.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
this.pbGradient.Name = "pbGradient";
|
||||
this.pbGradient.Size = new System.Drawing.Size(840, 345);
|
||||
this.pbGradient.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage;
|
||||
this.pbGradient.TabIndex = 0;
|
||||
this.pbGradient.TabStop = false;
|
||||
//
|
||||
// NvDitherPanel
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.Controls.Add(this.grpNvidiaOptions);
|
||||
this.Name = "NvDitherPanel";
|
||||
this.Size = new System.Drawing.Size(864, 485);
|
||||
this.grpNvidiaOptions.ResumeLayout(false);
|
||||
this.grpNvidiaOptions.PerformLayout();
|
||||
((System.ComponentModel.ISupportInitialize)(this.pbGradient)).EndInit();
|
||||
this.ResumeLayout(false);
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.GroupBox grpNvidiaOptions;
|
||||
private System.Windows.Forms.PictureBox pbGradient;
|
||||
private System.Windows.Forms.Label lblDitheringMode;
|
||||
private System.Windows.Forms.ComboBox cbxDitheringMode;
|
||||
private System.Windows.Forms.Label lblDitheringBitDepth;
|
||||
private System.Windows.Forms.ComboBox cbxDitheringBitDepth;
|
||||
private System.Windows.Forms.CheckBox chkDitheringEnabled;
|
||||
private System.Windows.Forms.Label lblDitheringDisplay;
|
||||
private System.Windows.Forms.ComboBox cbxDitheringDisplay;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,148 @@
|
||||
using ColorControl.Shared.Common;
|
||||
using ColorControl.Shared.Forms;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace ColorControl.Services.NVIDIA
|
||||
{
|
||||
public partial class NvDitherPanel : UserControl, IModulePanel
|
||||
{
|
||||
private NvService _nvService;
|
||||
private bool _updatingDitherSettings;
|
||||
private bool _initialized;
|
||||
|
||||
internal NvDitherPanel(NvService nvService)
|
||||
{
|
||||
_nvService = nvService;
|
||||
|
||||
InitializeComponent();
|
||||
|
||||
cbxDitheringBitDepth.Items.AddRange(Utils.GetDescriptions<NvDitherBits>().ToArray());
|
||||
cbxDitheringMode.Items.AddRange(Utils.GetDescriptions<NvDitherMode>().ToArray());
|
||||
FillGradient();
|
||||
|
||||
RefreshDisplays();
|
||||
|
||||
UpdateDitherSettings();
|
||||
|
||||
_initialized = true;
|
||||
|
||||
if (DarkModeUtils.UseDarkMode)
|
||||
{
|
||||
grpNvidiaOptions.ForeColor = FormUtils.CurrentForeColor;
|
||||
}
|
||||
}
|
||||
|
||||
private void RefreshDisplays()
|
||||
{
|
||||
var displays = _nvService.GetSimpleDisplayInfos();
|
||||
|
||||
if (displays == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var primaryDisplay = _nvService.GetPrimaryDisplay();
|
||||
var primaryDisplayInfo = displays.FirstOrDefault(d => d.Display == primaryDisplay);
|
||||
var index = primaryDisplayInfo != null ? displays.IndexOf(primaryDisplayInfo) : 0;
|
||||
|
||||
cbxDitheringDisplay.Items.Clear();
|
||||
cbxDitheringDisplay.Items.AddRange(displays.ToArray());
|
||||
|
||||
if (cbxDitheringDisplay.SelectedIndex == -1)
|
||||
{
|
||||
cbxDitheringDisplay.SelectedIndex = index;
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateDitherSettings()
|
||||
{
|
||||
var display = ((NvDisplayInfo)cbxDitheringDisplay.SelectedItem)?.Display;
|
||||
var ditherInfo = _nvService.GetDithering(display);
|
||||
|
||||
if (ditherInfo.state == -1)
|
||||
{
|
||||
MessageForms.ErrorOk("Error retrieving dithering settings. See log for details.");
|
||||
return;
|
||||
}
|
||||
|
||||
var state = (NvDitherState)ditherInfo.state;
|
||||
|
||||
_updatingDitherSettings = true;
|
||||
try
|
||||
{
|
||||
chkDitheringEnabled.CheckState = state switch { NvDitherState.Enabled => CheckState.Checked, NvDitherState.Disabled => CheckState.Unchecked, _ => CheckState.Indeterminate };
|
||||
cbxDitheringBitDepth.SelectedIndex = ditherInfo.bits;
|
||||
cbxDitheringMode.SelectedIndex = ditherInfo.mode;
|
||||
|
||||
cbxDitheringBitDepth.Enabled = state == NvDitherState.Enabled;
|
||||
cbxDitheringMode.Enabled = state == NvDitherState.Enabled;
|
||||
}
|
||||
finally
|
||||
{
|
||||
_updatingDitherSettings = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void FillGradient()
|
||||
{
|
||||
if (pbGradient.Image == null)
|
||||
{
|
||||
pbGradient.Image = Utils.GenerateGradientBitmap(pbGradient.Width, pbGradient.Height);
|
||||
}
|
||||
}
|
||||
|
||||
private void ApplyDitheringOptions()
|
||||
{
|
||||
if (_updatingDitherSettings)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var state = chkDitheringEnabled.CheckState switch { CheckState.Checked => NvDitherState.Enabled, CheckState.Unchecked => NvDitherState.Disabled, _ => NvDitherState.Auto };
|
||||
var bitDepth = cbxDitheringBitDepth.SelectedIndex;
|
||||
var mode = cbxDitheringMode.SelectedIndex;
|
||||
var display = ((NvDisplayInfo)cbxDitheringDisplay.SelectedItem)?.Display;
|
||||
|
||||
if (_nvService.SetDithering(state, (uint)bitDepth, (uint)(mode > -1 ? mode : (int)NvDitherMode.Temporal), currentDisplay: display) && state == NvDitherState.Auto)
|
||||
{
|
||||
UpdateDitherSettings();
|
||||
}
|
||||
}
|
||||
|
||||
private void cbxDitheringBitDepth_SelectedIndexChanged(object sender, EventArgs e)
|
||||
{
|
||||
ApplyDitheringOptions();
|
||||
}
|
||||
|
||||
private void cbxDitheringMode_SelectedIndexChanged(object sender, EventArgs e)
|
||||
{
|
||||
ApplyDitheringOptions();
|
||||
}
|
||||
|
||||
private void chkDitheringEnabled_CheckStateChanged(object sender, EventArgs e)
|
||||
{
|
||||
cbxDitheringBitDepth.Enabled = chkDitheringEnabled.CheckState == CheckState.Checked;
|
||||
cbxDitheringMode.Enabled = chkDitheringEnabled.CheckState == CheckState.Checked;
|
||||
|
||||
ApplyDitheringOptions();
|
||||
}
|
||||
|
||||
private void cbxDitheringDisplay_SelectedIndexChanged(object sender, EventArgs e)
|
||||
{
|
||||
if (!_initialized)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
UpdateDitherSettings();
|
||||
}
|
||||
|
||||
public void UpdateInfo()
|
||||
{
|
||||
RefreshDisplays();
|
||||
UpdateDitherSettings();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
<root>
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
</root>
|
||||
@@ -0,0 +1,859 @@
|
||||
using ColorControl.Shared.Common;
|
||||
using ColorControl.Shared.Contracts.NVIDIA;
|
||||
using ColorControl.Shared.Forms;
|
||||
using NvAPIWrapper.GPU;
|
||||
using NvAPIWrapper.Native;
|
||||
using NvAPIWrapper.Native.GPU;
|
||||
using NvAPIWrapper.Native.GPU.Structures;
|
||||
using NvAPIWrapper.Native.Interfaces.GPU;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using static NvAPIWrapper.Native.GPU.Structures.PerformanceStates20ClockEntryV1;
|
||||
using static NvAPIWrapper.Native.GPU.Structures.PrivateClockBoostLockV2;
|
||||
|
||||
namespace ColorControl.Services.NVIDIA
|
||||
{
|
||||
public enum NvThermalSensorType
|
||||
{
|
||||
Gpu = 0,
|
||||
HotSpot = 1,
|
||||
Memory = 3
|
||||
}
|
||||
|
||||
public class NvGpuInfo
|
||||
{
|
||||
private static readonly NLog.Logger Logger = NLog.LogManager.GetCurrentClassLogger();
|
||||
|
||||
public PhysicalGPU GPU { get; }
|
||||
public List<ClockBoostLock> ClockBoostLocks { get; private set; } = new();
|
||||
public List<IPerformanceStates20ClockEntry> ClockEntries { get; private set; } = new();
|
||||
public ClockDomainInfo StockGraphicsClock { get; private set; }
|
||||
public ClockDomainInfo StockMemoryClock { get; private set; }
|
||||
public PrivateVFPCurveV3 CurveV3 { get; private set; }
|
||||
public PrivateVFPCurveV1 CurveV1 { get; private set; }
|
||||
public int? DefaultPowerInMilliWatts { get; private set; }
|
||||
public int MinPowerInMilliWatts { get; private set; }
|
||||
public int MaxPowerInMilliWatts { get; private set; }
|
||||
public int MinCoreStepInMHz { get; private set; } = 15;
|
||||
|
||||
public List<NvGpuOcType> SupportedOcTypes { get; private set; } = new();
|
||||
|
||||
public string PCIIdentifier { get; private set; }
|
||||
|
||||
|
||||
public static readonly PublicClockDomain[] Domains = new[] { PublicClockDomain.Graphics, PublicClockDomain.Memory };
|
||||
|
||||
public static NvGpuInfo GetGpuInfo(string pciId)
|
||||
{
|
||||
var gpuHandles = GPUApi.EnumPhysicalGPUs();
|
||||
|
||||
var gpus = gpuHandles.Select(h => new PhysicalGPU(h)).ToList();
|
||||
|
||||
//var displays = Display.GetDisplays();
|
||||
//var gpus = displays.Select(d => d.DisplayDevice.PhysicalGPU).Distinct().ToList();
|
||||
|
||||
var gpu = gpus.FirstOrDefault(g => g.BusInformation.PCIIdentifiers.ToString() == pciId);
|
||||
|
||||
return GetGpuInfo(gpu);
|
||||
}
|
||||
|
||||
public static NvGpuInfo GetGpuInfo(PhysicalGPU gpu)
|
||||
{
|
||||
var gpuInfo = new NvGpuInfo(gpu);
|
||||
|
||||
return gpuInfo;
|
||||
}
|
||||
|
||||
private NvGpuInfo(PhysicalGPU gpu)
|
||||
{
|
||||
GPU = gpu;
|
||||
PCIIdentifier = GPU.BusInformation.PCIIdentifiers.ToString();
|
||||
|
||||
Logger.Swallow(ReadStockClocks);
|
||||
Logger.Swallow(ReadClockEntries);
|
||||
Logger.Swallow(ReadBoostLocks);
|
||||
ReadCurves();
|
||||
Logger.Swallow(ReadMinMaxPower);
|
||||
|
||||
//var handle = gpu.Handle;
|
||||
//var bla2 = GPUApi.GetClockBoostRanges(handle);
|
||||
//var bla3 = GPUApi.GetClockBoostTableV2(handle);
|
||||
|
||||
//for (var i = 0; i < bla3.GPUDeltas.Count(); i++)
|
||||
//{
|
||||
// if (bla3.GPUDeltas[i].ClockType == 0)
|
||||
// {
|
||||
// bla3.GPUDeltas[i].FrequencyDeltaInkHz = 145000;
|
||||
// }
|
||||
// else if (bla3.GPUDeltas[i].ClockType == 1)
|
||||
// {
|
||||
// //bla3.GPUDeltas[i]._FrequencyDeltaInkHz = 50000;
|
||||
// }
|
||||
|
||||
//}
|
||||
|
||||
//GPUApi.SetClockBoostTableV2(handle, bla3);
|
||||
|
||||
//var bla4 = GPUApi.GetAllClockFrequencies(handle);
|
||||
|
||||
SetSupportedOcTypes();
|
||||
}
|
||||
|
||||
private void ReadMinMaxPower()
|
||||
{
|
||||
if (NvidiaML.IsAvailable || NvidiaML.Initialize())
|
||||
{
|
||||
var device = NvidiaML.NvmlDeviceGetHandleByIndex(0);
|
||||
DefaultPowerInMilliWatts = NvidiaML.NvmlDeviceGetPowerManagementDefaultLimit(device.Value);
|
||||
|
||||
var powerLimits = GetPowerLimits();
|
||||
|
||||
if (!DefaultPowerInMilliWatts.HasValue)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
MinPowerInMilliWatts = (int)((decimal)DefaultPowerInMilliWatts / 100000 * powerLimits.Item1);
|
||||
MaxPowerInMilliWatts = (int)((decimal)DefaultPowerInMilliWatts / 100000 * powerLimits.Item2);
|
||||
}
|
||||
}
|
||||
|
||||
private void ReadClockEntries()
|
||||
{
|
||||
var perf = GPUApi.GetPerformanceStates20(GPU.Handle);
|
||||
var clock3D = perf.Clocks.FirstOrDefault(c => c.Key == PerformanceStateId.P0_3DPerformance);
|
||||
ClockEntries = clock3D.Value.ToList();
|
||||
}
|
||||
|
||||
private void ReadStockClocks()
|
||||
{
|
||||
StockGraphicsClock = GPU.BoostClockFrequencies.GraphicsClock;
|
||||
StockMemoryClock = GPU.BoostClockFrequencies.MemoryClock;
|
||||
}
|
||||
|
||||
private void SetSupportedOcTypes()
|
||||
{
|
||||
SupportedOcTypes.Clear();
|
||||
SupportedOcTypes.Add(NvGpuOcType.None);
|
||||
SupportedOcTypes.Add(NvGpuOcType.Offset);
|
||||
|
||||
if (CurveV3.GPUCurveEntries?.Length > 0)
|
||||
{
|
||||
SupportedOcTypes.Add(NvGpuOcType.Curve);
|
||||
SupportedOcTypes.Add(NvGpuOcType.BoostLock);
|
||||
}
|
||||
}
|
||||
|
||||
private void ReadBoostLocks()
|
||||
{
|
||||
var boostLock = GPUApi.GetClockBoostLock(GPU.Handle);
|
||||
ClockBoostLocks = boostLock.ClockBoostLocks.Where(l => l.LockMode == ClockLockMode.Manual).ToList();
|
||||
}
|
||||
|
||||
public (uint, uint) GetPowerLimits()
|
||||
{
|
||||
var power = Logger.Swallow(() => GPU.PerformanceControl.PowerLimitInformation.FirstOrDefault(), default);
|
||||
|
||||
if (power == null)
|
||||
{
|
||||
return (20000, 100000);
|
||||
}
|
||||
|
||||
return (power.MinimumPowerInPCM, power.MaximumPowerInPCM);
|
||||
}
|
||||
|
||||
public uint GetPowerUsageInMilliWatts()
|
||||
{
|
||||
if (DefaultPowerInMilliWatts.HasValue)
|
||||
{
|
||||
return Logger.Swallow(() =>
|
||||
{
|
||||
var powerInPCM = GPU.PowerTopologyInformation.PowerTopologyEntries.FirstOrDefault(e => e.Domain == PowerTopologyDomain.Board);
|
||||
var power = (uint)((decimal)powerInPCM.PowerUsageInPCM / 100000 * DefaultPowerInMilliWatts);
|
||||
|
||||
return power;
|
||||
});
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
private void ReadCurves()
|
||||
{
|
||||
if (!Logger.Swallow(ReadCurveV3, false))
|
||||
{
|
||||
Logger.Swallow(ReadCurveV1);
|
||||
}
|
||||
}
|
||||
|
||||
private bool ReadCurveV3()
|
||||
{
|
||||
CurveV3 = GPUApi.GetVFPCurveV3(GPU.Handle);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool ReadCurveV1()
|
||||
{
|
||||
Logger.Debug($"{GPU.FullName}: CurveV3 not available, falling back to V1");
|
||||
|
||||
MinCoreStepInMHz = 12;
|
||||
|
||||
var bla = GPUApi.GetClockBoostMask(GPU.Handle);
|
||||
|
||||
var masks = bla._Masks;
|
||||
Logger.Debug("MASKS: " + masks[0]);
|
||||
Logger.Debug("MASK: " + bla._Unknown1[0]);
|
||||
|
||||
CurveV1 = GPUApi.GetVFPCurve(GPU.Handle, masks);
|
||||
|
||||
var length = CurveV1.GPUCurveEntries.Length;
|
||||
var minFreq = CurveV1.GPUCurveEntries.Min(e => e.FrequencyInkHz);
|
||||
var maxFreq = CurveV1.GPUCurveEntries.Max(e => e.FrequencyInkHz);
|
||||
var minV = CurveV1.GPUCurveEntries.Min(e => e.VoltageInMicroV);
|
||||
var maxV = CurveV1.GPUCurveEntries.Max(e => e.VoltageInMicroV);
|
||||
|
||||
Logger.Debug($"CurveV1: L: {length}, MinF: {minFreq}, MaxF: {maxFreq}, MinV: {minV}, MaxV: {maxV}");
|
||||
|
||||
foreach (var entry in CurveV1.GPUCurveEntries)
|
||||
{
|
||||
Logger.Debug($"CurveV1: Freq: {entry.FrequencyInkHz}, Volt: {entry.VoltageInMicroV}");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool ApplyOcSettings(NvGpuOcSettings settings)
|
||||
{
|
||||
if (settings.PCIIdentifier != PCIIdentifier)
|
||||
{
|
||||
Logger.Warn($"Cannot apply OC-settings: PCI-identifier does not match GPU: {settings.PCIIdentifier}");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
ResetGpuClocks();
|
||||
|
||||
if (settings.PowerPCM >= 0)
|
||||
{
|
||||
SetPower(settings.PowerPCM);
|
||||
}
|
||||
|
||||
if (settings.Type == NvGpuOcType.None)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (settings.MemoryOffsetKHz != 0)
|
||||
{
|
||||
SetMemoryClockOffsetDelta(settings.MemoryOffsetKHz);
|
||||
}
|
||||
|
||||
if (settings.VoltageBoostPercent >= 0)
|
||||
{
|
||||
SetVoltageBoostPercent(settings.VoltageBoostPercent);
|
||||
}
|
||||
|
||||
if (settings.Type == NvGpuOcType.BoostLock)
|
||||
{
|
||||
LockGpuClock(settings.MaximumVoltageUv, settings.GraphicsOffsetKHz);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if (settings.Type == NvGpuOcType.Offset && settings.MaximumVoltageUv == 0)
|
||||
{
|
||||
SetGraphicsClockOffset(settings.GraphicsOffsetKHz);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
SetCurveOffset(settings.GraphicsOffsetKHz, settings.MaximumVoltageUv, settings.MaximumFrequencyKHz);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void SetPower(uint powerPercent)
|
||||
{
|
||||
if (powerPercent == 0)
|
||||
{
|
||||
powerPercent = 100000;
|
||||
}
|
||||
|
||||
var entry = new PrivatePowerPoliciesStatusV1.PowerPolicyStatusEntry(powerPercent);
|
||||
var status = new PrivatePowerPoliciesStatusV1(new[] { entry });
|
||||
|
||||
GPUApi.ClientPowerPoliciesSetStatus(GPU.Handle, status);
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
var gpuVoltage = GPUApi.GetCurrentVoltage(GPU.Handle).ValueInMicroVolt;
|
||||
|
||||
var temps = GetTemperatures();
|
||||
var power = GetPowerUsageInMilliWatts();
|
||||
|
||||
var sb = new StringBuilder();
|
||||
|
||||
sb.Append($"GPU: {GPU.CurrentClockFrequencies.GraphicsClock.Frequency.ToUnitString()} @ {gpuVoltage / 1000} mV, {temps[NvThermalSensorType.Gpu]}°");
|
||||
|
||||
if (temps.TryGetValue(NvThermalSensorType.HotSpot, out var hotSpotTemp))
|
||||
{
|
||||
sb.Append($"/{hotSpotTemp}°");
|
||||
}
|
||||
|
||||
sb.Append($", Mem: {GPU.CurrentClockFrequencies.MemoryClock.Frequency.ToUnitString()}");
|
||||
|
||||
if (temps.TryGetValue(NvThermalSensorType.Memory, out var memoryTemp))
|
||||
{
|
||||
sb.Append($", {memoryTemp}°");
|
||||
}
|
||||
|
||||
sb.Append($", Pwr: {Math.Round(power / 1000.0, 1)}W");
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
public Dictionary<NvThermalSensorType, double> GetTemperatures()
|
||||
{
|
||||
var temperatures = new Dictionary<NvThermalSensorType, double>();
|
||||
|
||||
try
|
||||
{
|
||||
var temps = GPUApi.QueryThermalSensors(GPU.Handle, 255u);
|
||||
|
||||
var gpuTemp = Math.Round(temps.Temperatures[0], 1);
|
||||
var hotspotTemp = Math.Round(temps.Temperatures[1], 1);
|
||||
var memoryTemp = temps.Temperatures.Last(l => l != 0);
|
||||
|
||||
temperatures.Add(NvThermalSensorType.Gpu, gpuTemp);
|
||||
temperatures.Add(NvThermalSensorType.HotSpot, hotspotTemp);
|
||||
temperatures.Add(NvThermalSensorType.Memory, memoryTemp);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
var gpuThermal = GPU.ThermalInformation.ThermalSensors.FirstOrDefault(s => s.Target == ThermalSettingsTarget.GPU);
|
||||
temperatures.Add(NvThermalSensorType.Gpu, gpuThermal.CurrentTemperature);
|
||||
}
|
||||
|
||||
return temperatures;
|
||||
}
|
||||
|
||||
public (int, int) GetDeltaClockMinMax(PublicClockDomain domain)
|
||||
{
|
||||
var delta = ClockEntries.FirstOrDefault(e => e.DomainId == domain)?.FrequencyDeltaInkHz;
|
||||
|
||||
return (delta?.DeltaRange.Minimum ?? -502000, delta?.DeltaRange.Maximum ?? (domain == PublicClockDomain.Graphics ? 1000000 : 3000000));
|
||||
}
|
||||
|
||||
public PerformanceStates20ParameterDelta? GetDeltaClockLimits(PublicClockDomain domain)
|
||||
{
|
||||
return ClockEntries.FirstOrDefault(e => e.DomainId == domain)?.FrequencyDeltaInkHz;
|
||||
}
|
||||
|
||||
public bool HasLock(PublicClockDomain domain)
|
||||
{
|
||||
return ClockBoostLocks.Any(l => l.ClockDomain == domain && l.LockMode == ClockLockMode.Manual) == true;
|
||||
}
|
||||
|
||||
public int GetOffset(PublicClockDomain domain)
|
||||
{
|
||||
var entry = ClockEntries.FirstOrDefault(e => e.DomainId == domain);
|
||||
|
||||
var value = entry?.FrequencyDeltaInkHz.DeltaValue ?? 0;
|
||||
|
||||
if (value == 0 && domain == PublicClockDomain.Memory && entry != null)
|
||||
{
|
||||
var maxFreq = entry.SingleFrequency.FrequencyInkHz;
|
||||
var defaultFreq = GPU.BoostClockFrequencies.MemoryClock.Frequency;
|
||||
|
||||
value = (int)(maxFreq - defaultFreq);
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
public (uint, int) GetLockedBoost(PublicClockDomain domain)
|
||||
{
|
||||
var boostLock = ClockBoostLocks.FirstOrDefault(l => l.ClockDomain == domain && l.LockMode == ClockLockMode.Manual);
|
||||
|
||||
if (boostLock.LockMode != ClockLockMode.Manual)
|
||||
{
|
||||
return (0, 0);
|
||||
}
|
||||
|
||||
var offset = GetOffset(domain);
|
||||
|
||||
return (boostLock.VoltageInMicroV, offset);
|
||||
}
|
||||
|
||||
public NvGpuOcSettings GetOverclockSettings()
|
||||
{
|
||||
var ocSettings = new NvGpuOcSettings { PCIIdentifier = PCIIdentifier };
|
||||
|
||||
var power = GPUApi.ClientPowerPoliciesGetStatus(GPU.Handle);
|
||||
|
||||
ocSettings.PowerPCM = power.PowerPolicyStatusEntries.FirstOrDefault(e => e.PerformanceStateId == PerformanceStateId.P0_3DPerformance).PowerTargetInPCM;
|
||||
|
||||
var voltageBoost = GPUApi.GetCoreVoltageBoostPercent(GPU.Handle);
|
||||
|
||||
ocSettings.VoltageBoostPercent = voltageBoost.Percent;
|
||||
|
||||
foreach (var domain in Domains)
|
||||
{
|
||||
var locked = GetLockedBoost(domain);
|
||||
|
||||
if (locked.Item1 != 0)
|
||||
{
|
||||
if (ocSettings.Type == NvGpuOcType.None)
|
||||
{
|
||||
ocSettings.Type = NvGpuOcType.BoostLock;
|
||||
}
|
||||
|
||||
ocSettings.MaximumVoltageUv = locked.Item1;
|
||||
|
||||
if (domain == PublicClockDomain.Graphics)
|
||||
{
|
||||
ocSettings.GraphicsOffsetKHz = locked.Item2;
|
||||
|
||||
if (CurveV3.GPUCurveEntries?.Length > 0)
|
||||
{
|
||||
var voltItem = CurveV3.GPUCurveEntries.FirstOrDefault(e => e.DefaultVoltageInMicroV == ocSettings.MaximumVoltageUv);
|
||||
|
||||
if (voltItem.DefaultFrequencyInkHz > 0)
|
||||
{
|
||||
var freq = voltItem.DefaultFrequencyInkHz + ocSettings.GraphicsOffsetKHz;
|
||||
ocSettings.MaximumFrequencyKHz = (uint)freq;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ocSettings.MemoryOffsetKHz = locked.Item2;
|
||||
}
|
||||
}
|
||||
|
||||
if (ocSettings.Type == NvGpuOcType.None && domain == PublicClockDomain.Graphics && CurveV3.GPUCurveEntries != null)
|
||||
{
|
||||
var entry = CurveV3.GPUCurveEntries.MaxBy(e => (int)e.FrequencyInkHz - (int)e.DefaultFrequencyInkHz);
|
||||
var offsetCurve = (int)entry.FrequencyInkHz - (int)entry.DefaultFrequencyInkHz;
|
||||
if (offsetCurve != 0)
|
||||
{
|
||||
var isChanged = CurveV3.GPUCurveEntries.Any(e => e.ClockType == 0 && e.DefaultFrequencyInkHz != 0 && ((int)e.FrequencyInkHz - (int)e.DefaultFrequencyInkHz) != offsetCurve);
|
||||
|
||||
ocSettings.Type = isChanged ? NvGpuOcType.Curve : NvGpuOcType.Offset;
|
||||
ocSettings.GraphicsOffsetKHz = offsetCurve;
|
||||
|
||||
if (offsetCurve > 0 && ocSettings.Type == NvGpuOcType.Curve)
|
||||
{
|
||||
var maxOcEntry = CurveV3.GPUCurveEntries.MaxBy(e => e.FrequencyInkHz);
|
||||
var maxDefEntry = CurveV3.GPUCurveEntries.MaxBy(e => e.DefaultFrequencyInkHz);
|
||||
|
||||
if (maxOcEntry.FrequencyInkHz < maxDefEntry.DefaultFrequencyInkHz)
|
||||
{
|
||||
ocSettings.MaximumVoltageUv = maxOcEntry.VoltageInMicroV;
|
||||
ocSettings.MaximumFrequencyKHz = maxDefEntry.FrequencyInkHz;
|
||||
ocSettings.FrequencyPreferred = ocSettings.MaximumFrequencyKHz > 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ocSettings.Type == NvGpuOcType.None || domain == PublicClockDomain.Memory)
|
||||
{
|
||||
var offset = GetOffset(domain);
|
||||
|
||||
if (offset != 0)
|
||||
{
|
||||
if (ocSettings.Type == NvGpuOcType.None)
|
||||
{
|
||||
ocSettings.Type = NvGpuOcType.Offset;
|
||||
}
|
||||
|
||||
if (domain == PublicClockDomain.Graphics)
|
||||
{
|
||||
ocSettings.GraphicsOffsetKHz = offset;
|
||||
}
|
||||
else
|
||||
{
|
||||
ocSettings.MemoryOffsetKHz = offset;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ocSettings;
|
||||
}
|
||||
|
||||
public void SetGpuClocks(uint lockedVoltageMicroV = 1000000, int coreOffsetKHz = 0, int memOffsetKHz = 0)
|
||||
{
|
||||
var handle = GPU.Handle;
|
||||
|
||||
var perf = GPUApi.GetPerformanceStates20(handle);
|
||||
|
||||
var lockv2 = new PrivateClockBoostLockV2(new[] { new ClockBoostLock(PublicClockDomain.Graphics, ClockLockMode.Manual, lockedVoltageMicroV) });
|
||||
|
||||
var bla = GPUApi.GetClockBoostLock(handle);
|
||||
|
||||
GPUApi.SetClockBoostLock(handle, lockv2);
|
||||
|
||||
//var curve = GPUApi.GetVFPCurve(handle);
|
||||
|
||||
var currentFreq = perf.Clocks.First().Value.First(v => v.DomainId == PublicClockDomain.Graphics).SingleFrequency;
|
||||
|
||||
var delta = new PerformanceStates20ParameterDelta(coreOffsetKHz);
|
||||
//var delta2 = new PerformanceStates20ParameterDelta(0);
|
||||
//var delta3 = new PerformanceStates20ParameterDelta(0);
|
||||
//var single1 = new PerformanceStates20ClockDependentSingleFrequency(2670000);
|
||||
//var single2 = new PerformanceStates20ClockDependentSingleFrequency(2760000);
|
||||
//var single3 = new PerformanceStates20ClockDependentSingleFrequency(2775000);
|
||||
|
||||
//var clockEntry1 = new PerformanceStates20ClockEntryV1(NvAPIWrapper.Native.GPU.PublicClockDomain.Graphics, delta, single1);
|
||||
//var clockEntry2 = new PerformanceStates20ClockEntryV1(NvAPIWrapper.Native.GPU.PublicClockDomain.Graphics, delta2, single2);
|
||||
//var clockEntry3 = new PerformanceStates20ClockEntryV1(NvAPIWrapper.Native.GPU.PublicClockDomain.Graphics, delta3, single3);
|
||||
|
||||
var range = new PerformanceStates20ClockDependentFrequencyRange(2400000, 3000000, PerformanceVoltageDomain.Core, 950000, 1050000);
|
||||
var clockEntry = new PerformanceStates20ClockEntryV1(PublicClockDomain.Graphics, delta, range);
|
||||
|
||||
var memDelta = new PerformanceStates20ParameterDelta(memOffsetKHz);
|
||||
var memClockEntry = new PerformanceStates20ClockEntryV1(PublicClockDomain.Memory, memDelta);
|
||||
|
||||
//var range2 = new PerformanceStates20ClockDependentFrequencyRange(2800001, 3000000, NvAPIWrapper.Native.GPU.PerformanceVoltageDomain.Core, 1000000, 1000000);
|
||||
//var clockEntry2 = new PerformanceStates20ClockEntryV1(NvAPIWrapper.Native.GPU.PublicClockDomain.Graphics, delta2, range2);
|
||||
|
||||
var deltaVoltage = new PerformanceStates20ParameterDelta(0);
|
||||
var voltage = new PerformanceStates20BaseVoltageEntryV1(PerformanceVoltageDomain.Core, deltaVoltage);
|
||||
|
||||
var state = new PerformanceStates20InfoV1.PerformanceState20(PerformanceStateId.P0_3DPerformance, new[] { clockEntry, memClockEntry }, new[] { voltage });
|
||||
|
||||
var newPerf = new PerformanceStates20InfoV3(new[] { state }, 2, 1);
|
||||
|
||||
GPUApi.SetPerformanceStates20(handle, newPerf);
|
||||
}
|
||||
|
||||
public void LockGpuClock(uint lockedVoltageMicroV = 1000000, int coreOffsetKHz = 0)
|
||||
{
|
||||
var handle = GPU.Handle;
|
||||
|
||||
var lockv2 = new PrivateClockBoostLockV2(new[] { new ClockBoostLock(PublicClockDomain.Graphics, ClockLockMode.Manual, lockedVoltageMicroV) });
|
||||
|
||||
GPUApi.SetClockBoostLock(handle, lockv2);
|
||||
|
||||
var delta = new PerformanceStates20ParameterDelta(coreOffsetKHz);
|
||||
|
||||
var range = new PerformanceStates20ClockDependentFrequencyRange(1200000, 3000000, PerformanceVoltageDomain.Core, 0, 0);
|
||||
var clockEntry = new PerformanceStates20ClockEntryV1(PublicClockDomain.Graphics, delta, range);
|
||||
|
||||
var state = new PerformanceStates20InfoV1.PerformanceState20(PerformanceStateId.P0_3DPerformance, new[] { clockEntry }, Array.Empty<PerformanceStates20BaseVoltageEntryV1>());
|
||||
|
||||
var newPerf = new PerformanceStates20InfoV3(new[] { state }, 1, 1);
|
||||
|
||||
GPUApi.SetPerformanceStates20(handle, newPerf);
|
||||
}
|
||||
|
||||
public void SetGraphicsClockOffset(int coreOffsetKHz = 0)
|
||||
{
|
||||
var delta = new PerformanceStates20ParameterDelta(coreOffsetKHz);
|
||||
|
||||
var range = new PerformanceStates20ClockDependentFrequencyRange(1200000, 3000000, PerformanceVoltageDomain.Core, 0, 0);
|
||||
var clockEntry = new PerformanceStates20ClockEntryV1(PublicClockDomain.Graphics, delta, range);
|
||||
|
||||
var state = new PerformanceStates20InfoV1.PerformanceState20(PerformanceStateId.P0_3DPerformance, new[] { clockEntry }, Array.Empty<PerformanceStates20BaseVoltageEntryV1>());
|
||||
|
||||
var newPerf = new PerformanceStates20InfoV3(new[] { state }, 1, 0);
|
||||
|
||||
GPUApi.SetPerformanceStates20(GPU.Handle, newPerf);
|
||||
}
|
||||
|
||||
public void SetMemoryClockOffsetDelta(int memOffsetKHz = 0)
|
||||
{
|
||||
var handle = GPU.Handle;
|
||||
|
||||
var memDelta = new PerformanceStates20ParameterDelta(memOffsetKHz);
|
||||
var memClockEntry = new PerformanceStates20ClockEntryV1(PublicClockDomain.Memory, memDelta);
|
||||
|
||||
var state = new PerformanceStates20InfoV1.PerformanceState20(PerformanceStateId.P0_3DPerformance, new[] { memClockEntry }, Array.Empty<PerformanceStates20BaseVoltageEntryV1>());
|
||||
|
||||
var newPerf = new PerformanceStates20InfoV3(new[] { state }, 1, 0);
|
||||
|
||||
GPUApi.SetPerformanceStates20(handle, newPerf);
|
||||
}
|
||||
|
||||
public void SetMemoryClockOffsetRange(int memOffsetKHz = 0)
|
||||
{
|
||||
var handle = GPU.Handle;
|
||||
|
||||
var memDelta = new PerformanceStates20ParameterDelta(0);
|
||||
|
||||
var defaultFreq = GPU.BoostClockFrequencies.MemoryClock.Frequency;
|
||||
var newFreq = (uint)(defaultFreq + memOffsetKHz);
|
||||
|
||||
var memFreq = new PerformanceStates20ClockDependentFrequencyRange(newFreq, newFreq, PerformanceVoltageDomain.Undefined, 0, 0);
|
||||
var memFreq2 = new PerformanceStates20ClockDependentSingleFrequency(newFreq);
|
||||
var memClockEntry = new PerformanceStates20ClockEntryV1(PublicClockDomain.Memory, memDelta, memFreq);
|
||||
var memClockEntry2 = new PerformanceStates20ClockEntryV1(PublicClockDomain.Memory, memDelta, memFreq2);
|
||||
|
||||
var state = new PerformanceStates20InfoV1.PerformanceState20(PerformanceStateId.P0_3DPerformance, new[] { memClockEntry, memClockEntry2 }, Array.Empty<PerformanceStates20BaseVoltageEntryV1>());
|
||||
|
||||
var newPerf = new PerformanceStates20InfoV3(new[] { state }, 1, 0);
|
||||
|
||||
GPUApi.SetPerformanceStates20(handle, newPerf);
|
||||
}
|
||||
|
||||
public void SetCurveOffset(int offsetKHz = 0, uint maxVoltageUv = 0, uint maxFreqKHz = 0)
|
||||
{
|
||||
if ((CurveV3.GPUCurveEntries?.Length ?? 0) == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var normalizedOffset = (offsetKHz / MinCoreStepInMHz) * MinCoreStepInMHz;
|
||||
|
||||
var handle = GPU.Handle;
|
||||
|
||||
var boostTable = GPUApi.GetClockBoostTableV2(handle);
|
||||
|
||||
var curveEntries = CurveV3.GPUCurveEntries;
|
||||
|
||||
if (maxVoltageUv > 0)
|
||||
{
|
||||
var newCurveEntryVolt = curveEntries.FirstOrDefault(e => e.DefaultVoltageInMicroV == maxVoltageUv);
|
||||
var newFreq = (uint)(newCurveEntryVolt.DefaultFrequencyInkHz + offsetKHz);
|
||||
var newCurveEntryFreq = curveEntries.FirstOrDefault(e => e.DefaultFrequencyInkHz == newFreq);
|
||||
|
||||
maxFreqKHz = newFreq;
|
||||
}
|
||||
|
||||
for (var i = 0; i < boostTable.GPUDeltas.Count(); i++)
|
||||
{
|
||||
if (boostTable.GPUDeltas[i].ClockType != 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
var curOffset = offsetKHz;
|
||||
|
||||
if (maxFreqKHz > 0 && CurveV3.GPUCurveEntries?.Length > i)
|
||||
{
|
||||
var curveEntry = CurveV3.GPUCurveEntries[i];
|
||||
|
||||
if (curveEntry.DefaultFrequencyInkHz + offsetKHz > maxFreqKHz)
|
||||
{
|
||||
curOffset += (int)(maxFreqKHz - (curveEntry.DefaultFrequencyInkHz + offsetKHz));
|
||||
}
|
||||
}
|
||||
|
||||
boostTable.GPUDeltas[i].FrequencyDeltaInkHz = curOffset;
|
||||
|
||||
}
|
||||
GPUApi.SetClockBoostTableV2(handle, boostTable);
|
||||
|
||||
ReadCurves();
|
||||
}
|
||||
|
||||
public void ResetGpuClocks()
|
||||
{
|
||||
var handle = GPU.Handle;
|
||||
|
||||
var lockv2 = new PrivateClockBoostLockV2(new[] { new ClockBoostLock(PublicClockDomain.Graphics, ClockLockMode.None, 0) });
|
||||
|
||||
GPUApi.SetClockBoostLock(handle, lockv2);
|
||||
|
||||
SetMemoryClockOffsetDelta(0);
|
||||
SetGraphicsClockOffset(0);
|
||||
SetCurveOffset(0);
|
||||
SetVoltageBoostPercent(0);
|
||||
}
|
||||
|
||||
public uint GetGpuVoltage()
|
||||
{
|
||||
var voltage = GPUApi.GetCurrentVoltage(GPU.Handle);
|
||||
|
||||
return voltage.ValueInMicroVolt;
|
||||
}
|
||||
|
||||
public void SetVoltageBoostPercent(uint percent)
|
||||
{
|
||||
var voltBoost = new PrivateVoltageBoostPercentV1(percent);
|
||||
|
||||
GPUApi.SetCoreVoltageBoostPercent(GPU.Handle, voltBoost);
|
||||
}
|
||||
|
||||
public string GetGpuLimits()
|
||||
{
|
||||
var handle = GPU.Handle;
|
||||
|
||||
var perf = GPUApi.GetPerformanceStates20(handle);
|
||||
var clock3D = perf.Clocks.FirstOrDefault(c => c.Key == NvAPIWrapper.Native.GPU.PerformanceStateId.P0_3DPerformance);
|
||||
|
||||
var boostLock = GPUApi.GetClockBoostLock(handle);
|
||||
|
||||
var clockFreqs = GPUApi.GetAllClockFrequencies(handle);
|
||||
|
||||
//GPUApi.ClientPowerPoliciesGetStatus(handle);
|
||||
|
||||
//var mask = GPUApi.GetClockBoostMask(handle);
|
||||
|
||||
//var ranges = GPUApi.GetClockBoostRanges(handle);
|
||||
|
||||
//var table = GPUApi.GetClockBoostTable(handle);
|
||||
|
||||
var voltageBoost = GPUApi.GetCoreVoltageBoostPercent(handle);
|
||||
|
||||
//var voltage = GPUApi.GetCurrentVoltage(handle);
|
||||
|
||||
//var dynPerf = GPUApi.GetDynamicPerformanceStatesInfoEx(handle);
|
||||
|
||||
//var pols = GPUApi.PerformancePoliciesGetInfo(handle);
|
||||
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
internal FieldDefinition GetCoreOffsetField(NvGpuOcSettings settings)
|
||||
{
|
||||
var graphicsDelta = GetDeltaClockMinMax(PublicClockDomain.Graphics);
|
||||
|
||||
//var field = new FieldDefinition
|
||||
//{
|
||||
// Label = $"Core offset in MHz ({graphicsDelta.Item1.ToUnitString()} to {graphicsDelta.Item2.ToUnitString()})",
|
||||
// FieldType = FieldType.Numeric,
|
||||
// MinValue = graphicsDelta.Item1 / 1000,
|
||||
// MaxValue = graphicsDelta.Item2 / 1000,
|
||||
// Value = settings.GraphicsOffsetKHz / 1000
|
||||
//};
|
||||
|
||||
var field = new FieldDefinition
|
||||
{
|
||||
Label = $"Core offset in MHz ({graphicsDelta.Item1.ToUnitString()} to {graphicsDelta.Item2.ToUnitString()})",
|
||||
FieldType = FieldType.TrackBar,
|
||||
MinValue = graphicsDelta.Item1 / 1000,
|
||||
MaxValue = graphicsDelta.Item2 / 1000,
|
||||
Value = settings.GraphicsOffsetKHz / 1000,
|
||||
StepSize = MinCoreStepInMHz
|
||||
};
|
||||
|
||||
return field;
|
||||
}
|
||||
|
||||
internal FieldDefinition GetMemoryOffsetField(NvGpuOcSettings settings)
|
||||
{
|
||||
var memoryDelta = GetDeltaClockMinMax(PublicClockDomain.Memory);
|
||||
|
||||
//var field = new FieldDefinition
|
||||
//{
|
||||
// Label = $"Memory offset in MHz ({memoryDelta.Item1.ToUnitString()} to {memoryDelta.Item2.ToUnitString()})",
|
||||
// FieldType = FieldType.Numeric,
|
||||
// MinValue = memoryDelta.Item1 / 1000,
|
||||
// MaxValue = memoryDelta.Item2 / 1000,
|
||||
// Value = settings.MemoryOffsetKHz / 1000
|
||||
//};
|
||||
|
||||
var field = new FieldDefinition
|
||||
{
|
||||
Label = $"Memory offset in MHz ({memoryDelta.Item1.ToUnitString()} to {memoryDelta.Item2.ToUnitString()})",
|
||||
FieldType = FieldType.TrackBar,
|
||||
MinValue = memoryDelta.Item1 / 1000,
|
||||
MaxValue = memoryDelta.Item2 / 1000,
|
||||
Value = settings.MemoryOffsetKHz / 1000,
|
||||
StepSize = 25
|
||||
};
|
||||
|
||||
return field;
|
||||
}
|
||||
|
||||
internal FieldDefinition GetPowerField(NvGpuOcSettings settings)
|
||||
{
|
||||
var powerLimits = GetPowerLimits();
|
||||
|
||||
var defaultPowerLimitMw = DefaultPowerInMilliWatts;
|
||||
|
||||
if (settings.PowerPCM == 0)
|
||||
{
|
||||
settings.PowerPCM = NvGpuOcSettings.DefaultPowerPCM;
|
||||
}
|
||||
else if (settings.PowerPCM < powerLimits.Item1)
|
||||
{
|
||||
settings.PowerPCM = powerLimits.Item1;
|
||||
}
|
||||
|
||||
var powerField = defaultPowerLimitMw > 0 ?
|
||||
new FieldDefinition
|
||||
{
|
||||
Label = $"Power limit in watts. Min: {MinPowerInMilliWatts / 1000}, max: {MaxPowerInMilliWatts / 1000}",
|
||||
FieldType = FieldType.TrackBar,
|
||||
Value = (int)Math.Round((decimal)defaultPowerLimitMw / 100000000 * settings.PowerPCM),
|
||||
MinValue = MinPowerInMilliWatts / 1000,
|
||||
MaxValue = MaxPowerInMilliWatts / 1000
|
||||
}
|
||||
: new FieldDefinition
|
||||
{
|
||||
Label = $"Power limit in PCM (per cent mille). Min: {powerLimits.Item1}, max: {powerLimits.Item2}",
|
||||
FieldType = FieldType.TrackBar,
|
||||
Value = settings.PowerPCM,
|
||||
MinValue = powerLimits.Item1,
|
||||
MaxValue = powerLimits.Item2
|
||||
};
|
||||
|
||||
return powerField;
|
||||
}
|
||||
|
||||
internal FieldDefinition GetVoltageBoostField(NvGpuOcSettings settings)
|
||||
{
|
||||
var field = new FieldDefinition
|
||||
{
|
||||
Label = "Voltage boost in %",
|
||||
FieldType = FieldType.TrackBar,
|
||||
Value = settings.VoltageBoostPercent,
|
||||
MinValue = 0,
|
||||
MaxValue = 100
|
||||
};
|
||||
|
||||
return field;
|
||||
}
|
||||
|
||||
internal (FieldDefinition, FieldDefinition) GetCurveVoltFreqFields(NvGpuOcSettings settings)
|
||||
{
|
||||
var curveEntries = CurveV3.GPUCurveEntries;
|
||||
|
||||
var graphicsDelta = GetDeltaClockMinMax(PublicClockDomain.Graphics);
|
||||
|
||||
var minCurveFreq = curveEntries.Max(e => e.DefaultFrequencyInkHz) + graphicsDelta.Item1;
|
||||
var freqValues = curveEntries
|
||||
.Where(e => e.DefaultFrequencyInkHz == 0 || e.DefaultFrequencyInkHz >= minCurveFreq)
|
||||
.Select(e => (e.DefaultFrequencyInkHz / 1000).ToString()).Distinct()
|
||||
.OrderBy(x => x)
|
||||
.ToList();
|
||||
var voltValues = curveEntries
|
||||
.Where(e => (e.DefaultVoltageInMicroV == 0 || e.DefaultFrequencyInkHz >= minCurveFreq) && e.DefaultVoltageInMicroV <= 1100000)
|
||||
.OrderBy(e => e.DefaultVoltageInMicroV)
|
||||
.Select(e => (e.DefaultVoltageInMicroV / 1000).ToString())
|
||||
.Distinct()
|
||||
.ToList();
|
||||
|
||||
var voltField = new FieldDefinition
|
||||
{
|
||||
Label = "Optional undervolt: maximum voltage in millivolt (0 = disabled)",
|
||||
SubLabel = "If both UV voltage and UV frequency are set, frequency is derived from voltage.",
|
||||
FieldType = FieldType.DropDown,
|
||||
Value = settings.FrequencyPreferred ? 0 : settings.MaximumVoltageUv / 1000,
|
||||
Values = voltValues,
|
||||
};
|
||||
var freqField = new FieldDefinition
|
||||
{
|
||||
Label = "Optional undervolt: maximum core frequency in MHz (0 = disabled)",
|
||||
FieldType = FieldType.DropDown,
|
||||
Value = !settings.FrequencyPreferred ? 0 : settings.MaximumFrequencyKHz / 1000,
|
||||
Values = freqValues,
|
||||
};
|
||||
|
||||
return (voltField, freqField);
|
||||
}
|
||||
|
||||
public uint PowerToPCM(uint power, bool powerInMilliWatts)
|
||||
{
|
||||
return powerInMilliWatts ? (uint)((decimal)power / DefaultPowerInMilliWatts * 100000000) : power * 1000;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
namespace ColorControl.Services.NVIDIA
|
||||
{
|
||||
partial class NvInfoPanel
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Component Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
grpNVIDIAInfo = new System.Windows.Forms.GroupBox();
|
||||
btnRefreshNVIDIAInfo = new System.Windows.Forms.Button();
|
||||
tvNVIDIAInfo = new System.Windows.Forms.TreeView();
|
||||
grpNVIDIAInfo.SuspendLayout();
|
||||
SuspendLayout();
|
||||
//
|
||||
// grpNVIDIAInfo
|
||||
//
|
||||
grpNVIDIAInfo.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right;
|
||||
grpNVIDIAInfo.Controls.Add(btnRefreshNVIDIAInfo);
|
||||
grpNVIDIAInfo.Controls.Add(tvNVIDIAInfo);
|
||||
grpNVIDIAInfo.Location = new System.Drawing.Point(4, 3);
|
||||
grpNVIDIAInfo.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
grpNVIDIAInfo.Name = "grpNVIDIAInfo";
|
||||
grpNVIDIAInfo.Padding = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
grpNVIDIAInfo.Size = new System.Drawing.Size(643, 547);
|
||||
grpNVIDIAInfo.TabIndex = 5;
|
||||
grpNVIDIAInfo.TabStop = false;
|
||||
grpNVIDIAInfo.Text = "NVIDIA info";
|
||||
//
|
||||
// btnRefreshNVIDIAInfo
|
||||
//
|
||||
btnRefreshNVIDIAInfo.Anchor = System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left;
|
||||
btnRefreshNVIDIAInfo.Location = new System.Drawing.Point(8, 514);
|
||||
btnRefreshNVIDIAInfo.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
btnRefreshNVIDIAInfo.Name = "btnRefreshNVIDIAInfo";
|
||||
btnRefreshNVIDIAInfo.Size = new System.Drawing.Size(88, 27);
|
||||
btnRefreshNVIDIAInfo.TabIndex = 1;
|
||||
btnRefreshNVIDIAInfo.Text = "Refresh";
|
||||
btnRefreshNVIDIAInfo.UseVisualStyleBackColor = true;
|
||||
btnRefreshNVIDIAInfo.Click += btnRefreshNVIDIAInfo_Click;
|
||||
//
|
||||
// tvNVIDIAInfo
|
||||
//
|
||||
tvNVIDIAInfo.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right;
|
||||
tvNVIDIAInfo.Location = new System.Drawing.Point(8, 22);
|
||||
tvNVIDIAInfo.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
tvNVIDIAInfo.Name = "tvNVIDIAInfo";
|
||||
tvNVIDIAInfo.Size = new System.Drawing.Size(627, 486);
|
||||
tvNVIDIAInfo.TabIndex = 0;
|
||||
//
|
||||
// NvInfoPanel
|
||||
//
|
||||
AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
|
||||
AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
Controls.Add(grpNVIDIAInfo);
|
||||
Name = "NvInfoPanel";
|
||||
Size = new System.Drawing.Size(654, 556);
|
||||
grpNVIDIAInfo.ResumeLayout(false);
|
||||
ResumeLayout(false);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.GroupBox grpNVIDIAInfo;
|
||||
private System.Windows.Forms.Button btnRefreshNVIDIAInfo;
|
||||
private System.Windows.Forms.TreeView tvNVIDIAInfo;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
using ColorControl.Shared.Forms;
|
||||
using NvAPIWrapper.Display;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace ColorControl.Services.NVIDIA
|
||||
{
|
||||
public partial class NvInfoPanel : UserControl, IModulePanel
|
||||
{
|
||||
private NvService _nvService;
|
||||
|
||||
internal NvInfoPanel(NvService nvService)
|
||||
{
|
||||
_nvService = nvService;
|
||||
|
||||
InitializeComponent();
|
||||
|
||||
if (DarkModeUtils.UseDarkMode)
|
||||
{
|
||||
grpNVIDIAInfo.ForeColor = FormUtils.CurrentForeColor;
|
||||
}
|
||||
|
||||
RefreshInfo();
|
||||
}
|
||||
|
||||
public void UpdateInfo()
|
||||
{
|
||||
RefreshInfo();
|
||||
}
|
||||
|
||||
private void btnRefreshNVIDIAInfo_Click(object sender, System.EventArgs e)
|
||||
{
|
||||
}
|
||||
|
||||
private void RefreshInfo()
|
||||
{
|
||||
tvNVIDIAInfo.Nodes.Clear();
|
||||
var displays = Display.GetDisplays();
|
||||
for (var i = 0; i < displays.Length; i++)
|
||||
{
|
||||
var display = displays[i];
|
||||
var node = TreeNodeBuilder.CreateTree(display, $"Display[{i}]");
|
||||
tvNVIDIAInfo.Nodes.Add(node);
|
||||
}
|
||||
|
||||
for (var i = 0; i < tvNVIDIAInfo.Nodes.Count; i++)
|
||||
{
|
||||
var node = tvNVIDIAInfo.Nodes[i];
|
||||
node.Expand();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing"">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
</root>
|
||||
+782
@@ -0,0 +1,782 @@
|
||||
|
||||
namespace ColorControl.Services.NVIDIA
|
||||
{
|
||||
partial class NvPanel
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Component Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
components = new System.ComponentModel.Container();
|
||||
lblNvOverclock = new System.Windows.Forms.Label();
|
||||
edtNvOverclock = new System.Windows.Forms.TextBox();
|
||||
btnNvSetClocks = new System.Windows.Forms.Button();
|
||||
lblNvGpuInfo = new System.Windows.Forms.Label();
|
||||
edtNvGpuInfo = new System.Windows.Forms.TextBox();
|
||||
lblNvGPU = new System.Windows.Forms.Label();
|
||||
cbxNvGPU = new System.Windows.Forms.ComboBox();
|
||||
btnNvSettings = new System.Windows.Forms.Button();
|
||||
chkNvShowInQuickAccess = new System.Windows.Forms.CheckBox();
|
||||
lblNvPresetName = new System.Windows.Forms.Label();
|
||||
edtNvPresetName = new System.Windows.Forms.TextBox();
|
||||
btnAddModesNv = new System.Windows.Forms.Button();
|
||||
btnNvPresetDelete = new System.Windows.Forms.Button();
|
||||
lblError = new System.Windows.Forms.Label();
|
||||
btnClone = new System.Windows.Forms.Button();
|
||||
btnNvPresetSave = new System.Windows.Forms.Button();
|
||||
lblShortcut = new System.Windows.Forms.Label();
|
||||
edtShortcut = new System.Windows.Forms.TextBox();
|
||||
btnChange = new System.Windows.Forms.Button();
|
||||
mnuNvPresets = new System.Windows.Forms.ContextMenuStrip(components);
|
||||
miNvApply = new System.Windows.Forms.ToolStripMenuItem();
|
||||
miNvPresetApplyOnStartup = new System.Windows.Forms.ToolStripMenuItem();
|
||||
tssNvPresetMenu = new System.Windows.Forms.ToolStripSeparator();
|
||||
mnuNvDisplay = new System.Windows.Forms.ToolStripMenuItem();
|
||||
miNvPrimaryDisplay = new System.Windows.Forms.ToolStripMenuItem();
|
||||
mnuNvPresetsColorSettings = new System.Windows.Forms.ToolStripMenuItem();
|
||||
miNvPresetColorSettings = new System.Windows.Forms.ToolStripMenuItem();
|
||||
mnuRefreshRate = new System.Windows.Forms.ToolStripMenuItem();
|
||||
miRefreshRateIncluded = new System.Windows.Forms.ToolStripMenuItem();
|
||||
mnuNvResolution = new System.Windows.Forms.ToolStripMenuItem();
|
||||
miNvResolutionIncluded = new System.Windows.Forms.ToolStripMenuItem();
|
||||
miNvPresetDithering = new System.Windows.Forms.ToolStripMenuItem();
|
||||
miNvPresetApplyDithering = new System.Windows.Forms.ToolStripMenuItem();
|
||||
miNvPresetDitheringEnabled = new System.Windows.Forms.ToolStripMenuItem();
|
||||
mnuNvDitheringBitDepth = new System.Windows.Forms.ToolStripMenuItem();
|
||||
miNvDithering6bit = new System.Windows.Forms.ToolStripMenuItem();
|
||||
miNvDithering8bit = new System.Windows.Forms.ToolStripMenuItem();
|
||||
miNvDithering10bit = new System.Windows.Forms.ToolStripMenuItem();
|
||||
mnuNvDitheringMode = new System.Windows.Forms.ToolStripMenuItem();
|
||||
spatial1ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
spatial2ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
spatialDynamic2x2ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
spatialStatic2x2ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
temporalToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
miNvHDR = new System.Windows.Forms.ToolStripMenuItem();
|
||||
miHDRIncluded = new System.Windows.Forms.ToolStripMenuItem();
|
||||
miToggleHDR = new System.Windows.Forms.ToolStripMenuItem();
|
||||
miHDREnabled = new System.Windows.Forms.ToolStripMenuItem();
|
||||
mnuNvDriverSettings = new System.Windows.Forms.ToolStripMenuItem();
|
||||
miNvDriverSettingsIncluded = new System.Windows.Forms.ToolStripMenuItem();
|
||||
mnuNvOtherSettings = new System.Windows.Forms.ToolStripMenuItem();
|
||||
miNvOtherIncluded = new System.Windows.Forms.ToolStripMenuItem();
|
||||
mnuNvHdmiSettings = new System.Windows.Forms.ToolStripMenuItem();
|
||||
miNvHdmiIncluded = new System.Windows.Forms.ToolStripMenuItem();
|
||||
mnuNvOverclocking = new System.Windows.Forms.ToolStripMenuItem();
|
||||
miNvOverclockingIncluded = new System.Windows.Forms.ToolStripMenuItem();
|
||||
miNvCopyId = new System.Windows.Forms.ToolStripMenuItem();
|
||||
btnApply = new System.Windows.Forms.Button();
|
||||
lvNvPresets = new System.Windows.Forms.ListView();
|
||||
mnuNvSettings = new System.Windows.Forms.ContextMenuStrip(components);
|
||||
miNvProfileInspector = new System.Windows.Forms.ToolStripMenuItem();
|
||||
miNvNovideo = new System.Windows.Forms.ToolStripMenuItem();
|
||||
miNvSettings = new System.Windows.Forms.ToolStripMenuItem();
|
||||
miNvTestDithering = new System.Windows.Forms.ToolStripMenuItem();
|
||||
lvNvPresetsToolTip = new System.Windows.Forms.ToolTip(components);
|
||||
miNVIDIAInfo = new System.Windows.Forms.ToolStripMenuItem();
|
||||
mnuNvPresets.SuspendLayout();
|
||||
mnuNvSettings.SuspendLayout();
|
||||
SuspendLayout();
|
||||
//
|
||||
// lblNvOverclock
|
||||
//
|
||||
lblNvOverclock.Anchor = System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left;
|
||||
lblNvOverclock.AutoSize = true;
|
||||
lblNvOverclock.Location = new System.Drawing.Point(578, 496);
|
||||
lblNvOverclock.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
|
||||
lblNvOverclock.Name = "lblNvOverclock";
|
||||
lblNvOverclock.Size = new System.Drawing.Size(51, 15);
|
||||
lblNvOverclock.TabIndex = 66;
|
||||
lblNvOverclock.Text = "OC info:";
|
||||
//
|
||||
// edtNvOverclock
|
||||
//
|
||||
edtNvOverclock.Anchor = System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right;
|
||||
edtNvOverclock.Enabled = false;
|
||||
edtNvOverclock.Location = new System.Drawing.Point(648, 493);
|
||||
edtNvOverclock.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
edtNvOverclock.Name = "edtNvOverclock";
|
||||
edtNvOverclock.Size = new System.Drawing.Size(457, 23);
|
||||
edtNvOverclock.TabIndex = 65;
|
||||
//
|
||||
// btnNvSetClocks
|
||||
//
|
||||
btnNvSetClocks.Anchor = System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left;
|
||||
btnNvSetClocks.Location = new System.Drawing.Point(868, 433);
|
||||
btnNvSetClocks.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
btnNvSetClocks.Name = "btnNvSetClocks";
|
||||
btnNvSetClocks.Size = new System.Drawing.Size(88, 27);
|
||||
btnNvSetClocks.TabIndex = 64;
|
||||
btnNvSetClocks.Text = "Change OC...";
|
||||
btnNvSetClocks.UseVisualStyleBackColor = true;
|
||||
btnNvSetClocks.Click += btnNvSetClocks_Click;
|
||||
//
|
||||
// lblNvGpuInfo
|
||||
//
|
||||
lblNvGpuInfo.Anchor = System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left;
|
||||
lblNvGpuInfo.AutoSize = true;
|
||||
lblNvGpuInfo.Location = new System.Drawing.Point(578, 469);
|
||||
lblNvGpuInfo.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
|
||||
lblNvGpuInfo.Name = "lblNvGpuInfo";
|
||||
lblNvGpuInfo.Size = new System.Drawing.Size(31, 15);
|
||||
lblNvGpuInfo.TabIndex = 63;
|
||||
lblNvGpuInfo.Text = "Info:";
|
||||
//
|
||||
// edtNvGpuInfo
|
||||
//
|
||||
edtNvGpuInfo.Anchor = System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right;
|
||||
edtNvGpuInfo.Enabled = false;
|
||||
edtNvGpuInfo.Location = new System.Drawing.Point(648, 466);
|
||||
edtNvGpuInfo.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
edtNvGpuInfo.Name = "edtNvGpuInfo";
|
||||
edtNvGpuInfo.Size = new System.Drawing.Size(457, 23);
|
||||
edtNvGpuInfo.TabIndex = 62;
|
||||
//
|
||||
// lblNvGPU
|
||||
//
|
||||
lblNvGPU.Anchor = System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left;
|
||||
lblNvGPU.AutoSize = true;
|
||||
lblNvGPU.Location = new System.Drawing.Point(578, 439);
|
||||
lblNvGPU.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
|
||||
lblNvGPU.Name = "lblNvGPU";
|
||||
lblNvGPU.Size = new System.Drawing.Size(33, 15);
|
||||
lblNvGPU.TabIndex = 61;
|
||||
lblNvGPU.Text = "GPU:";
|
||||
//
|
||||
// cbxNvGPU
|
||||
//
|
||||
cbxNvGPU.Anchor = System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left;
|
||||
cbxNvGPU.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
|
||||
cbxNvGPU.FormattingEnabled = true;
|
||||
cbxNvGPU.Location = new System.Drawing.Point(648, 436);
|
||||
cbxNvGPU.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
cbxNvGPU.Name = "cbxNvGPU";
|
||||
cbxNvGPU.Size = new System.Drawing.Size(212, 23);
|
||||
cbxNvGPU.TabIndex = 60;
|
||||
cbxNvGPU.SelectedIndexChanged += cbxNvGPU_SelectedIndexChanged;
|
||||
//
|
||||
// btnNvSettings
|
||||
//
|
||||
btnNvSettings.Anchor = System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right;
|
||||
btnNvSettings.Location = new System.Drawing.Point(1017, 428);
|
||||
btnNvSettings.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
btnNvSettings.Name = "btnNvSettings";
|
||||
btnNvSettings.Size = new System.Drawing.Size(88, 27);
|
||||
btnNvSettings.TabIndex = 59;
|
||||
btnNvSettings.Text = "Settings...";
|
||||
btnNvSettings.UseVisualStyleBackColor = true;
|
||||
btnNvSettings.Click += btnNvSettings_Click;
|
||||
//
|
||||
// chkNvShowInQuickAccess
|
||||
//
|
||||
chkNvShowInQuickAccess.Anchor = System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left;
|
||||
chkNvShowInQuickAccess.AutoSize = true;
|
||||
chkNvShowInQuickAccess.Enabled = false;
|
||||
chkNvShowInQuickAccess.Location = new System.Drawing.Point(343, 465);
|
||||
chkNvShowInQuickAccess.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
chkNvShowInQuickAccess.Name = "chkNvShowInQuickAccess";
|
||||
chkNvShowInQuickAccess.Size = new System.Drawing.Size(141, 19);
|
||||
chkNvShowInQuickAccess.TabIndex = 45;
|
||||
chkNvShowInQuickAccess.Text = "Show in Quick Access";
|
||||
chkNvShowInQuickAccess.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// lblNvPresetName
|
||||
//
|
||||
lblNvPresetName.Anchor = System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left;
|
||||
lblNvPresetName.AutoSize = true;
|
||||
lblNvPresetName.Location = new System.Drawing.Point(7, 466);
|
||||
lblNvPresetName.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
|
||||
lblNvPresetName.Name = "lblNvPresetName";
|
||||
lblNvPresetName.Size = new System.Drawing.Size(42, 15);
|
||||
lblNvPresetName.TabIndex = 22;
|
||||
lblNvPresetName.Text = "Name:";
|
||||
//
|
||||
// edtNvPresetName
|
||||
//
|
||||
edtNvPresetName.Anchor = System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left;
|
||||
edtNvPresetName.Enabled = false;
|
||||
edtNvPresetName.Location = new System.Drawing.Point(102, 463);
|
||||
edtNvPresetName.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
edtNvPresetName.Name = "edtNvPresetName";
|
||||
edtNvPresetName.Size = new System.Drawing.Size(233, 23);
|
||||
edtNvPresetName.TabIndex = 21;
|
||||
//
|
||||
// btnAddModesNv
|
||||
//
|
||||
btnAddModesNv.Anchor = System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left;
|
||||
btnAddModesNv.Location = new System.Drawing.Point(385, 429);
|
||||
btnAddModesNv.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
btnAddModesNv.Name = "btnAddModesNv";
|
||||
btnAddModesNv.Size = new System.Drawing.Size(88, 27);
|
||||
btnAddModesNv.TabIndex = 9;
|
||||
btnAddModesNv.Text = "Add...";
|
||||
btnAddModesNv.UseVisualStyleBackColor = true;
|
||||
btnAddModesNv.Click += btnAddModesNv_Click;
|
||||
//
|
||||
// btnNvPresetDelete
|
||||
//
|
||||
btnNvPresetDelete.Anchor = System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left;
|
||||
btnNvPresetDelete.Enabled = false;
|
||||
btnNvPresetDelete.Location = new System.Drawing.Point(290, 429);
|
||||
btnNvPresetDelete.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
btnNvPresetDelete.Name = "btnNvPresetDelete";
|
||||
btnNvPresetDelete.Size = new System.Drawing.Size(88, 27);
|
||||
btnNvPresetDelete.TabIndex = 8;
|
||||
btnNvPresetDelete.Text = "Delete";
|
||||
btnNvPresetDelete.UseVisualStyleBackColor = true;
|
||||
btnNvPresetDelete.Click += btnNvPresetDelete_Click;
|
||||
//
|
||||
// lblError
|
||||
//
|
||||
lblError.AutoSize = true;
|
||||
lblError.Location = new System.Drawing.Point(7, 7);
|
||||
lblError.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
|
||||
lblError.Name = "lblError";
|
||||
lblError.Size = new System.Drawing.Size(53, 15);
|
||||
lblError.TabIndex = 7;
|
||||
lblError.Text = "ErrorText";
|
||||
lblError.Visible = false;
|
||||
//
|
||||
// btnClone
|
||||
//
|
||||
btnClone.Anchor = System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left;
|
||||
btnClone.Enabled = false;
|
||||
btnClone.Location = new System.Drawing.Point(196, 429);
|
||||
btnClone.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
btnClone.Name = "btnClone";
|
||||
btnClone.Size = new System.Drawing.Size(88, 27);
|
||||
btnClone.TabIndex = 6;
|
||||
btnClone.Text = "Clone";
|
||||
btnClone.UseVisualStyleBackColor = true;
|
||||
btnClone.Click += btnClone_Click;
|
||||
//
|
||||
// btnNvPresetSave
|
||||
//
|
||||
btnNvPresetSave.Anchor = System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left;
|
||||
btnNvPresetSave.Enabled = false;
|
||||
btnNvPresetSave.Location = new System.Drawing.Point(479, 429);
|
||||
btnNvPresetSave.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
btnNvPresetSave.Name = "btnNvPresetSave";
|
||||
btnNvPresetSave.Size = new System.Drawing.Size(88, 27);
|
||||
btnNvPresetSave.TabIndex = 5;
|
||||
btnNvPresetSave.Text = "Save";
|
||||
btnNvPresetSave.UseVisualStyleBackColor = true;
|
||||
btnNvPresetSave.Click += btnSetShortcut_Click;
|
||||
//
|
||||
// lblShortcut
|
||||
//
|
||||
lblShortcut.Anchor = System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left;
|
||||
lblShortcut.AutoSize = true;
|
||||
lblShortcut.Location = new System.Drawing.Point(7, 496);
|
||||
lblShortcut.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
|
||||
lblShortcut.Name = "lblShortcut";
|
||||
lblShortcut.Size = new System.Drawing.Size(55, 15);
|
||||
lblShortcut.TabIndex = 4;
|
||||
lblShortcut.Text = "Shortcut:";
|
||||
//
|
||||
// edtShortcut
|
||||
//
|
||||
edtShortcut.Anchor = System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left;
|
||||
edtShortcut.Enabled = false;
|
||||
edtShortcut.Location = new System.Drawing.Point(102, 493);
|
||||
edtShortcut.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
edtShortcut.Name = "edtShortcut";
|
||||
edtShortcut.ReadOnly = true;
|
||||
edtShortcut.Size = new System.Drawing.Size(233, 23);
|
||||
edtShortcut.TabIndex = 3;
|
||||
edtShortcut.TextChanged += edtShortcut_TextChanged;
|
||||
edtShortcut.KeyDown += edtShortcut_KeyDown;
|
||||
edtShortcut.KeyUp += edtShortcut_KeyUp;
|
||||
//
|
||||
// btnChange
|
||||
//
|
||||
btnChange.Anchor = System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left;
|
||||
btnChange.ContextMenuStrip = mnuNvPresets;
|
||||
btnChange.Location = new System.Drawing.Point(102, 429);
|
||||
btnChange.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
btnChange.Name = "btnChange";
|
||||
btnChange.Size = new System.Drawing.Size(88, 27);
|
||||
btnChange.TabIndex = 2;
|
||||
btnChange.Text = "Change...";
|
||||
btnChange.UseVisualStyleBackColor = true;
|
||||
btnChange.Click += btnChange_Click;
|
||||
//
|
||||
// mnuNvPresets
|
||||
//
|
||||
mnuNvPresets.ImageScalingSize = new System.Drawing.Size(20, 20);
|
||||
mnuNvPresets.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { miNvApply, miNvPresetApplyOnStartup, tssNvPresetMenu, mnuNvDisplay, mnuNvPresetsColorSettings, mnuRefreshRate, mnuNvResolution, miNvPresetDithering, miNvHDR, mnuNvDriverSettings, mnuNvOtherSettings, mnuNvHdmiSettings, mnuNvOverclocking, miNvCopyId });
|
||||
mnuNvPresets.Name = "mnuNvPresets";
|
||||
mnuNvPresets.Size = new System.Drawing.Size(185, 296);
|
||||
mnuNvPresets.Opening += mnuNvPresets_Opening;
|
||||
//
|
||||
// miNvApply
|
||||
//
|
||||
miNvApply.Name = "miNvApply";
|
||||
miNvApply.Size = new System.Drawing.Size(184, 22);
|
||||
miNvApply.Text = "Apply";
|
||||
miNvApply.Click += btnApply_Click;
|
||||
//
|
||||
// miNvPresetApplyOnStartup
|
||||
//
|
||||
miNvPresetApplyOnStartup.CheckOnClick = true;
|
||||
miNvPresetApplyOnStartup.Name = "miNvPresetApplyOnStartup";
|
||||
miNvPresetApplyOnStartup.Size = new System.Drawing.Size(184, 22);
|
||||
miNvPresetApplyOnStartup.Text = "Apply on startup";
|
||||
miNvPresetApplyOnStartup.Click += miNvPresetApplyOnStartup_Click;
|
||||
//
|
||||
// tssNvPresetMenu
|
||||
//
|
||||
tssNvPresetMenu.Name = "tssNvPresetMenu";
|
||||
tssNvPresetMenu.Size = new System.Drawing.Size(181, 6);
|
||||
//
|
||||
// mnuNvDisplay
|
||||
//
|
||||
mnuNvDisplay.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { miNvPrimaryDisplay });
|
||||
mnuNvDisplay.Name = "mnuNvDisplay";
|
||||
mnuNvDisplay.Size = new System.Drawing.Size(184, 22);
|
||||
mnuNvDisplay.Text = "Display";
|
||||
//
|
||||
// miNvPrimaryDisplay
|
||||
//
|
||||
miNvPrimaryDisplay.Name = "miNvPrimaryDisplay";
|
||||
miNvPrimaryDisplay.Size = new System.Drawing.Size(155, 22);
|
||||
miNvPrimaryDisplay.Text = "Primary display";
|
||||
miNvPrimaryDisplay.Click += displayMenuItem_Click;
|
||||
//
|
||||
// mnuNvPresetsColorSettings
|
||||
//
|
||||
mnuNvPresetsColorSettings.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { miNvPresetColorSettings });
|
||||
mnuNvPresetsColorSettings.Name = "mnuNvPresetsColorSettings";
|
||||
mnuNvPresetsColorSettings.Size = new System.Drawing.Size(184, 22);
|
||||
mnuNvPresetsColorSettings.Text = "Color Settings";
|
||||
//
|
||||
// miNvPresetColorSettings
|
||||
//
|
||||
miNvPresetColorSettings.Name = "miNvPresetColorSettings";
|
||||
miNvPresetColorSettings.Size = new System.Drawing.Size(120, 22);
|
||||
miNvPresetColorSettings.Text = "Included";
|
||||
miNvPresetColorSettings.Click += miNvPresetColorSettings_Click;
|
||||
//
|
||||
// mnuRefreshRate
|
||||
//
|
||||
mnuRefreshRate.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { miRefreshRateIncluded });
|
||||
mnuRefreshRate.Name = "mnuRefreshRate";
|
||||
mnuRefreshRate.Size = new System.Drawing.Size(184, 22);
|
||||
mnuRefreshRate.Text = "Refresh Rate";
|
||||
//
|
||||
// miRefreshRateIncluded
|
||||
//
|
||||
miRefreshRateIncluded.Name = "miRefreshRateIncluded";
|
||||
miRefreshRateIncluded.Size = new System.Drawing.Size(120, 22);
|
||||
miRefreshRateIncluded.Text = "Included";
|
||||
miRefreshRateIncluded.Click += includedToolStripMenuItem_Click;
|
||||
//
|
||||
// mnuNvResolution
|
||||
//
|
||||
mnuNvResolution.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { miNvResolutionIncluded });
|
||||
mnuNvResolution.Name = "mnuNvResolution";
|
||||
mnuNvResolution.Size = new System.Drawing.Size(184, 22);
|
||||
mnuNvResolution.Text = "Resolution";
|
||||
//
|
||||
// miNvResolutionIncluded
|
||||
//
|
||||
miNvResolutionIncluded.CheckOnClick = true;
|
||||
miNvResolutionIncluded.Name = "miNvResolutionIncluded";
|
||||
miNvResolutionIncluded.Size = new System.Drawing.Size(120, 22);
|
||||
miNvResolutionIncluded.Text = "Included";
|
||||
miNvResolutionIncluded.Click += miNvResolutionIncluded_Click;
|
||||
//
|
||||
// miNvPresetDithering
|
||||
//
|
||||
miNvPresetDithering.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { miNvPresetApplyDithering, miNvPresetDitheringEnabled, mnuNvDitheringBitDepth, mnuNvDitheringMode });
|
||||
miNvPresetDithering.Name = "miNvPresetDithering";
|
||||
miNvPresetDithering.Size = new System.Drawing.Size(184, 22);
|
||||
miNvPresetDithering.Text = "Dithering";
|
||||
//
|
||||
// miNvPresetApplyDithering
|
||||
//
|
||||
miNvPresetApplyDithering.Name = "miNvPresetApplyDithering";
|
||||
miNvPresetApplyDithering.Size = new System.Drawing.Size(122, 22);
|
||||
miNvPresetApplyDithering.Text = "Included";
|
||||
miNvPresetApplyDithering.Click += miNvPresetApplyDithering_Click;
|
||||
//
|
||||
// miNvPresetDitheringEnabled
|
||||
//
|
||||
miNvPresetDitheringEnabled.Name = "miNvPresetDitheringEnabled";
|
||||
miNvPresetDitheringEnabled.Size = new System.Drawing.Size(122, 22);
|
||||
miNvPresetDitheringEnabled.Text = "Enabled";
|
||||
miNvPresetDitheringEnabled.Click += miNvPresetDitheringEnabled_Click;
|
||||
//
|
||||
// mnuNvDitheringBitDepth
|
||||
//
|
||||
mnuNvDitheringBitDepth.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { miNvDithering6bit, miNvDithering8bit, miNvDithering10bit });
|
||||
mnuNvDitheringBitDepth.Name = "mnuNvDitheringBitDepth";
|
||||
mnuNvDitheringBitDepth.Size = new System.Drawing.Size(122, 22);
|
||||
mnuNvDitheringBitDepth.Text = "Bit depth";
|
||||
//
|
||||
// miNvDithering6bit
|
||||
//
|
||||
miNvDithering6bit.Name = "miNvDithering6bit";
|
||||
miNvDithering6bit.Size = new System.Drawing.Size(105, 22);
|
||||
miNvDithering6bit.Tag = "0";
|
||||
miNvDithering6bit.Text = "6-bit";
|
||||
miNvDithering6bit.Click += miNvDithering6bit_Click;
|
||||
//
|
||||
// miNvDithering8bit
|
||||
//
|
||||
miNvDithering8bit.Name = "miNvDithering8bit";
|
||||
miNvDithering8bit.Size = new System.Drawing.Size(105, 22);
|
||||
miNvDithering8bit.Tag = "1";
|
||||
miNvDithering8bit.Text = "8-bit";
|
||||
miNvDithering8bit.Click += miNvDithering6bit_Click;
|
||||
//
|
||||
// miNvDithering10bit
|
||||
//
|
||||
miNvDithering10bit.Name = "miNvDithering10bit";
|
||||
miNvDithering10bit.Size = new System.Drawing.Size(105, 22);
|
||||
miNvDithering10bit.Tag = "2";
|
||||
miNvDithering10bit.Text = "10-bit";
|
||||
miNvDithering10bit.Click += miNvDithering6bit_Click;
|
||||
//
|
||||
// mnuNvDitheringMode
|
||||
//
|
||||
mnuNvDitheringMode.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { spatial1ToolStripMenuItem, spatial2ToolStripMenuItem, spatialDynamic2x2ToolStripMenuItem, spatialStatic2x2ToolStripMenuItem, temporalToolStripMenuItem });
|
||||
mnuNvDitheringMode.Name = "mnuNvDitheringMode";
|
||||
mnuNvDitheringMode.Size = new System.Drawing.Size(122, 22);
|
||||
mnuNvDitheringMode.Text = "Mode";
|
||||
//
|
||||
// spatial1ToolStripMenuItem
|
||||
//
|
||||
spatial1ToolStripMenuItem.Name = "spatial1ToolStripMenuItem";
|
||||
spatial1ToolStripMenuItem.Size = new System.Drawing.Size(180, 22);
|
||||
spatial1ToolStripMenuItem.Tag = "0";
|
||||
spatial1ToolStripMenuItem.Text = "Spatial Dynamic";
|
||||
spatial1ToolStripMenuItem.Click += spatial1ToolStripMenuItem_Click;
|
||||
//
|
||||
// spatial2ToolStripMenuItem
|
||||
//
|
||||
spatial2ToolStripMenuItem.Name = "spatial2ToolStripMenuItem";
|
||||
spatial2ToolStripMenuItem.Size = new System.Drawing.Size(180, 22);
|
||||
spatial2ToolStripMenuItem.Tag = "1";
|
||||
spatial2ToolStripMenuItem.Text = "Spatial Static";
|
||||
spatial2ToolStripMenuItem.Click += spatial1ToolStripMenuItem_Click;
|
||||
//
|
||||
// spatialDynamic2x2ToolStripMenuItem
|
||||
//
|
||||
spatialDynamic2x2ToolStripMenuItem.Name = "spatialDynamic2x2ToolStripMenuItem";
|
||||
spatialDynamic2x2ToolStripMenuItem.Size = new System.Drawing.Size(180, 22);
|
||||
spatialDynamic2x2ToolStripMenuItem.Tag = "2";
|
||||
spatialDynamic2x2ToolStripMenuItem.Text = "Spatial Dynamic 2x2";
|
||||
spatialDynamic2x2ToolStripMenuItem.Click += spatial1ToolStripMenuItem_Click;
|
||||
//
|
||||
// spatialStatic2x2ToolStripMenuItem
|
||||
//
|
||||
spatialStatic2x2ToolStripMenuItem.Name = "spatialStatic2x2ToolStripMenuItem";
|
||||
spatialStatic2x2ToolStripMenuItem.Size = new System.Drawing.Size(180, 22);
|
||||
spatialStatic2x2ToolStripMenuItem.Tag = "3";
|
||||
spatialStatic2x2ToolStripMenuItem.Text = "Spatial Static 2x2";
|
||||
spatialStatic2x2ToolStripMenuItem.Click += spatial1ToolStripMenuItem_Click;
|
||||
//
|
||||
// temporalToolStripMenuItem
|
||||
//
|
||||
temporalToolStripMenuItem.Name = "temporalToolStripMenuItem";
|
||||
temporalToolStripMenuItem.Size = new System.Drawing.Size(180, 22);
|
||||
temporalToolStripMenuItem.Tag = "4";
|
||||
temporalToolStripMenuItem.Text = "Temporal";
|
||||
temporalToolStripMenuItem.Click += spatial1ToolStripMenuItem_Click;
|
||||
//
|
||||
// miNvHDR
|
||||
//
|
||||
miNvHDR.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { miHDRIncluded, miToggleHDR, miHDREnabled });
|
||||
miNvHDR.Name = "miNvHDR";
|
||||
miNvHDR.Size = new System.Drawing.Size(184, 22);
|
||||
miNvHDR.Text = "HDR";
|
||||
//
|
||||
// miHDRIncluded
|
||||
//
|
||||
miHDRIncluded.Name = "miHDRIncluded";
|
||||
miHDRIncluded.Size = new System.Drawing.Size(136, 22);
|
||||
miHDRIncluded.Text = "Included";
|
||||
miHDRIncluded.Click += miHDRIncluded_Click;
|
||||
//
|
||||
// miToggleHDR
|
||||
//
|
||||
miToggleHDR.Name = "miToggleHDR";
|
||||
miToggleHDR.Size = new System.Drawing.Size(136, 22);
|
||||
miToggleHDR.Text = "Toggle HDR";
|
||||
miToggleHDR.Click += miToggleHDR_Click;
|
||||
//
|
||||
// miHDREnabled
|
||||
//
|
||||
miHDREnabled.Name = "miHDREnabled";
|
||||
miHDREnabled.Size = new System.Drawing.Size(136, 22);
|
||||
miHDREnabled.Text = "Enabled";
|
||||
miHDREnabled.Click += miHDREnabled_Click;
|
||||
//
|
||||
// mnuNvDriverSettings
|
||||
//
|
||||
mnuNvDriverSettings.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { miNvDriverSettingsIncluded });
|
||||
mnuNvDriverSettings.Name = "mnuNvDriverSettings";
|
||||
mnuNvDriverSettings.Size = new System.Drawing.Size(184, 22);
|
||||
mnuNvDriverSettings.Text = "Driver Settings";
|
||||
//
|
||||
// miNvDriverSettingsIncluded
|
||||
//
|
||||
miNvDriverSettingsIncluded.Name = "miNvDriverSettingsIncluded";
|
||||
miNvDriverSettingsIncluded.Size = new System.Drawing.Size(120, 22);
|
||||
miNvDriverSettingsIncluded.Text = "Included";
|
||||
miNvDriverSettingsIncluded.Click += miNvDriverSettingsIncluded_Click;
|
||||
//
|
||||
// mnuNvOtherSettings
|
||||
//
|
||||
mnuNvOtherSettings.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { miNvOtherIncluded });
|
||||
mnuNvOtherSettings.Name = "mnuNvOtherSettings";
|
||||
mnuNvOtherSettings.Size = new System.Drawing.Size(184, 22);
|
||||
mnuNvOtherSettings.Text = "Other";
|
||||
//
|
||||
// miNvOtherIncluded
|
||||
//
|
||||
miNvOtherIncluded.Name = "miNvOtherIncluded";
|
||||
miNvOtherIncluded.Size = new System.Drawing.Size(120, 22);
|
||||
miNvOtherIncluded.Text = "Included";
|
||||
miNvOtherIncluded.Click += miNvOtherIncluded_Click;
|
||||
//
|
||||
// mnuNvHdmiSettings
|
||||
//
|
||||
mnuNvHdmiSettings.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { miNvHdmiIncluded });
|
||||
mnuNvHdmiSettings.Name = "mnuNvHdmiSettings";
|
||||
mnuNvHdmiSettings.Size = new System.Drawing.Size(184, 22);
|
||||
mnuNvHdmiSettings.Text = "HDMI Settings";
|
||||
//
|
||||
// miNvHdmiIncluded
|
||||
//
|
||||
miNvHdmiIncluded.Name = "miNvHdmiIncluded";
|
||||
miNvHdmiIncluded.Size = new System.Drawing.Size(120, 22);
|
||||
miNvHdmiIncluded.Text = "Included";
|
||||
miNvHdmiIncluded.Click += miNvHdmiIncluded_Click;
|
||||
//
|
||||
// mnuNvOverclocking
|
||||
//
|
||||
mnuNvOverclocking.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { miNvOverclockingIncluded });
|
||||
mnuNvOverclocking.Name = "mnuNvOverclocking";
|
||||
mnuNvOverclocking.Size = new System.Drawing.Size(184, 22);
|
||||
mnuNvOverclocking.Text = "Overclocking";
|
||||
//
|
||||
// miNvOverclockingIncluded
|
||||
//
|
||||
miNvOverclockingIncluded.Name = "miNvOverclockingIncluded";
|
||||
miNvOverclockingIncluded.Size = new System.Drawing.Size(120, 22);
|
||||
miNvOverclockingIncluded.Text = "Included";
|
||||
miNvOverclockingIncluded.Click += miNvOverclockingIncluded_Click;
|
||||
//
|
||||
// miNvCopyId
|
||||
//
|
||||
miNvCopyId.Name = "miNvCopyId";
|
||||
miNvCopyId.Size = new System.Drawing.Size(184, 22);
|
||||
miNvCopyId.Text = "Copy Id to Clipboard";
|
||||
miNvCopyId.Click += miNvCopyId_Click;
|
||||
//
|
||||
// btnApply
|
||||
//
|
||||
btnApply.Anchor = System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left;
|
||||
btnApply.Enabled = false;
|
||||
btnApply.Location = new System.Drawing.Point(7, 429);
|
||||
btnApply.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
btnApply.Name = "btnApply";
|
||||
btnApply.Size = new System.Drawing.Size(88, 27);
|
||||
btnApply.TabIndex = 1;
|
||||
btnApply.Text = "Apply";
|
||||
btnApply.UseVisualStyleBackColor = true;
|
||||
btnApply.Click += btnApply_Click;
|
||||
//
|
||||
// lvNvPresets
|
||||
//
|
||||
lvNvPresets.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right;
|
||||
lvNvPresets.CheckBoxes = true;
|
||||
lvNvPresets.ContextMenuStrip = mnuNvPresets;
|
||||
lvNvPresets.FullRowSelect = true;
|
||||
lvNvPresets.Location = new System.Drawing.Point(7, 7);
|
||||
lvNvPresets.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
lvNvPresets.MultiSelect = false;
|
||||
lvNvPresets.Name = "lvNvPresets";
|
||||
lvNvPresets.Size = new System.Drawing.Size(1098, 415);
|
||||
lvNvPresets.TabIndex = 0;
|
||||
lvNvPresets.UseCompatibleStateImageBehavior = false;
|
||||
lvNvPresets.View = System.Windows.Forms.View.Details;
|
||||
lvNvPresets.ColumnClick += lvLgPresets_ColumnClick;
|
||||
lvNvPresets.ItemCheck += lvNvPresets_ItemCheck;
|
||||
lvNvPresets.ItemChecked += lvNvPresets_ItemChecked;
|
||||
lvNvPresets.SelectedIndexChanged += lvNvPresets_SelectedIndexChanged;
|
||||
lvNvPresets.DoubleClick += btnApply_Click;
|
||||
lvNvPresets.MouseLeave += lvNvPresets_MouseLeave;
|
||||
lvNvPresets.MouseMove += lvNvPresets_MouseMove;
|
||||
//
|
||||
// mnuNvSettings
|
||||
//
|
||||
mnuNvSettings.ImageScalingSize = new System.Drawing.Size(20, 20);
|
||||
mnuNvSettings.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { miNvProfileInspector, miNvNovideo, miNvSettings, miNvTestDithering, miNVIDIAInfo });
|
||||
mnuNvSettings.Name = "mnuLgButtons";
|
||||
mnuNvSettings.Size = new System.Drawing.Size(202, 136);
|
||||
//
|
||||
// miNvProfileInspector
|
||||
//
|
||||
miNvProfileInspector.Name = "miNvProfileInspector";
|
||||
miNvProfileInspector.Size = new System.Drawing.Size(201, 22);
|
||||
miNvProfileInspector.Text = "NVIDIA Profile Inspector";
|
||||
miNvProfileInspector.Click += miNvProfileInspector_Click;
|
||||
//
|
||||
// miNvNovideo
|
||||
//
|
||||
miNvNovideo.Name = "miNvNovideo";
|
||||
miNvNovideo.Size = new System.Drawing.Size(201, 22);
|
||||
miNvNovideo.Text = "Novideo sRGB";
|
||||
miNvNovideo.Click += miNvNovideo_Click;
|
||||
//
|
||||
// miNvSettings
|
||||
//
|
||||
miNvSettings.Name = "miNvSettings";
|
||||
miNvSettings.Size = new System.Drawing.Size(201, 22);
|
||||
miNvSettings.Text = "Settings";
|
||||
miNvSettings.Click += miNvSettings_Click;
|
||||
//
|
||||
// miNvTestDithering
|
||||
//
|
||||
miNvTestDithering.Name = "miNvTestDithering";
|
||||
miNvTestDithering.Size = new System.Drawing.Size(201, 22);
|
||||
miNvTestDithering.Text = "Test dithering";
|
||||
miNvTestDithering.Click += miNvTestDithering_Click;
|
||||
//
|
||||
// miNVIDIAInfo
|
||||
//
|
||||
miNVIDIAInfo.Name = "miNVIDIAInfo";
|
||||
miNVIDIAInfo.Size = new System.Drawing.Size(201, 22);
|
||||
miNVIDIAInfo.Text = "NVIDIA Info";
|
||||
miNVIDIAInfo.Click += miNVIDIAInfo_Click;
|
||||
//
|
||||
// NvPanel
|
||||
//
|
||||
AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
|
||||
AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
BackColor = System.Drawing.Color.White;
|
||||
Controls.Add(lblNvOverclock);
|
||||
Controls.Add(edtNvOverclock);
|
||||
Controls.Add(btnNvSetClocks);
|
||||
Controls.Add(lblNvGpuInfo);
|
||||
Controls.Add(edtNvGpuInfo);
|
||||
Controls.Add(lblNvGPU);
|
||||
Controls.Add(cbxNvGPU);
|
||||
Controls.Add(btnNvSettings);
|
||||
Controls.Add(chkNvShowInQuickAccess);
|
||||
Controls.Add(lblNvPresetName);
|
||||
Controls.Add(edtNvPresetName);
|
||||
Controls.Add(btnAddModesNv);
|
||||
Controls.Add(btnNvPresetDelete);
|
||||
Controls.Add(lblError);
|
||||
Controls.Add(btnClone);
|
||||
Controls.Add(btnNvPresetSave);
|
||||
Controls.Add(lblShortcut);
|
||||
Controls.Add(edtShortcut);
|
||||
Controls.Add(btnChange);
|
||||
Controls.Add(btnApply);
|
||||
Controls.Add(lvNvPresets);
|
||||
Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
Name = "NvPanel";
|
||||
Size = new System.Drawing.Size(1114, 539);
|
||||
mnuNvPresets.ResumeLayout(false);
|
||||
mnuNvSettings.ResumeLayout(false);
|
||||
ResumeLayout(false);
|
||||
PerformLayout();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.ListView lvNvPresets;
|
||||
private System.Windows.Forms.Button btnApply;
|
||||
private System.Windows.Forms.Button btnChange;
|
||||
private System.Windows.Forms.Button btnNvPresetSave;
|
||||
private System.Windows.Forms.Label lblShortcut;
|
||||
private System.Windows.Forms.TextBox edtShortcut;
|
||||
private System.Windows.Forms.Button btnClone;
|
||||
private System.Windows.Forms.ContextMenuStrip mnuNvPresets;
|
||||
private System.Windows.Forms.ToolStripMenuItem miNvPresetDithering;
|
||||
private System.Windows.Forms.ToolStripMenuItem miNvPresetApplyDithering;
|
||||
private System.Windows.Forms.ToolStripMenuItem miNvPresetDitheringEnabled;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuRefreshRate;
|
||||
private System.Windows.Forms.ToolStripMenuItem miRefreshRateIncluded;
|
||||
private System.Windows.Forms.ToolStripMenuItem miNvHDR;
|
||||
private System.Windows.Forms.ToolStripMenuItem miHDRIncluded;
|
||||
private System.Windows.Forms.ToolStripMenuItem miToggleHDR;
|
||||
private System.Windows.Forms.ToolStripMenuItem miHDREnabled;
|
||||
private System.Windows.Forms.Label lblError;
|
||||
private System.Windows.Forms.Button btnNvPresetDelete;
|
||||
private System.Windows.Forms.Button btnAddModesNv;
|
||||
private System.Windows.Forms.ToolStripMenuItem miNvApply;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuNvDisplay;
|
||||
private System.Windows.Forms.ToolStripMenuItem miNvPrimaryDisplay;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuNvPresetsColorSettings;
|
||||
private System.Windows.Forms.ToolStripMenuItem miNvPresetColorSettings;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuNvDitheringBitDepth;
|
||||
private System.Windows.Forms.ToolStripMenuItem miNvDithering6bit;
|
||||
private System.Windows.Forms.ToolStripMenuItem miNvDithering8bit;
|
||||
private System.Windows.Forms.ToolStripMenuItem miNvDithering10bit;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuNvDitheringMode;
|
||||
private System.Windows.Forms.ToolStripMenuItem spatial1ToolStripMenuItem;
|
||||
private System.Windows.Forms.ToolStripMenuItem spatial2ToolStripMenuItem;
|
||||
private System.Windows.Forms.ToolStripMenuItem spatialDynamic2x2ToolStripMenuItem;
|
||||
private System.Windows.Forms.ToolStripMenuItem spatialStatic2x2ToolStripMenuItem;
|
||||
private System.Windows.Forms.ToolStripMenuItem temporalToolStripMenuItem;
|
||||
private System.Windows.Forms.ToolStripMenuItem miNvPresetApplyOnStartup;
|
||||
private System.Windows.Forms.ToolStripMenuItem miNvCopyId;
|
||||
private System.Windows.Forms.Label lblNvPresetName;
|
||||
private System.Windows.Forms.TextBox edtNvPresetName;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuNvResolution;
|
||||
private System.Windows.Forms.ToolStripMenuItem miNvResolutionIncluded;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuNvDriverSettings;
|
||||
private System.Windows.Forms.ToolStripMenuItem miNvDriverSettingsIncluded;
|
||||
private System.Windows.Forms.CheckBox chkNvShowInQuickAccess;
|
||||
private System.Windows.Forms.Button btnNvSettings;
|
||||
private System.Windows.Forms.ContextMenuStrip mnuNvSettings;
|
||||
private System.Windows.Forms.ToolStripMenuItem miNvProfileInspector;
|
||||
private System.Windows.Forms.ToolStripMenuItem miNvSettings;
|
||||
private System.Windows.Forms.ToolTip lvNvPresetsToolTip;
|
||||
private System.Windows.Forms.ToolStripSeparator tssNvPresetMenu;
|
||||
private System.Windows.Forms.Label lblNvGPU;
|
||||
private System.Windows.Forms.ComboBox cbxNvGPU;
|
||||
private System.Windows.Forms.Label lblNvGpuInfo;
|
||||
private System.Windows.Forms.TextBox edtNvGpuInfo;
|
||||
private System.Windows.Forms.Button btnNvSetClocks;
|
||||
private System.Windows.Forms.Label lblNvOverclock;
|
||||
private System.Windows.Forms.TextBox edtNvOverclock;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuNvOverclocking;
|
||||
private System.Windows.Forms.ToolStripMenuItem miNvOverclockingIncluded;
|
||||
private System.Windows.Forms.ToolStripMenuItem miNvNovideo;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuNvOtherSettings;
|
||||
private System.Windows.Forms.ToolStripMenuItem miNvOtherIncluded;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuNvHdmiSettings;
|
||||
private System.Windows.Forms.ToolStripMenuItem miNvHdmiIncluded;
|
||||
private System.Windows.Forms.ToolStripMenuItem miNvTestDithering;
|
||||
private System.Windows.Forms.ToolStripMenuItem miNVIDIAInfo;
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,129 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing"">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<metadata name="mnuNvPresets.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>17, 17</value>
|
||||
</metadata>
|
||||
<metadata name="mnuNvSettings.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>147, 17</value>
|
||||
</metadata>
|
||||
<metadata name="lvNvPresetsToolTip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>282, 17</value>
|
||||
</metadata>
|
||||
</root>
|
||||
@@ -0,0 +1,437 @@
|
||||
using ColorControl.Services.Common;
|
||||
using ColorControl.Shared.Common;
|
||||
using ColorControl.Shared.Contracts;
|
||||
using ColorControl.Shared.Contracts.NVIDIA;
|
||||
using Newtonsoft.Json;
|
||||
using nspector.Common;
|
||||
using NStandard;
|
||||
using NvAPIWrapper.Display;
|
||||
using NvAPIWrapper.Native.Display;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace ColorControl.Services.NVIDIA
|
||||
{
|
||||
class NvPreset : PresetBase
|
||||
{
|
||||
public static NvService NvService { get; set; }
|
||||
|
||||
public bool applyColorData { get; set; }
|
||||
public ColorData colorData { get; set; }
|
||||
public bool applyHDR { get; set; }
|
||||
public bool HDREnabled { get; set; }
|
||||
public bool toggleHDR { get; set; }
|
||||
public bool applyDithering { get; set; }
|
||||
public bool? ditheringEnabled { get; set; }
|
||||
public bool applyRefreshRate { get; set; }
|
||||
public uint refreshRate { get; set; }
|
||||
public bool applyResolution { get; set; }
|
||||
public uint resolutionWidth { get; set; }
|
||||
public uint resolutionHeight { get; set; }
|
||||
public bool primaryDisplay { get; set; }
|
||||
public string displayName { get; set; }
|
||||
public uint ditheringBits { get; set; }
|
||||
public uint ditheringMode { get; set; }
|
||||
public bool applyOther { get; set; }
|
||||
public int? SDRBrightness { get; set; }
|
||||
public Scaling? scaling { get; set; }
|
||||
public bool applyDriverSettings { get; set; }
|
||||
public Dictionary<uint, uint> driverSettings { get; set; }
|
||||
public bool applyOverclocking { get; set; }
|
||||
public List<NvGpuOcSettings> ocSettings { get; set; }
|
||||
|
||||
public bool applyHdmiSettings { get; set; }
|
||||
public NvHdmiInfoFrameSettings HdmiInfoFrameSettings { get; set; }
|
||||
public NvColorProfileSettings ColorProfileSettings { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
public bool IsDisplayPreset { get; set; }
|
||||
[JsonIgnore]
|
||||
public Display Display { get; set; }
|
||||
[JsonIgnore]
|
||||
public string InfoLine { get; set; }
|
||||
public NvDitherState DitherState => ditheringEnabled.HasValue ? ditheringEnabled == true ? NvDitherState.Enabled : NvDitherState.Disabled : NvDitherState.Auto;
|
||||
|
||||
public NvPreset() : base()
|
||||
{
|
||||
applyColorData = true;
|
||||
applyDithering = false;
|
||||
ditheringEnabled = true;
|
||||
applyHDR = false;
|
||||
HDREnabled = false;
|
||||
toggleHDR = false;
|
||||
applyRefreshRate = false;
|
||||
refreshRate = 60;
|
||||
applyResolution = false;
|
||||
resolutionWidth = 0;
|
||||
resolutionHeight = 0;
|
||||
primaryDisplay = true;
|
||||
ditheringBits = 1;
|
||||
ditheringMode = 4;
|
||||
applyDriverSettings = false;
|
||||
driverSettings = new Dictionary<uint, uint>();
|
||||
ocSettings = new List<NvGpuOcSettings>();
|
||||
HdmiInfoFrameSettings = new NvHdmiInfoFrameSettings();
|
||||
ColorProfileSettings = new NvColorProfileSettings();
|
||||
}
|
||||
|
||||
public NvPreset(ColorData colorData) : this()
|
||||
{
|
||||
id = GetNewId();
|
||||
this.colorData = colorData;
|
||||
}
|
||||
|
||||
public NvPreset(NvPreset preset) : this()
|
||||
{
|
||||
id = GetNewId();
|
||||
|
||||
primaryDisplay = preset.primaryDisplay;
|
||||
displayName = preset.displayName;
|
||||
|
||||
var colorData = preset.colorData;
|
||||
this.colorData = new ColorData(colorData.ColorFormat, dynamicRange: colorData.DynamicRange, colorDepth: colorData.ColorDepth, colorSelectionPolicy: ColorDataSelectionPolicy.User);
|
||||
applyColorData = preset.applyColorData;
|
||||
|
||||
applyHDR = preset.applyHDR;
|
||||
HDREnabled = preset.HDREnabled;
|
||||
toggleHDR = preset.toggleHDR;
|
||||
applyDithering = preset.applyDithering;
|
||||
ditheringEnabled = preset.ditheringEnabled;
|
||||
applyRefreshRate = preset.applyRefreshRate;
|
||||
refreshRate = preset.refreshRate;
|
||||
applyResolution = preset.applyResolution;
|
||||
resolutionWidth = preset.resolutionWidth;
|
||||
resolutionHeight = preset.resolutionHeight;
|
||||
applyDriverSettings = preset.applyDriverSettings;
|
||||
driverSettings = new Dictionary<uint, uint>(preset.driverSettings);
|
||||
|
||||
SDRBrightness = preset.SDRBrightness;
|
||||
scaling = preset.scaling;
|
||||
ColorProfileSettings = new NvColorProfileSettings(preset.ColorProfileSettings);
|
||||
applyOther = preset.applyOther;
|
||||
|
||||
HdmiInfoFrameSettings = new NvHdmiInfoFrameSettings(preset.HdmiInfoFrameSettings);
|
||||
applyHdmiSettings = preset.applyHdmiSettings;
|
||||
}
|
||||
|
||||
public NvPreset Clone()
|
||||
{
|
||||
var preset = new NvPreset(this);
|
||||
|
||||
return preset;
|
||||
}
|
||||
|
||||
public static string[] GetColumnNames()
|
||||
{
|
||||
return new[] { "Name", "Display|140", "Color settings (BPC, format, dyn. range, color space)|260", "Refresh rate|100", "Resolution|120", "Dithering", "HDR", "Driver settings|300", "HDMI settings|200", "Other|200", "Overclocking|300", "Shortcut", "Apply on startup" };
|
||||
}
|
||||
|
||||
public override List<string> GetDisplayValues(Config config = null)
|
||||
{
|
||||
var isCurrent = IsDisplayPreset;
|
||||
|
||||
var values = new List<string>
|
||||
{
|
||||
isCurrent ? "Current settings" : name
|
||||
};
|
||||
|
||||
var display = isCurrent ? displayName : string.Format("{0}", primaryDisplay ? "Primary" : displayName);
|
||||
values.Add(display);
|
||||
|
||||
var colorSettings = FormatDisplaySetting(string.Format("{0}, {1}, {2}, {3}", colorData.ColorDepth, colorData.ColorFormat, colorData.DynamicRange, colorData.Colorimetry), isCurrent, applyColorData);
|
||||
|
||||
values.Add(colorSettings);
|
||||
values.Add(FormatDisplaySetting(string.Format("{0}Hz", refreshRate), isCurrent, applyRefreshRate));
|
||||
|
||||
if (applyResolution || resolutionWidth > 0)
|
||||
{
|
||||
values.Add(FormatDisplaySetting(string.Format("{0}x{1}", resolutionWidth, resolutionHeight), isCurrent, applyResolution));
|
||||
}
|
||||
else
|
||||
{
|
||||
values.Add(isCurrent ? "" : "Excluded");
|
||||
}
|
||||
|
||||
var dithering = GetDitheringDescription();
|
||||
|
||||
values.Add(FormatDisplaySetting(dithering, isCurrent, applyDithering));
|
||||
values.Add(FormatDisplaySetting(toggleHDR ? "Toggle" : HDREnabled ? "Enabled" : "Disabled", isCurrent, applyHDR));
|
||||
|
||||
values.Add(FormatDisplaySetting(GetDriverSettingsDescription(), isCurrent, applyDriverSettings));
|
||||
|
||||
values.Add(FormatDisplaySetting(GetHdmiSettingsDescription(), isCurrent, applyHdmiSettings));
|
||||
|
||||
values.Add(FormatDisplaySetting(GetOtherDescription(), isCurrent, applyOther));
|
||||
|
||||
values.Add(FormatDisplaySetting(GetOverclockingSettingsDescription(), isCurrent, applyOverclocking));
|
||||
|
||||
values.Add(isCurrent ? "" : shortcut);
|
||||
|
||||
values.Add(isCurrent ? "" : string.Format("{0}", config?.NvPresetId_ApplyOnStartup == id ? "Yes" : string.Empty));
|
||||
|
||||
if (isCurrent)
|
||||
{
|
||||
InfoLine = string.Format("{0}: {1}, {2}Hz, HDR: {3}", displayName, colorSettings, refreshRate, HDREnabled ? "Yes" : "No");
|
||||
}
|
||||
|
||||
return values;
|
||||
}
|
||||
|
||||
private static string FormatDisplaySetting(string values, bool isCurrent, bool isEnabled)
|
||||
{
|
||||
return string.Format("{0}{1}", isCurrent ? "" : isEnabled ? "Included: " : "Excluded: ", values);
|
||||
}
|
||||
|
||||
public string GetOverclockingSettingsDescription(bool useNewLines = false)
|
||||
{
|
||||
if (ocSettings.Count == 0)
|
||||
{
|
||||
return "None";
|
||||
}
|
||||
|
||||
var values = new List<string>();
|
||||
|
||||
foreach (var ocSetting in ocSettings)
|
||||
{
|
||||
var value = ocSetting.ToString();
|
||||
|
||||
values.Add($"{value}");
|
||||
}
|
||||
|
||||
return string.Join(useNewLines ? "\r\n" : ", ", values);
|
||||
}
|
||||
|
||||
public string GetDriverSettingsDescription(bool useNewLines = false)
|
||||
{
|
||||
if (driverSettings.Count == 0)
|
||||
{
|
||||
return "None";
|
||||
}
|
||||
|
||||
var values = new List<string>();
|
||||
|
||||
foreach (var driverSetting in driverSettings)
|
||||
{
|
||||
var settingMeta = NvService.GetSettingMeta(driverSetting.Key);
|
||||
|
||||
var value = settingMeta.ToFriendlyName(intValue: driverSetting.Value, displayDefault: true);
|
||||
|
||||
if (value == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
values.Add($"{settingMeta.SettingName}: {value}");
|
||||
}
|
||||
|
||||
return string.Join(useNewLines ? "\r\n" : ", ", values);
|
||||
}
|
||||
|
||||
public string GetDitheringDescription(string disabledText = "Disabled")
|
||||
{
|
||||
if (ditheringEnabled == null && ditheringBits == 0 && ditheringMode == 0)
|
||||
{
|
||||
return "Auto: Disabled";
|
||||
}
|
||||
|
||||
if (ditheringEnabled is null or true)
|
||||
{
|
||||
var ditherBitsDescription = ((NvDitherBits)ditheringBits).GetDescription();
|
||||
var ditherModeDescription = ((NvDitherMode)ditheringMode).GetDescription();
|
||||
return string.Format("{0}{1} {2}", ditheringEnabled == null ? "Auto: " : "", ditherBitsDescription, ditherModeDescription);
|
||||
}
|
||||
|
||||
return disabledText;
|
||||
}
|
||||
|
||||
public string GetHdmiSettingsDescription()
|
||||
{
|
||||
var values = new List<string>();
|
||||
|
||||
if (HdmiInfoFrameSettings.Colorimetry.HasValue)
|
||||
{
|
||||
values.Add($"Colorimetry: {HdmiInfoFrameSettings.Colorimetry.Value}");
|
||||
}
|
||||
if (HdmiInfoFrameSettings.ExtendedColorimetry.HasValue)
|
||||
{
|
||||
values.Add($"Ext. colorimetry: {HdmiInfoFrameSettings.ExtendedColorimetry.Value}");
|
||||
}
|
||||
if (HdmiInfoFrameSettings.ContentType.HasValue)
|
||||
{
|
||||
values.Add($"Content type: {HdmiInfoFrameSettings.ContentType.Value}");
|
||||
}
|
||||
|
||||
if (!values.Any())
|
||||
{
|
||||
values.Add("None");
|
||||
}
|
||||
|
||||
return string.Join(", ", values);
|
||||
}
|
||||
|
||||
public string GetOtherDescription()
|
||||
{
|
||||
var values = new List<string>();
|
||||
|
||||
if (SDRBrightness.HasValue && (HDREnabled || !IsDisplayPreset))
|
||||
{
|
||||
values.Add($"SDR brightness: {SDRBrightness.Value}%");
|
||||
}
|
||||
if (scaling.HasValue)
|
||||
{
|
||||
values.Add($"Scaling: {scaling.Value.GetDescription()}");
|
||||
}
|
||||
if (!ColorProfileSettings.ProfileName.IsNullOrWhiteSpace())
|
||||
{
|
||||
values.Add($"Color profile: {ColorProfileSettings.ProfileName}");
|
||||
}
|
||||
|
||||
if (!values.Any())
|
||||
{
|
||||
values.Add("None");
|
||||
}
|
||||
|
||||
return string.Join(", ", values);
|
||||
}
|
||||
|
||||
public static ColorData DefaultColorData => new ColorData(ColorDataFormat.Auto, dynamicRange: ColorDataDynamicRange.Auto, colorDepth: ColorDataDepth.Default, colorSelectionPolicy: ColorDataSelectionPolicy.BestQuality);
|
||||
|
||||
public static List<NvPreset> GetDefaultPresets()
|
||||
{
|
||||
var presets = new List<NvPreset>
|
||||
{
|
||||
new NvPreset(DefaultColorData)
|
||||
};
|
||||
|
||||
for (var dynamicRange = ColorDataDynamicRange.VESA; dynamicRange <= ColorDataDynamicRange.CEA; dynamicRange++)
|
||||
{
|
||||
presets.Add(new NvPreset(new ColorData(ColorDataFormat.RGB, dynamicRange: dynamicRange, colorDepth: ColorDataDepth.BPC8, colorSelectionPolicy: ColorDataSelectionPolicy.User)));
|
||||
presets.Add(new NvPreset(new ColorData(ColorDataFormat.RGB, dynamicRange: dynamicRange, colorDepth: ColorDataDepth.BPC10, colorSelectionPolicy: ColorDataSelectionPolicy.User)));
|
||||
presets.Add(new NvPreset(new ColorData(ColorDataFormat.RGB, dynamicRange: dynamicRange, colorDepth: ColorDataDepth.BPC12, colorSelectionPolicy: ColorDataSelectionPolicy.User)));
|
||||
}
|
||||
|
||||
for (var format = ColorDataFormat.YUV422; format <= ColorDataFormat.YUV420; format++)
|
||||
{
|
||||
presets.Add(new NvPreset(new ColorData(format, dynamicRange: ColorDataDynamicRange.Auto, colorDepth: ColorDataDepth.BPC8, colorSelectionPolicy: ColorDataSelectionPolicy.User)));
|
||||
presets.Add(new NvPreset(new ColorData(format, dynamicRange: ColorDataDynamicRange.Auto, colorDepth: ColorDataDepth.BPC10, colorSelectionPolicy: ColorDataSelectionPolicy.User)));
|
||||
presets.Add(new NvPreset(new ColorData(format, dynamicRange: ColorDataDynamicRange.Auto, colorDepth: ColorDataDepth.BPC12, colorSelectionPolicy: ColorDataSelectionPolicy.User)));
|
||||
}
|
||||
|
||||
return presets;
|
||||
}
|
||||
|
||||
public override string GetTextForMenuItem()
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
if (!string.IsNullOrEmpty(name))
|
||||
{
|
||||
sb.Append(name);
|
||||
sb.Append(" / ");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (displayName != null)
|
||||
{
|
||||
sb.AppendFormat("Display: {0} / ", displayName);
|
||||
}
|
||||
if (applyColorData)
|
||||
{
|
||||
var colorSettings = string.Format("Format: {0}, {1}, {2}", colorData.ColorDepth, colorData.ColorFormat, colorData.DynamicRange);
|
||||
sb.Append(colorSettings);
|
||||
sb.Append(" / ");
|
||||
}
|
||||
if (applyRefreshRate)
|
||||
{
|
||||
sb.AppendFormat("{0}Hz", refreshRate);
|
||||
sb.Append(" / ");
|
||||
}
|
||||
if (applyResolution)
|
||||
{
|
||||
sb.AppendFormat("{0}x{1}", resolutionWidth, resolutionHeight);
|
||||
sb.Append(" / ");
|
||||
}
|
||||
if (applyDithering)
|
||||
{
|
||||
var dithering = GetDitheringDescription("No");
|
||||
sb.AppendFormat("Dithering: {0}", dithering);
|
||||
sb.Append(" / ");
|
||||
}
|
||||
if (applyHDR)
|
||||
{
|
||||
sb.AppendFormat("HDR: {0}", toggleHDR ? "Toggle" : HDREnabled ? "Enabled" : "Disabled");
|
||||
sb.Append(" / ");
|
||||
}
|
||||
if (applyDriverSettings)
|
||||
{
|
||||
sb.AppendFormat("DRS: {0}", GetDriverSettingsDescription());
|
||||
sb.Append(" / ");
|
||||
}
|
||||
}
|
||||
|
||||
return sb.ToString(0, Math.Max(0, sb.Length - 3));
|
||||
}
|
||||
|
||||
public static ColorData GenerateColorData(IDictionary<string, object> dictionary)
|
||||
{
|
||||
var format = ColorDataFormat.RGB;
|
||||
var dynamicRange = ColorDataDynamicRange.VESA;
|
||||
var colorDepth = ColorDataDepth.BPC8;
|
||||
var colorimetry = ColorDataColorimetry.Auto;
|
||||
var selectionPolicy = ColorDataSelectionPolicy.User;
|
||||
object value;
|
||||
if (dictionary.TryGetValue("ColorFormat", out value))
|
||||
{
|
||||
format = (ColorDataFormat)Enum.ToObject(typeof(ColorDataFormat), value);
|
||||
}
|
||||
if (dictionary.TryGetValue("ColorDepth", out value))
|
||||
{
|
||||
colorDepth = (ColorDataDepth)Enum.ToObject(typeof(ColorDataDepth), value);
|
||||
}
|
||||
if (dictionary.TryGetValue("Colorimetry", out value))
|
||||
{
|
||||
colorimetry = (ColorDataColorimetry)Enum.ToObject(typeof(ColorDataColorimetry), value);
|
||||
}
|
||||
if (dictionary.TryGetValue("DynamicRange", out value))
|
||||
{
|
||||
dynamicRange = (ColorDataDynamicRange)Enum.ToObject(typeof(ColorDataDynamicRange), value);
|
||||
}
|
||||
if (dictionary.TryGetValue("SelectionPolicy", out _))
|
||||
{
|
||||
selectionPolicy =
|
||||
colorDepth == ColorDataDepth.Default &&
|
||||
format >= ColorDataFormat.Default &&
|
||||
colorimetry >= ColorDataColorimetry.Default &&
|
||||
dynamicRange == ColorDataDynamicRange.Auto ?
|
||||
ColorDataSelectionPolicy.BestQuality : selectionPolicy;
|
||||
}
|
||||
return new ColorData(format, dynamicRange: dynamicRange, colorimetry: colorimetry, colorDepth: colorDepth, colorSelectionPolicy: selectionPolicy, desktopColorDepth: ColorDataDesktopDepth.Default);
|
||||
}
|
||||
|
||||
internal void UpdateDriverSetting(SettingItem settingItem, uint settingValue)
|
||||
{
|
||||
driverSettings[settingItem.SettingId] = settingValue;
|
||||
}
|
||||
|
||||
internal void ResetDriverSetting(uint settingId)
|
||||
{
|
||||
driverSettings.Remove(settingId);
|
||||
}
|
||||
|
||||
internal void UpdateOverclockingSetting(NvGpuOcSettings newSettings)
|
||||
{
|
||||
var index = ocSettings.FindIndex(s => s.PCIIdentifier == newSettings.PCIIdentifier);
|
||||
|
||||
if (index >= 0)
|
||||
{
|
||||
ocSettings[index] = newSettings;
|
||||
}
|
||||
else
|
||||
{
|
||||
ocSettings.Add(newSettings);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,12 @@
|
||||
namespace ColorControl.Services.NVIDIA
|
||||
{
|
||||
class NvServiceConfig
|
||||
{
|
||||
public bool ShowOverclocking { get; set; }
|
||||
public bool ApplyNovideoOnStartup { get; set; }
|
||||
|
||||
public NvServiceConfig()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,400 @@
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
|
||||
// If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
// Copyright (C) LibreHardwareMonitor and Contributors.
|
||||
// All Rights Reserved.
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace ColorControl.Services.NVIDIA;
|
||||
|
||||
internal static class NvidiaML
|
||||
{
|
||||
private const string LinuxDllName = "nvidia-ml";
|
||||
private const string WindowsDllName = "nvml.dll";
|
||||
|
||||
private static readonly object _syncRoot = new();
|
||||
|
||||
private static IntPtr _windowsDll;
|
||||
|
||||
private static WindowsNvmlGetHandleDelegate _windowsNvmlDeviceGetHandleByIndex;
|
||||
private static WindowsNvmlGetHandleByPciBusIdDelegate _windowsNvmlDeviceGetHandleByPciBusId;
|
||||
private static WindowsNvmlDeviceGetPcieThroughputDelegate _windowsNvmlDeviceGetPcieThroughputDelegate;
|
||||
private static WindowsNvmlDeviceGetPciInfo _windowsNvmlDeviceGetPciInfo;
|
||||
private static WindowsNvmlGetPowerUsageDelegate _windowsNvmlDeviceGetPowerUsage;
|
||||
private static WindowsNvmlGetPowerManagementDefaultLimitDelegate _windowsNvmlDevicePowerManagementDefaultLimit;
|
||||
private static WindowsNvmlDelegate _windowsNvmlInit;
|
||||
private static WindowsNvmlDelegate _windowsNvmlShutdown;
|
||||
|
||||
public enum NvmlPcieUtilCounter
|
||||
{
|
||||
TxBytes = 0,
|
||||
RxBytes = 1
|
||||
}
|
||||
|
||||
public enum NvmlReturn
|
||||
{
|
||||
/// <summary>
|
||||
/// The operation was successful
|
||||
/// </summary>
|
||||
Success = 0,
|
||||
|
||||
/// <summary>
|
||||
/// NvidiaML was not first initialized with nvmlInit()
|
||||
/// </summary>
|
||||
Uninitialized = 1,
|
||||
|
||||
/// <summary>
|
||||
/// A supplied argument is invalid
|
||||
/// </summary>
|
||||
InvalidArgument = 2,
|
||||
|
||||
/// <summary>
|
||||
/// The requested operation is not available on target device
|
||||
/// </summary>
|
||||
NotSupported = 3,
|
||||
|
||||
/// <summary>
|
||||
/// The current user does not have permission for operation
|
||||
/// </summary>
|
||||
NoPermission = 4,
|
||||
|
||||
/// <summary>
|
||||
/// A query to find an object was unsuccessful
|
||||
/// </summary>
|
||||
NotFound = 6,
|
||||
|
||||
/// <summary>
|
||||
/// An input argument is not large enough
|
||||
/// </summary>
|
||||
InsufficientSize = 7,
|
||||
|
||||
/// <summary>
|
||||
/// A device's external power cables are not properly attached
|
||||
/// </summary>
|
||||
InsufficientPower = 8,
|
||||
|
||||
/// <summary>
|
||||
/// NVIDIA driver is not loaded
|
||||
/// </summary>
|
||||
DriverNotLoaded = 9,
|
||||
|
||||
/// <summary>
|
||||
/// User provided timeout passed
|
||||
/// </summary>
|
||||
TimeOut = 10,
|
||||
|
||||
/// <summary>
|
||||
/// NVIDIA Kernel detected an interrupt issue with a GPU
|
||||
/// </summary>
|
||||
IRQIssue = 11,
|
||||
|
||||
/// <summary>
|
||||
/// NvidiaML Shared Library couldn't be found or loaded
|
||||
/// </summary>
|
||||
LibraryNotFound = 12,
|
||||
|
||||
/// <summary>
|
||||
/// Local version of NvidiaML doesn't implement this function
|
||||
/// </summary>
|
||||
FunctionNotFound = 13,
|
||||
|
||||
/// <summary>
|
||||
/// infoROM is corrupted
|
||||
/// </summary>
|
||||
CorruptedInfoRom = 14,
|
||||
|
||||
/// <summary>
|
||||
/// The GPU has fallen off the bus or has otherwise become inaccessible
|
||||
/// </summary>
|
||||
GpuIsLost = 15,
|
||||
|
||||
/// <summary>
|
||||
/// The GPU requires a reset before it can be used again
|
||||
/// </summary>
|
||||
ResetRequired = 16,
|
||||
|
||||
/// <summary>
|
||||
/// The GPU control device has been blocked by the operating system/cgroups
|
||||
/// </summary>
|
||||
OperatingSystem = 17,
|
||||
|
||||
/// <summary>
|
||||
/// RM detects a driver/library version mismatch
|
||||
/// </summary>
|
||||
LibRmVersionMismatch = 18,
|
||||
|
||||
/// <summary>
|
||||
/// An operation cannot be performed because the GPU is currently in use
|
||||
/// </summary>
|
||||
InUse = 19,
|
||||
|
||||
/// <summary>
|
||||
/// An public driver error occurred
|
||||
/// </summary>
|
||||
Unknown = 999
|
||||
}
|
||||
|
||||
public static bool IsAvailable { get; private set; }
|
||||
|
||||
public static bool Initialize()
|
||||
{
|
||||
lock (_syncRoot)
|
||||
{
|
||||
if (IsAvailable)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// Attempt to load the Nvidia Management Library from the
|
||||
// windows standard search order for applications. This will
|
||||
// help installations that either have the library in
|
||||
// %windir%/system32 or provide their own library
|
||||
_windowsDll = Kernel32.LoadLibrary(WindowsDllName);
|
||||
|
||||
// If there is no dll in the path, then attempt to load it
|
||||
// from program files
|
||||
if (_windowsDll == IntPtr.Zero)
|
||||
{
|
||||
string programFilesDirectory = Environment.ExpandEnvironmentVariables("%ProgramW6432%");
|
||||
string dllPath = Path.Combine(programFilesDirectory, @"NVIDIA Corporation\NVSMI", WindowsDllName);
|
||||
|
||||
_windowsDll = Kernel32.LoadLibrary(dllPath);
|
||||
}
|
||||
|
||||
IsAvailable = (_windowsDll != IntPtr.Zero) && InitialiseDelegates() && (_windowsNvmlInit() == NvmlReturn.Success);
|
||||
|
||||
return IsAvailable;
|
||||
}
|
||||
}
|
||||
|
||||
private static bool InitialiseDelegates()
|
||||
{
|
||||
IntPtr nvmlInit = Kernel32.GetProcAddress(_windowsDll, "nvmlInit_v2");
|
||||
|
||||
if (nvmlInit != IntPtr.Zero)
|
||||
{
|
||||
_windowsNvmlInit = (WindowsNvmlDelegate)Marshal.GetDelegateForFunctionPointer(nvmlInit, typeof(WindowsNvmlDelegate));
|
||||
}
|
||||
else
|
||||
{
|
||||
nvmlInit = Kernel32.GetProcAddress(_windowsDll, "nvmlInit");
|
||||
if (nvmlInit != IntPtr.Zero)
|
||||
_windowsNvmlInit = (WindowsNvmlDelegate)Marshal.GetDelegateForFunctionPointer(nvmlInit, typeof(WindowsNvmlDelegate));
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
IntPtr nvmlShutdown = Kernel32.GetProcAddress(_windowsDll, "nvmlShutdown");
|
||||
if (nvmlShutdown != IntPtr.Zero)
|
||||
_windowsNvmlShutdown = (WindowsNvmlDelegate)Marshal.GetDelegateForFunctionPointer(nvmlShutdown, typeof(WindowsNvmlDelegate));
|
||||
else
|
||||
return false;
|
||||
|
||||
IntPtr nvmlGetHandle = Kernel32.GetProcAddress(_windowsDll, "nvmlDeviceGetHandleByIndex_v2");
|
||||
if (nvmlGetHandle != IntPtr.Zero)
|
||||
_windowsNvmlDeviceGetHandleByIndex = (WindowsNvmlGetHandleDelegate)Marshal.GetDelegateForFunctionPointer(nvmlGetHandle, typeof(WindowsNvmlGetHandleDelegate));
|
||||
else
|
||||
{
|
||||
nvmlGetHandle = Kernel32.GetProcAddress(_windowsDll, "nvmlDeviceGetHandleByIndex");
|
||||
if (nvmlGetHandle != IntPtr.Zero)
|
||||
_windowsNvmlDeviceGetHandleByIndex = (WindowsNvmlGetHandleDelegate)Marshal.GetDelegateForFunctionPointer(nvmlGetHandle, typeof(WindowsNvmlGetHandleDelegate));
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
IntPtr nvmlGetPowerUsage = Kernel32.GetProcAddress(_windowsDll, "nvmlDeviceGetPowerUsage");
|
||||
if (nvmlGetPowerUsage != IntPtr.Zero)
|
||||
_windowsNvmlDeviceGetPowerUsage = (WindowsNvmlGetPowerUsageDelegate)Marshal.GetDelegateForFunctionPointer(nvmlGetPowerUsage, typeof(WindowsNvmlGetPowerUsageDelegate));
|
||||
else
|
||||
return false;
|
||||
|
||||
IntPtr nvmlGetPowerManagementDefaultLimit = Kernel32.GetProcAddress(_windowsDll, "nvmlDeviceGetPowerManagementDefaultLimit");
|
||||
if (nvmlGetPowerManagementDefaultLimit != IntPtr.Zero)
|
||||
_windowsNvmlDevicePowerManagementDefaultLimit = (WindowsNvmlGetPowerManagementDefaultLimitDelegate)Marshal.GetDelegateForFunctionPointer(nvmlGetPowerManagementDefaultLimit, typeof(WindowsNvmlGetPowerManagementDefaultLimitDelegate));
|
||||
else
|
||||
return false;
|
||||
|
||||
IntPtr nvmlGetPcieThroughput = Kernel32.GetProcAddress(_windowsDll, "nvmlDeviceGetPcieThroughput");
|
||||
if (nvmlGetPcieThroughput != IntPtr.Zero)
|
||||
_windowsNvmlDeviceGetPcieThroughputDelegate = (WindowsNvmlDeviceGetPcieThroughputDelegate)Marshal.GetDelegateForFunctionPointer(nvmlGetPcieThroughput, typeof(WindowsNvmlDeviceGetPcieThroughputDelegate));
|
||||
else
|
||||
return false;
|
||||
|
||||
IntPtr nvmlGetHandlePciBus = Kernel32.GetProcAddress(_windowsDll, "nvmlDeviceGetHandleByPciBusId_v2");
|
||||
if (nvmlGetHandlePciBus != IntPtr.Zero)
|
||||
_windowsNvmlDeviceGetHandleByPciBusId = (WindowsNvmlGetHandleByPciBusIdDelegate)Marshal.GetDelegateForFunctionPointer(nvmlGetHandlePciBus, typeof(WindowsNvmlGetHandleByPciBusIdDelegate));
|
||||
else
|
||||
return false;
|
||||
|
||||
IntPtr nvmlDeviceGetPciInfo = Kernel32.GetProcAddress(_windowsDll, "nvmlDeviceGetPciInfo_v2");
|
||||
if (nvmlDeviceGetPciInfo != IntPtr.Zero)
|
||||
_windowsNvmlDeviceGetPciInfo = (WindowsNvmlDeviceGetPciInfo)Marshal.GetDelegateForFunctionPointer(nvmlDeviceGetPciInfo, typeof(WindowsNvmlDeviceGetPciInfo));
|
||||
else
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static void Close()
|
||||
{
|
||||
lock (_syncRoot)
|
||||
{
|
||||
if (IsAvailable)
|
||||
{
|
||||
if (_windowsDll != IntPtr.Zero)
|
||||
{
|
||||
_windowsNvmlShutdown();
|
||||
Kernel32.FreeLibrary(_windowsDll);
|
||||
}
|
||||
|
||||
IsAvailable = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static NvmlDevice? NvmlDeviceGetHandleByIndex(int index)
|
||||
{
|
||||
if (IsAvailable)
|
||||
{
|
||||
NvmlDevice nvmlDevice;
|
||||
if (_windowsNvmlDeviceGetHandleByIndex(index, out nvmlDevice) == NvmlReturn.Success)
|
||||
return nvmlDevice;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static NvmlDevice? NvmlDeviceGetHandleByPciBusId(string pciBusId)
|
||||
{
|
||||
if (IsAvailable)
|
||||
{
|
||||
NvmlDevice nvmlDevice;
|
||||
if (_windowsNvmlDeviceGetHandleByPciBusId(pciBusId, out nvmlDevice) == NvmlReturn.Success)
|
||||
return nvmlDevice;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static int? NvmlDeviceGetPowerUsage(NvmlDevice nvmlDevice)
|
||||
{
|
||||
if (IsAvailable)
|
||||
{
|
||||
int powerUsage;
|
||||
if (_windowsNvmlDeviceGetPowerUsage(nvmlDevice, out powerUsage) == NvmlReturn.Success)
|
||||
return powerUsage;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static int? NvmlDeviceGetPowerManagementDefaultLimit(NvmlDevice nvmlDevice)
|
||||
{
|
||||
if (IsAvailable)
|
||||
{
|
||||
int defaultLimit;
|
||||
if (_windowsNvmlDevicePowerManagementDefaultLimit(nvmlDevice, out defaultLimit) == NvmlReturn.Success)
|
||||
return defaultLimit;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static uint? NvmlDeviceGetPcieThroughput(NvmlDevice nvmlDevice, NvmlPcieUtilCounter counter)
|
||||
{
|
||||
if (IsAvailable)
|
||||
{
|
||||
uint pcieThroughput;
|
||||
if (_windowsNvmlDeviceGetPcieThroughputDelegate(nvmlDevice, counter, out pcieThroughput) == NvmlReturn.Success)
|
||||
return pcieThroughput;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static NvmlPciInfo? NvmlDeviceGetPciInfo(NvmlDevice nvmlDevice)
|
||||
{
|
||||
if (IsAvailable)
|
||||
{
|
||||
var pci = new NvmlPciInfo();
|
||||
|
||||
if (_windowsNvmlDeviceGetPciInfo(nvmlDevice, ref pci) == NvmlReturn.Success)
|
||||
return pci;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
[DllImport(LinuxDllName, EntryPoint = "nvmlInit_v2", ExactSpelling = true)]
|
||||
private static extern NvmlReturn nvmlInit();
|
||||
|
||||
[DllImport(LinuxDllName, EntryPoint = "nvmlInit", ExactSpelling = true)]
|
||||
private static extern NvmlReturn nvmlInitLegacy();
|
||||
|
||||
[DllImport(LinuxDllName, EntryPoint = "nvmlShutdown", ExactSpelling = true)]
|
||||
private static extern NvmlReturn nvmlShutdown();
|
||||
|
||||
[DllImport(LinuxDllName, EntryPoint = "nvmlDeviceGetHandleByIndex_v2", ExactSpelling = true)]
|
||||
private static extern NvmlReturn nvmlDeviceGetHandleByIndex(int index, out NvmlDevice device);
|
||||
|
||||
[DllImport(LinuxDllName, EntryPoint = "nvmlDeviceGetHandleByPciBusId_v2", ExactSpelling = true)]
|
||||
private static extern NvmlReturn nvmlDeviceGetHandleByPciBusId([MarshalAs(UnmanagedType.LPStr)] string pciBusId, out NvmlDevice device);
|
||||
|
||||
[DllImport(LinuxDllName, EntryPoint = "nvmlDeviceGetHandleByIndex", ExactSpelling = true)]
|
||||
private static extern NvmlReturn nvmlDeviceGetHandleByIndexLegacy(int index, out NvmlDevice device);
|
||||
|
||||
[DllImport(LinuxDllName, EntryPoint = "nvmlDeviceGetPowerUsage", ExactSpelling = true)]
|
||||
private static extern NvmlReturn nvmlDeviceGetPowerUsage(NvmlDevice device, out int power);
|
||||
|
||||
[DllImport(LinuxDllName, EntryPoint = "nvmlDeviceGetPcieThroughput", ExactSpelling = true)]
|
||||
private static extern NvmlReturn nvmlDeviceGetPcieThroughput(NvmlDevice device, NvmlPcieUtilCounter counter, out uint value);
|
||||
|
||||
[DllImport(LinuxDllName, EntryPoint = "nvmlDeviceGetPciInfo_v2")]
|
||||
private static extern NvmlReturn nvmlDeviceGetPciInfo(NvmlDevice device, ref NvmlPciInfo pci);
|
||||
|
||||
private delegate NvmlReturn WindowsNvmlDelegate();
|
||||
|
||||
private delegate NvmlReturn WindowsNvmlGetHandleDelegate(int index, out NvmlDevice device);
|
||||
|
||||
private delegate NvmlReturn WindowsNvmlGetHandleByPciBusIdDelegate([MarshalAs(UnmanagedType.LPStr)] string pciBusId, out NvmlDevice device);
|
||||
|
||||
private delegate NvmlReturn WindowsNvmlGetPowerUsageDelegate(NvmlDevice device, out int power);
|
||||
|
||||
private delegate NvmlReturn WindowsNvmlGetPowerManagementDefaultLimitDelegate(NvmlDevice device, out int defaultLimit);
|
||||
|
||||
private delegate NvmlReturn WindowsNvmlDeviceGetPcieThroughputDelegate(NvmlDevice device, NvmlPcieUtilCounter counter, out uint value);
|
||||
|
||||
private delegate NvmlReturn WindowsNvmlDeviceGetPciInfo(NvmlDevice device, ref NvmlPciInfo pci);
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct NvmlDevice
|
||||
{
|
||||
public IntPtr Handle;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct NvmlPciInfo
|
||||
{
|
||||
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)]
|
||||
public string busId;
|
||||
|
||||
public uint domain;
|
||||
|
||||
public uint bus;
|
||||
|
||||
public uint device;
|
||||
|
||||
public ushort pciVendorId;
|
||||
|
||||
public ushort pciDeviceId;
|
||||
|
||||
public uint pciSubSystemId;
|
||||
|
||||
public uint reserved0;
|
||||
public uint reserved1;
|
||||
public uint reserved2;
|
||||
public uint reserved3;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace ColorControl.Services.Samsung
|
||||
{
|
||||
internal interface ISamsungService
|
||||
{
|
||||
SamsungServiceConfig Config { get; }
|
||||
List<SamsungDevice> Devices { get; }
|
||||
SamsungDevice SelectedDevice { get; set; }
|
||||
string ServiceName { get; }
|
||||
|
||||
Task<bool> ApplyPreset(SamsungPreset preset);
|
||||
Task<bool> ApplyPreset(string idOrName);
|
||||
SamsungDevice GetPresetDevice(SamsungPreset preset);
|
||||
void GlobalSave();
|
||||
void InstallEventHandlers();
|
||||
Task RefreshDevices(bool connect = true, bool afterStartUp = false);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace ColorControl.Services.Samsung
|
||||
{
|
||||
internal class RawRequestMessage
|
||||
{
|
||||
public RawRequestMessage(RequestMessage rm, int commandCount)
|
||||
{
|
||||
Id = commandCount.ToString();
|
||||
Method = rm.Method;
|
||||
Params = rm.Params;
|
||||
}
|
||||
|
||||
[JsonIgnore]
|
||||
public string Id { get; set; }
|
||||
|
||||
[JsonProperty("method")]
|
||||
public string Method { get; set; }
|
||||
[JsonProperty("params")]
|
||||
public object Params { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
namespace ColorControl.Services.Samsung
|
||||
{
|
||||
public class RequestMessage
|
||||
{
|
||||
public RequestMessage(string method, object payload)
|
||||
{
|
||||
Method = method;
|
||||
Params = payload;
|
||||
}
|
||||
|
||||
public string Method { get; set; }
|
||||
public object Params { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,328 @@
|
||||
using ColorControl.Shared.Common;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Serialization;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Windows.Networking.Sockets;
|
||||
using Windows.Security.Cryptography.Certificates;
|
||||
using Windows.Storage.Streams;
|
||||
|
||||
namespace ColorControl.Services.Samsung
|
||||
{
|
||||
public class SendMessageException : Exception
|
||||
{
|
||||
public SendMessageException(string message, Exception e) : base(message, e)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public delegate void ConnectedDelegate(string token, bool disconnect);
|
||||
|
||||
public class SamTvConnection : IDisposable
|
||||
{
|
||||
public static SynchronizationContext SyncContext { get; set; }
|
||||
|
||||
public bool? ConnectionClosed { get; private set; }
|
||||
public bool ClosedByDispose { get; private set; }
|
||||
|
||||
private MessageWebSocket _connection;
|
||||
private DataWriter _messageWriter;
|
||||
private int _commandCount;
|
||||
private int _readTimeout;
|
||||
|
||||
public event ConnectedDelegate Connected;
|
||||
private readonly ConcurrentDictionary<string, TaskCompletionSource<dynamic>> _tokens = new ConcurrentDictionary<string, TaskCompletionSource<dynamic>>();
|
||||
private readonly ConcurrentDictionary<string, Func<dynamic, bool>> _callbacks = new ConcurrentDictionary<string, Func<dynamic, bool>>();
|
||||
|
||||
private static readonly NLog.Logger Logger = NLog.LogManager.GetCurrentClassLogger();
|
||||
|
||||
public async Task<bool> Connect(Uri uri, int readTimeout = 5000)
|
||||
{
|
||||
_readTimeout = readTimeout;
|
||||
|
||||
try
|
||||
{
|
||||
_connection?.Dispose();
|
||||
|
||||
_commandCount = 0;
|
||||
|
||||
// Not creating the web socket from main thread can cause a stackoverflow in combase32.dll
|
||||
if (Environment.CurrentManagedThreadId != 1)
|
||||
{
|
||||
SyncContext.Send((_) => CreateWebSocket(), null);
|
||||
}
|
||||
else
|
||||
{
|
||||
CreateWebSocket();
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
await _connection.ConnectAsync(uri).AsTask().WaitAsync(TimeSpan.FromSeconds(5));
|
||||
|
||||
ConnectionClosed = false;
|
||||
|
||||
_messageWriter = new DataWriter(_connection.OutputStream);
|
||||
|
||||
return true;
|
||||
}
|
||||
catch (TimeoutException te)
|
||||
{
|
||||
Logger.Error($"Connect to {uri}: {te.Message}");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
switch (SocketError.GetStatus(e.HResult))
|
||||
{
|
||||
case SocketErrorStatus.HostNotFound:
|
||||
// Handle HostNotFound Error
|
||||
break;
|
||||
default:
|
||||
// Handle Unknown Error
|
||||
break;
|
||||
}
|
||||
|
||||
Logger.Error($"Connect to {uri}: {e.Message}");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private void CreateWebSocket()
|
||||
{
|
||||
_connection = new MessageWebSocket();
|
||||
_connection.Control.IgnorableServerCertificateErrors.Add(ChainValidationResult.Untrusted);
|
||||
_connection.Control.IgnorableServerCertificateErrors.Add(ChainValidationResult.InvalidName);
|
||||
_connection.Control.MessageType = SocketMessageType.Utf8;
|
||||
_connection.MessageReceived += Connection_MessageReceived;
|
||||
_connection.Closed += Connection_Closed;
|
||||
}
|
||||
|
||||
public async Task SendMessageAsync(string message)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (_messageWriter == null)
|
||||
{
|
||||
throw new Exception("SendMessageAsync: no writer");
|
||||
}
|
||||
|
||||
_messageWriter.WriteString(message);
|
||||
|
||||
await _messageWriter.StoreAsync().AsTask().WaitAsync(TimeSpan.FromSeconds(5));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.Error("SendMessageAsync: " + e.Message);
|
||||
ConnectionClosed = true;
|
||||
_messageWriter?.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<dynamic> SendCommandAsync(string id, string message, bool waitForAnswer = true)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (waitForAnswer)
|
||||
{
|
||||
var taskSource = new TaskCompletionSource<dynamic>();
|
||||
_tokens.TryAdd(id, taskSource);
|
||||
|
||||
await SendMessageAsync(message);
|
||||
if (ConnectionClosed == true)
|
||||
{
|
||||
throw new Exception("Connection closed");
|
||||
}
|
||||
|
||||
return await taskSource.Task;
|
||||
}
|
||||
else
|
||||
{
|
||||
await SendMessageAsync(message);
|
||||
if (ConnectionClosed == true)
|
||||
{
|
||||
throw new Exception("Connection closed");
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new SendMessageException("Can't send message", e);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<dynamic> SendCommandAsync(RequestMessage message, bool waitForAnswer = true)
|
||||
{
|
||||
var rawMessage = new RawRequestMessage(message, ++_commandCount);
|
||||
var serialized = JsonConvert.SerializeObject(rawMessage, new JsonSerializerSettings()
|
||||
{
|
||||
NullValueHandling = NullValueHandling.Ignore,
|
||||
//ContractResolver = new CamelCasePropertyNamesContractResolver()
|
||||
});
|
||||
return await SendCommandAsync(rawMessage.Id, serialized, waitForAnswer);
|
||||
}
|
||||
|
||||
public async Task<dynamic> SubscribeAsync(RequestMessage message, Func<dynamic, bool> callback)
|
||||
{
|
||||
var rawMessage = new RawRequestMessage(message, ++_commandCount);
|
||||
var serialized = JsonConvert.SerializeObject(rawMessage, new JsonSerializerSettings()
|
||||
{
|
||||
NullValueHandling = NullValueHandling.Ignore,
|
||||
ContractResolver = new CamelCasePropertyNamesContractResolver()
|
||||
});
|
||||
|
||||
_callbacks.TryAdd(rawMessage.Id, callback);
|
||||
|
||||
return await SendCommandAsync(rawMessage.Id, serialized);
|
||||
}
|
||||
|
||||
private void Connection_Closed(IWebSocket sender, WebSocketClosedEventArgs args)
|
||||
{
|
||||
var webSocket = Interlocked.Exchange(ref _connection, null);
|
||||
webSocket?.Dispose();
|
||||
ConnectionClosed = true;
|
||||
|
||||
Logger.Debug("Connection closed");
|
||||
|
||||
Connected?.Invoke(null, true);
|
||||
}
|
||||
|
||||
private const string MS_CHANNEL_CONNECT_EVENT = "ms.channel.connect";
|
||||
private const string MS_CHANNEL_CLIENT_CONNECT_EVENT = "ms.channel.clientConnect";
|
||||
private const string MS_CHANNEL_CLIENT_DISCONNECT_EVENT = "ms.channel.clientDisconnect";
|
||||
private const string MS_CHANNEL_READY_EVENT = "ms.channel.ready";
|
||||
private const string MS_CHANNEL_UNAUTHORIZED = "ms.channel.unauthorized";
|
||||
private const string MS_ERROR_EVENT = "ms.error";
|
||||
|
||||
private async void Connection_MessageReceived(MessageWebSocket sender, MessageWebSocketMessageReceivedEventArgs args)
|
||||
{
|
||||
try
|
||||
{
|
||||
var task = new Task<DataReader>(args.GetDataReader);
|
||||
task.Start();
|
||||
var dataReader = await task.WaitAsync(TimeSpan.FromMilliseconds(_readTimeout));
|
||||
|
||||
using (dataReader)
|
||||
{
|
||||
dataReader.UnicodeEncoding = UnicodeEncoding.Utf8;
|
||||
var message = dataReader.ReadString(dataReader.UnconsumedBufferLength);
|
||||
var obj = JsonConvert.DeserializeObject<dynamic>(message);
|
||||
var id = (string)obj.id;
|
||||
var type = (string)obj.@event;
|
||||
|
||||
Logger.Debug($"Received message: {message}");
|
||||
|
||||
// Response:
|
||||
// {"data":{"clients":[{"attributes":{"name":"c2Ftc3VuZ2N0bA=="},"connectTime":1685302606520,"deviceName":"c2Ftc3VuZ2N0bA==","id":"92e0cbc1-6f86-4013-9b9b-65a47afb2236","isHost":false}],"id":"92e0cbc1-6f86-4013-9b9b-65a47afb2236","token":"16224598"},"event":"ms.channel.connect"}
|
||||
// Second response:
|
||||
// {"data":{"clients":[{"attributes":{"name":"c2Ftc3VuZ2N0bA==","token":"16224598"},"connectTime":1685303321571,"deviceName":"c2Ftc3VuZ2N0bA==","id":"58589451-2ecf-44f0-9267-31983a5466","isHost":false}],"id":"58589451-2ecf-44f0-9267-31983a5466"},"event":"ms.channel.connect"}
|
||||
|
||||
//TaskCompletionSource<dynamic> taskCompletion;
|
||||
if (type == MS_CHANNEL_CONNECT_EVENT)
|
||||
{
|
||||
var token = (string)obj.data?.token;
|
||||
|
||||
if (token == null)
|
||||
{
|
||||
token = (string)obj.data?.clients[0]?.attributes?.token;
|
||||
}
|
||||
|
||||
if (token != null)
|
||||
{
|
||||
Connected?.Invoke(token, false);
|
||||
}
|
||||
|
||||
//if (_tokens.TryRemove(id, out taskCompletion))
|
||||
//{
|
||||
// var key = (string)JObject.Parse(message)["payload"]["client-key"];
|
||||
// taskCompletion.TrySetResult(new { clientKey = key });
|
||||
//}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
}
|
||||
//else if (_tokens.TryGetValue(id, out taskCompletion))
|
||||
//{
|
||||
// if (id == "register_0") return;
|
||||
// if (obj.type == "error")
|
||||
// {
|
||||
// taskCompletion.SetException(new Exception(obj.error?.ToString()));
|
||||
// }
|
||||
// //else if (args.Cancelled)
|
||||
// //{
|
||||
// // taskSource.SetCanceled();
|
||||
// //}
|
||||
// taskCompletion.TrySetResult(obj.payload);
|
||||
|
||||
// if (_callbacks.TryGetValue(id, out Func<dynamic, bool> callback))
|
||||
// {
|
||||
// try
|
||||
// {
|
||||
// callback(obj.payload);
|
||||
// }
|
||||
// catch (Exception callbackException)
|
||||
// {
|
||||
// Logger.Error($"Connection_MessageReceived: the callback threw an exception: {callbackException.ToLogString()}");
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
var status = WebSocketError.GetStatus(ex.GetBaseException().HResult);
|
||||
Logger.Error($"Connection_MessageReceived: status: {status}, exception: {ex.ToLogString()}");
|
||||
|
||||
SetExceptionOnAllTokens(ex);
|
||||
|
||||
ConnectionClosed = true;
|
||||
|
||||
_messageWriter?.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
private void SetExceptionOnAllTokens(Exception ex)
|
||||
{
|
||||
//Logger.Debug($"Tokens: {_tokens.Count}");
|
||||
|
||||
foreach (var taskCompletion in _tokens.Values)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (taskCompletion.Task.Status != TaskStatus.RanToCompletion)
|
||||
{
|
||||
Logger.Debug("taskCompletion.Task.Status: " + taskCompletion.Task.Status);
|
||||
taskCompletion.SetException(new Exception(ex.Message));
|
||||
}
|
||||
}
|
||||
catch (Exception ex2)
|
||||
{
|
||||
Logger.Error("SetExceptionOnAllTokens: " + ex2.Message);
|
||||
}
|
||||
}
|
||||
|
||||
_tokens.Clear();
|
||||
}
|
||||
|
||||
public void Close()
|
||||
{
|
||||
_connection?.Close(1000, "");
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
ClosedByDispose = true;
|
||||
Close();
|
||||
_connection?.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
namespace ColorControl.Services.Samsung
|
||||
{
|
||||
public class SamsungApp
|
||||
{
|
||||
public string Title { get; set; }
|
||||
public string AppId { get; set; }
|
||||
|
||||
public SamsungApp(string appId, string title)
|
||||
{
|
||||
AppId = appId;
|
||||
Title = title;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return Title;
|
||||
}
|
||||
}
|
||||
}
|
||||
Loaded 100 of 682 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user