Compare commits

...
94 Commits
Author SHA1 Message Date
Vincent Maas bc565abd38 fix auto-start not working, add support for color profiles, add B3 as supported models for service menu unlock 2023-11-25 11:47:52 +01:00
Vincent Maas db19a9ad68 add Nvidia scaling setting 2023-11-05 15:30:22 +01:00
Vincent Maas 9fd8e8f9bb fix Novideo, add Game launcher auto-apply, add some LG actions, move winapi/admin functions to designated services 2023-10-28 14:53:17 +02:00
Vincent Maas 6eae7db459 fix Nvidia error, add HDMI settings, add LG action 2023-08-26 13:33:14 +02:00
Vincent Maas 2c5b08af72 fix modules, add raw input, add service menu to Samsung controller 2023-07-15 14:31:52 +02:00
Vincent Maas 3c5c2b3e4e fix error with dark mode, add clone functionality of current settings, add SDR brightness setting 2023-07-01 17:37:49 +02:00
Vincent Maas c6f9bedcd2 fix crash due to fetching resource from wrong assembly 2023-06-28 14:01:08 +02:00
Vincent Maas de3a1a6e72 uncomment code 2023-06-28 10:44:29 +02:00
Vincent Maas 966b8336de fixed final content type issues and message form width 2023-06-28 10:35:40 +02:00
Vincent Maas bc102334c8 fix xaml, merge latest Nvinspector changes 2023-06-27 22:34:09 +02:00
Vincent Maas 4186d4add5 move shared code to shared project, fix most xaml issues 2023-06-27 19:24:27 +02:00
Vincent Maas e0d1ba13f0 add Nvidia content type setting, start creating base Xaml window 2023-06-27 09:59:24 +02:00
Vincent Maas 21bd8e2080 add missing samsung presets to game launcher 2023-06-25 15:11:08 +02:00
Vincent Maas 3086058ebe fix package version 2023-06-25 14:48:12 +02:00
Vincent Maas 464da6ccb8 fix final issues 2023-06-25 14:36:07 +02:00
Vincent Maas 7e1eb8bfa8 fix final Samsung issues 2023-06-24 14:29:01 +02:00
Vincent Maas 04d447a48b fix most dark mode issues of logging 2023-06-24 10:58:10 +02:00
Vincent Maas 3ef21278cd improve samsung controller, add NLogViewer 2023-06-19 16:29:26 +02:00
Vincent Maas 3d7abd991c add samsung service, fix some issues 2023-06-13 21:58:00 +02:00
Vincent Maas 97b931f433 add licensing 2023-05-27 14:46:23 +02:00
Vincent Maas 7543cca15d fixed #224, added HDMI signalling override and reboot actions, fixed #228, fixed #222 2023-05-22 22:19:23 +02:00
Vincent Maas 58e03313e0 add some 2023 oled settings 2023-05-12 19:25:41 +02:00
Vincent Maas fa013b056f fix issues 2023-05-06 15:38:30 +02:00
Vincent Maas 8c186679cf add dark mode, fix wol 2023-05-06 15:22:24 +02:00
Vincent Maas 047ba98067 fix auto-update, add async handlers, remove old wait for task code, final fix of combase32 crash, readd some LG actions, extend screen saver functionality 2023-04-28 14:35:58 +02:00
Vincent Maas db23e67742 fix crash and nvidia error 2023-04-21 20:11:20 +02:00
Vincent Maas 52fd635fda fix LG device settings not saving, upgrade to .NET 7 2023-04-15 10:37:08 +02:00
Vincent Maas 6318d37247 add modules and make them configurable, enable page up/down shortcuts 2023-04-01 10:29:31 +02:00
Vincent Maas dd083a5e9f improve message dialogs 2023-03-12 16:58:21 +01:00
Vincent Maas 4b6d687e4c move Nvidia dithering test to separate panel 2023-03-04 19:35:39 +01:00
Vincent Maas dbf5670bc3 move LG UI to separate panel 2023-03-04 14:30:13 +01:00
Vincent Maas dd64ba491b move game launcher to separate panel 2023-03-04 13:15:21 +01:00
Vincent Maas 04c6be729f move Amd UI to separate panel 2023-03-04 12:00:55 +01:00
Vincent Maas dc6da0e60d move Nvidia UI to separate panel 2023-03-03 18:59:56 +01:00
Vincent Maas 7fcf154601 add Nvidia overclocking options, integrate NvAPIWrapper/NvidiaML to enable and extend overclocking (curve), some other fixes 2023-03-03 14:40:56 +01:00
Vincent Maas 1c5095777c add some missing LG settings, add Nvidia driver settings, fix game launcher not executing LG presets 2023-02-09 20:00:04 +01:00
Vincent Maas 0322e7243d Merge branch 'master' of https://github.com/Maassoft/ColorControl 2023-01-19 19:09:08 +01:00
Vincent Maas 57a6a36d9b fix LG connection issues, improve color temperature setting, add rBAR driver settings 2023-01-19 19:08:59 +01:00
Maassoft db1ca339fe Add CLI and uninstallation info 2023-01-17 19:05:17 +01:00
Vincent Maas c85b33127b add check on connection before executing LG actions, update AMD API, improve NVIDIA dithering with multiple displays, add NVIDIA driver settings , fix some crashes 2023-01-07 14:56:04 +01:00
Vincent Maas 43f038e9ee add auto update, add LG expert actions and auto set current device 2022-12-04 10:13:53 +01:00
Maassoft cb09d5c540 Merge pull request #142 from Shraymonks/fix-readme-url
Fix lgtv.js url in readme
2022-11-22 20:01:32 +01:00
Raymond Ha d29f607ab0 Fix lgtv.js url in readme 2022-11-21 13:10:23 -08:00
Vincent Maas dc2f7f493c fixed several issues, add pre-launch/finalize steps to game presets 2022-11-13 15:06:24 +01:00
Vincent Maas 452206729b fix WOL issues, add Windows Service 2022-10-28 14:25:14 +02:00
Vincent Maas a8d41f67c9 fix screensaver issue, add eye comfort mode, improve elevated process and add priority/affinity settings to game launcher 2022-09-11 16:40:55 +02:00
Vincent Maas 84cb7e6446 add auto volume and total power on hours action 2022-07-24 15:14:44 +02:00
Vincent Maas 6c21245b98 fix typo 2022-07-16 15:16:09 +02:00
Vincent Maas a1121c165f fix some issues, add LG aspect ratio/zoom actions 2022-07-16 15:04:07 +02:00
Vincent Maas 5836f88ef0 restructured code (wip), add game launcher and quick access 2022-06-27 19:07:33 +02:00
Vincent Maas 41cf8ae3e2 add/improve some picture settings, allow enabling OLED Motion Pro for C2/G2, add NVIDIA resolution and driver settings 2022-05-21 11:30:28 +02:00
Vincent Maas c1ace0bdd5 add sorting of list views, improve refresh rate/color depth apply order, fix manually turned off tv's 2022-05-01 10:07:22 +02:00
Vincent Maas 66e682ba3d fixed corrupt json file issues, retrieving apps and added HDMI port selection and new power setting 2022-04-03 14:58:14 +02:00
Vincent Maas 0de3deebf7 fixed some nvidia/lg controller issues 2022-03-26 15:19:55 +01:00
Vincent Maas 0c1859f848 add spanish translations to restart detector 2022-02-27 15:23:46 +01:00
Vincent Maas b8910a3b64 fixed several issues, add some LG settings 2022-02-26 14:35:38 +01:00
Vincent Maas b2e7c529a0 fix/add various LG/NVIDIA issues 2022-02-05 11:53:49 +01:00
Vincent Maas 977060e927 fix dithering issues 2022-01-02 15:24:33 +01:00
Vincent Maas f609471fd2 add label to set device config call, add EzAdjust service menu expert button 2021-12-31 14:48:28 +01:00
Vincent Maas a1a94d27db add hdmi 1-4 icon actions 2021-12-29 11:47:47 +01:00
Vincent Maas e12faaba27 remove asp.net framework dependency 2021-12-27 17:50:10 +01:00
Vincent Maas 6f5f7c4dd3 add game bar and some other functions, upgrade to .NET 6 2021-12-27 14:37:14 +01:00
Vincent Maas e1800b8d50 add some LG actions, fix IP address edit box 2021-09-26 10:19:06 +02:00
Vincent Maas 7779533c1e Merge branch 'master' of https://github.com/Maassoft/ColorControl 2021-09-12 14:46:14 +02:00
Vincent Maas 74cefc00f7 add firmware downgrade functionality 2021-09-12 14:46:07 +02:00
Maassoft a8d33b6a30 Update readme (work in progress) 2021-09-05 20:07:07 +02:00
Vincent Maas f83869da04 add turn screen off/on actions 2021-09-04 14:25:48 +02:00
Vincent Maas 815710c081 fix shortcuts and refresh of apps 2021-08-30 19:17:34 +02:00
Vincent Maas 805c516371 fix F13-F24 keys 2021-08-29 16:14:17 +02:00
Vincent Maas b85d929890 fixed process monitor issue, improve shortcuts and Chrome fix 2021-08-29 15:28:18 +02:00
Vincent Maas dd9ce932fc made loading presets code more robust 2021-08-18 11:15:56 +02:00
Vincent Maas 3667243fc7 fixed some issues, added check for updates 2021-08-16 13:59:01 +02:00
Vincent Maas 92f4ab8ef5 add triggers, fixed some bugs 2021-08-13 15:11:33 +02:00
Vincent Maas 90ca095954 add nvidia/amd presets to steps in LG controller 2021-07-04 16:18:59 +02:00
Vincent Maas fa63d8dc4f fixed some issues 2021-06-20 13:59:12 +02:00
Vincent Maas fc134b146a extend eligible models for motion pro, fix bug when adding WOL action 2021-06-11 20:07:51 +02:00
Vincent Maas 3abf106496 extended expert-button, added new actions 2021-06-06 15:58:21 +02:00
Vincent Maas a17534abcb use modelName for detection if eligible for motion pro 2021-05-30 17:17:46 +02:00
Vincent Maas 4614886954 add LG expert button to test new way of changing settings 2021-05-30 10:31:35 +02:00
Vincent Maas 26a91dc7e9 manually add device, add device setting per preset, add remote control image 2021-05-02 17:38:38 +02:00
Vincent Maas cac5180c76 add name to NVIDIA/AMD presets, add CLI 2021-04-18 15:15:55 +02:00
Vincent Maas 0c877623c0 add screensaver trigger, focus main window when already started, fix some bugs 2021-04-03 16:27:59 +02:00
Vincent Maas a33543acd5 add support for AMD GPU's, improve WOL, refactor code 2021-03-20 14:35:58 +01:00
Vincent Maas 7f6175f8ef add WOL to steps, fix saving configs 2021-02-14 15:17:30 +01:00
Vincent Maas fd51bcca99 add alternate WOL function 2021-02-07 10:45:53 +01:00
Vincent Maas 5268e6679e add better logging of network devices when sending WOL 2021-02-05 19:56:19 +01:00
Vincent Maas 91fd44d698 try to wake device first when lookup fails 2021-02-02 19:43:14 +01:00
Vincent Maas 48b13b1c64 improve checking on attached displays 2021-02-01 19:26:03 +01:00
Vincent Maas d2aacbb8e0 fix crash on startup when no displays are active, set thread execution state when powering off tv on standby 2021-01-30 15:23:06 +01:00
Vincent Maas 04d52d6062 add apply on startup, improve remote controller, fixed some bugs 2021-01-24 15:35:00 +01:00
Vincent Maas 13420d2855 Merge branch 'master' of https://github.com/Maassoft/ColorControl 2021-01-11 19:44:04 +01:00
Vincent Maas 43a4660cc5 add some buttons to control LG TV (volume/mute)
add preliminary remote control form
2021-01-11 19:43:53 +01:00
Maassoft 8683cd5be0 Update README.md 2021-01-01 14:32:02 +01:00
Vincent Maas 038a70cc81 add testing/customization of dithering 2020-12-29 19:24:25 +01:00
682 changed files with 107232 additions and 5755 deletions

No files matched your search

+2 -1
View File
@@ -337,4 +337,5 @@ ASALocalRun/
.localhistory/
# BeatPulse healthcheck temp database
healthchecksdb
healthchecksdb
*.clef
+57 -7
View File
@@ -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
+1
View File
@@ -0,0 +1 @@
{"Build":"0.3.261602\u002Befb3cc30a24e699e6e4337f263a2b9478f04f618","CurrentProject":"ColorControl.csproj","EntryPoints":["ColorControl.csproj"],"Properties":{}}
-529
View File
@@ -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
-170
View File
@@ -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;
}
}
}
-186
View File
@@ -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);
}
}
}
-132
View File
@@ -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();
}
}
}
+317
View File
@@ -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"
}
]
}
-25
View File
@@ -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
View File
@@ -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>
-54
View File
@@ -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);
}
}
}
+122
View File
@@ -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);
}
}
}
}
-24
View File
@@ -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
View File
@@ -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
}
}
+53
View File
@@ -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);
}
}
+60
View File
@@ -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>
+7
View File
@@ -0,0 +1,7 @@
namespace ColorControl
{
internal interface IModulePanel
{
public void UpdateInfo();
}
}
-70
View File
@@ -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);
}
}
}
-337
View File
@@ -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());
}
});
}
}
}
-25
View File
@@ -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]";
}
}
}
+494 -1110
View File
File diff suppressed because it is too large. Load diff
+1100 -1576
View File
File diff suppressed because it is too large. Load diff
+25 -31
View File
@@ -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>
-186
View File
@@ -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);
}
}
}
-214
View File
@@ -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();
}
}
}
}
-49
View File
@@ -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
View File
@@ -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);
}
}
}
-36
View File
@@ -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
View File
@@ -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]&quot;;.
/// </summary>
internal static string RC_coords {
get {
return ResourceManager.GetString("RC_coords", resourceCulture);
}
}
}
}
+15 -5
View File
@@ -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"
}
}
}
+77
View File
@@ -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

+37
View File
@@ -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
+396
View File
@@ -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
+402
View File
@@ -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
View File
@@ -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;
}
}
+618
View File
@@ -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);
}
}
}
+63
View File
@@ -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>
+145
View File
@@ -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));
}
}
}
+364
View File
@@ -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;
}
}
}
+212
View File
@@ -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();
}
}
}
+124
View File
@@ -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>
+180
View File
@@ -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;
}
}
}
+493
View File
@@ -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
View File
@@ -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;
}
}
+330
View File
@@ -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;
}
}
}
+63
View File
@@ -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
View File
@@ -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
+129
View File
@@ -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>
+118
View File
@@ -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);
}
}
}
+928
View File
@@ -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
View File
@@ -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>
+84
View File
@@ -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
View File
@@ -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>
+859
View File
@@ -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;
}
}
}
+89
View File
@@ -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
View File
@@ -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
+129
View File
@@ -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>
+437
View File
@@ -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()
{
}
}
}
+400
View File
@@ -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