From 64f5a0d5cc3a6b41a1079811247bfaf524201366 Mon Sep 17 00:00:00 2001 From: Lesueur Benjamin Date: Wed, 25 Oct 2023 11:16:10 +0200 Subject: [PATCH] port from EA - Add support for ONEXPLAYER 2 PRO ARP23P (non eva) - Add support for GPD Win 4 2023 - Improve bluetooth controllers stability and UI experience - Implement power cycling logic for bluetooth controllers - Implement fan control over Rog Ally - Migrated to more reliable and faster HidLibrary - Fixed an issue with broken first start check - Fixed an issue with infinite rumble on start - DualSense and DualShock 4 LED will now be equal to Windows Accent Color --- HandheldCompanion.iss | 2 +- .../Controllers/DS4Controller.cs | 11 + .../Controllers/DualSenseController.cs | 10 + .../Controllers/IController.xaml | 16 +- .../Controllers/IController.xaml.cs | 50 +- HandheldCompanion/Controllers/JSController.cs | 26 + .../Controllers/SteamController.cs | 14 + .../Controllers/XInputController.cs | 76 ++- HandheldCompanion/Devices/ASUS/AsusACPI.cs | 511 ++++++++++++++++++ HandheldCompanion/Devices/ASUS/ROGAlly.cs | 246 +++++---- .../Devices/GPD/GPDWin4-2023-7640U.cs | 74 +++ .../Devices/GPD/GPDWin4-2023-7840U.cs | 74 +++ HandheldCompanion/Devices/IDevice.cs | 33 +- HandheldCompanion/HandheldCompanion.csproj | 6 +- HandheldCompanion/JoyShockLibrary.dll | Bin 245248 -> 246784 bytes .../Managers/ControllerManager.cs | 67 ++- HandheldCompanion/Misc/HidHide.cs | 57 +- HandheldCompanion/Misc/JoyShockLibrary.cs | 2 + HandheldCompanion/Misc/PnPDetails.cs | 148 ++++- .../Properties/Resources.Designer.cs | 45 +- .../Properties/Resources.de-DE.resx | 2 +- .../Properties/Resources.es-ES.resx | 2 +- .../Properties/Resources.fr-FR.resx | 2 +- .../Properties/Resources.it-IT.resx | 2 +- .../Properties/Resources.ja-JP.resx | 2 +- .../Properties/Resources.pt-BR.resx | 2 +- HandheldCompanion/Properties/Resources.resx | 11 +- .../Properties/Resources.ru-RU.resx | 2 +- .../Properties/Resources.zh-CN.resx | 2 +- .../Properties/Resources.zh-Hant.resx | 2 +- .../Properties/Settings.Designer.cs | 19 +- HandheldCompanion/Utils/CommonUtils.cs | 7 + HandheldCompanion/Utils/FileUtils.cs | 1 - .../Views/Pages/ControllerPage.xaml | 10 +- HandheldCompanion/Views/Pages/DevicePage.xaml | 144 +++++ .../Views/Pages/DevicePage.xaml.cs | 125 +++++ .../Views/Pages/SettingsPage.xaml | 127 +---- .../Views/Pages/SettingsPage.xaml.cs | 75 --- HandheldCompanion/Views/SplashScreen.xaml | 1 - HandheldCompanion/Views/SplashScreen.xaml.cs | 5 - .../Views/Windows/MainWindow.xaml | 17 + .../Views/Windows/MainWindow.xaml.cs | 7 +- 42 files changed, 1602 insertions(+), 433 deletions(-) create mode 100644 HandheldCompanion/Devices/ASUS/AsusACPI.cs create mode 100644 HandheldCompanion/Devices/GPD/GPDWin4-2023-7640U.cs create mode 100644 HandheldCompanion/Devices/GPD/GPDWin4-2023-7840U.cs create mode 100644 HandheldCompanion/Views/Pages/DevicePage.xaml create mode 100644 HandheldCompanion/Views/Pages/DevicePage.xaml.cs diff --git a/HandheldCompanion.iss b/HandheldCompanion.iss index a641b5eba..f93aadead 100644 --- a/HandheldCompanion.iss +++ b/HandheldCompanion.iss @@ -389,7 +389,7 @@ end; #define MyAppSetupName 'Handheld Companion' #define MyBuildId 'HandheldCompanion' -#define MyAppVersion '0.18.0.3' +#define MyAppVersion '0.18.0.4' #define MyAppPublisher 'BenjaminLSR' #define MyAppCopyright 'Copyright @ BenjaminLSR' #define MyAppURL 'https://github.com/Valkirie/HandheldCompanion' diff --git a/HandheldCompanion/Controllers/DS4Controller.cs b/HandheldCompanion/Controllers/DS4Controller.cs index c331591f4..f43ba69a7 100644 --- a/HandheldCompanion/Controllers/DS4Controller.cs +++ b/HandheldCompanion/Controllers/DS4Controller.cs @@ -1,6 +1,8 @@ using HandheldCompanion.Inputs; using HandheldCompanion.Managers; using HandheldCompanion.Utils; +using Inkore.UI.WPF.Modern; +using System.Windows; using System.Windows.Media; using static JSL; @@ -97,6 +99,15 @@ public override void Unplug() base.Unplug(); } + public override void SetLightColor(byte R, byte G, byte B) + { + // UI thread + Application.Current.Dispatcher.Invoke(() => + { + JslSetLightColour(UserIndex, CommonUtils.rgb_to_int(R, G, B)); + }); + } + public override void Cleanup() { TimerManager.Tick -= UpdateInputs; diff --git a/HandheldCompanion/Controllers/DualSenseController.cs b/HandheldCompanion/Controllers/DualSenseController.cs index 2bbc7f202..48755e2e8 100644 --- a/HandheldCompanion/Controllers/DualSenseController.cs +++ b/HandheldCompanion/Controllers/DualSenseController.cs @@ -1,6 +1,7 @@ using HandheldCompanion.Inputs; using HandheldCompanion.Managers; using HandheldCompanion.Utils; +using System.Windows; using static JSL; namespace HandheldCompanion.Controllers; @@ -90,6 +91,15 @@ public override void Unplug() base.Unplug(); } + public override void SetLightColor(byte R, byte G, byte B) + { + // UI thread + Application.Current.Dispatcher.Invoke(() => + { + JslSetLightColour(UserIndex, CommonUtils.rgb_to_int(R, G, B)); + }); + } + public override void Cleanup() { TimerManager.Tick -= UpdateInputs; diff --git a/HandheldCompanion/Controllers/IController.xaml b/HandheldCompanion/Controllers/IController.xaml index b73fc82c9..57033b1a5 100644 --- a/HandheldCompanion/Controllers/IController.xaml +++ b/HandheldCompanion/Controllers/IController.xaml @@ -63,11 +63,19 @@ - + Spacing="6" + Visibility="Collapsed"> + + + diff --git a/HandheldCompanion/Controllers/IController.xaml.cs b/HandheldCompanion/Controllers/IController.xaml.cs index 1315d230c..254e7cd71 100644 --- a/HandheldCompanion/Controllers/IController.xaml.cs +++ b/HandheldCompanion/Controllers/IController.xaml.cs @@ -206,8 +206,7 @@ public void InjectButton(ButtonFlags button, bool IsKeyDown, bool IsKeyUp) public virtual void SetVibrationStrength(uint value, bool rumble = false) { VibrationStrength = value / 100.0d; - if (rumble) - Rumble(); + if (rumble) Rumble(); } public virtual void SetVibration(byte LargeMotor, byte SmallMotor) @@ -223,11 +222,14 @@ public virtual bool IsConnected() return false; } - public virtual async void Rumble(int delay = 125) + public virtual void Rumble(int delay = 125) { - SetVibration(byte.MaxValue, byte.MaxValue); - await Task.Delay(delay); - SetVibration(0, 0); + Task.Run(async () => + { + SetVibration(byte.MaxValue, byte.MaxValue); + await Task.Delay(delay); + SetVibration(0, 0); + }); } public virtual bool IsPlugged() @@ -262,59 +264,64 @@ public virtual void Cleanup() public bool IsHidden() { - var hide_device = HidHide.IsRegistered(Details.deviceInstanceId); + // var hide_device = HidHide.IsRegistered(Details.deviceInstanceId); var hide_base = HidHide.IsRegistered(Details.baseContainerDeviceInstanceId); return /* hide_device || */ hide_base; } - public void Hide(bool powerCycle = true) + public virtual void Hide(bool powerCycle = true) { HideHID(); - // set flag - powerCycle = powerCycle && this is not SteamController; - if (powerCycle) { // UI thread (async) Application.Current.Dispatcher.BeginInvoke(() => { IsEnabled = false; - ProgressBarUpdate.Visibility = Visibility.Visible; + ProgressBarPanel.Visibility = Visibility.Visible; }); ControllerManager.PowerCyclers[Details.baseContainerDeviceInstanceId] = true; - Details.CyclePort(); + + CyclePort(); return; } RefreshControls(); } - public void Unhide(bool powerCycle = true) + public virtual void Unhide(bool powerCycle = true) { UnhideHID(); - // set flag - powerCycle = powerCycle && this is not SteamController; - if (powerCycle) { // UI thread (async) Application.Current.Dispatcher.BeginInvoke(() => { IsEnabled = false; - ProgressBarUpdate.Visibility = Visibility.Visible; + ProgressBarPanel.Visibility = Visibility.Visible; }); ControllerManager.PowerCyclers[Details.baseContainerDeviceInstanceId] = true; - Details.CyclePort(); + + CyclePort(); return; } RefreshControls(); } + public virtual void CyclePort() + { + Details.CyclePort(); + } + + public virtual void SetLightColor(byte R, byte G, byte B) + { + } + public void HideHID() { HidHide.HidePath(Details.baseContainerDeviceInstanceId); @@ -343,6 +350,11 @@ public void UnhideHID() */ } + public virtual bool RestoreDrivers() + { + return true; + } + protected virtual void Calibrate() { } diff --git a/HandheldCompanion/Controllers/JSController.cs b/HandheldCompanion/Controllers/JSController.cs index a538cdcda..cab491d15 100644 --- a/HandheldCompanion/Controllers/JSController.cs +++ b/HandheldCompanion/Controllers/JSController.cs @@ -1,5 +1,7 @@ using HandheldCompanion.Inputs; using HandheldCompanion.Utils; +using Nefarius.Utilities.DeviceManagement.PnP; +using System.Threading.Tasks; using System.Windows; using static JSL; using Timer = System.Timers.Timer; @@ -177,6 +179,30 @@ protected override void Calibrate() }); } + public override void CyclePort() + { + string enumerator = Details.GetEnumerator(); + switch (enumerator) + { + default: + case "BTHENUM": + Task.Run(async () => + { + // Details.InstallNullDrivers(); + // await Task.Delay(1000); + // Details.InstallCustomDriver("hidbth.inf"); + + Details.Uninstall(false); + await Task.Delay(1000); + Devcon.Refresh(); + }); + break; + case "USB": + base.CyclePort(); + break; + } + } + protected override void ui_button_calibrate_Click(object sender, RoutedEventArgs e) { // start calibration diff --git a/HandheldCompanion/Controllers/SteamController.cs b/HandheldCompanion/Controllers/SteamController.cs index 59283f53a..d429b2882 100644 --- a/HandheldCompanion/Controllers/SteamController.cs +++ b/HandheldCompanion/Controllers/SteamController.cs @@ -28,6 +28,20 @@ public virtual void SetVirtualMuted(bool mute) isVirtualMuted = mute; } + public override void Hide(bool powerCycle = true) + { + HideHID(); + + RefreshControls(); + } + + public override void Unhide(bool powerCycle = true) + { + UnhideHID(); + + RefreshControls(); + } + public override string GetGlyph(ButtonFlags button) { switch (button) diff --git a/HandheldCompanion/Controllers/XInputController.cs b/HandheldCompanion/Controllers/XInputController.cs index a35718e67..9dcec7290 100644 --- a/HandheldCompanion/Controllers/XInputController.cs +++ b/HandheldCompanion/Controllers/XInputController.cs @@ -1,9 +1,12 @@ using HandheldCompanion.Inputs; using HandheldCompanion.Managers; +using Nefarius.Utilities.DeviceManagement.PnP; using SharpDX.XInput; using System; using System.Linq; using System.Runtime.InteropServices; +using System.Threading.Tasks; +using System.Windows; using System.Windows.Media; namespace HandheldCompanion.Controllers; @@ -13,9 +16,6 @@ public class XInputController : IController private Controller Controller; private Gamepad Gamepad; - private GamepadButtonFlags prevButtons; - private XInputStateSecret prevState; - private XInputStateSecret State; public XInputController() @@ -75,11 +75,6 @@ public override void UpdateInputs(long ticks) // update secret state XInputGetStateSecret14(UserIndex, out State); - /* - if (prevButtons.Equals(Gamepad.Buttons) && State.wButtons.Equals(prevState.wButtons) && prevInjectedButtons.Equals(InjectedButtons)) - return; - */ - Inputs.ButtonState = InjectedButtons.Clone() as ButtonState; Inputs.ButtonState[ButtonFlags.B1] = Gamepad.Buttons.HasFlag(GamepadButtonFlags.A); @@ -129,10 +124,6 @@ public override void UpdateInputs(long ticks) Inputs.AxisState[AxisFlags.L2] = Gamepad.LeftTrigger; Inputs.AxisState[AxisFlags.R2] = Gamepad.RightTrigger; - - // update states - prevButtons = Gamepad.Buttons; - prevState = State; } catch { } @@ -195,6 +186,67 @@ public static UserIndex TryGetUserIndex(PnPDetails details) return SharpDX.XInput.UserIndex.Any; } + public override void Hide(bool powerCycle = true) + { + if (powerCycle) + { + // UI thread (async) + Application.Current.Dispatcher.BeginInvoke(() => + { + ProgressBarWarning.Text = Properties.Resources.ControllerPage_XInputControllerWarning; + }); + } + + base.Hide(powerCycle); + } + + public override void Unhide(bool powerCycle = true) + { + if (powerCycle) + { + // UI thread (async) + Application.Current.Dispatcher.BeginInvoke(() => + { + ProgressBarWarning.Text = Properties.Resources.ControllerPage_XInputControllerWarning; + }); + } + + base.Unhide(powerCycle); + } + + public override void CyclePort() + { + string enumerator = Details.GetEnumerator(); + switch (enumerator) + { + default: + case "BTHENUM": + Task.Run(async () => + { + /* + // Bluetooth HID Device + Details.InstallNullDrivers(false); + Details.InstallCustomDriver("hidbth.inf", false); + + // Bluetooth XINPUT compatible input device + Details.InstallNullDrivers(true); + Details.InstallCustomDriver("xinputhid.inf", true); + */ + + /* + Details.Uninstall(false); // Bluetooth HID Device + Details.Uninstall(true); // Bluetooth XINPUT compatible input device + await Task.Delay(1000); + Devcon.Refresh(); + */ + }); + break; + case "USB": + base.CyclePort(); + break; + } + } + public override string GetGlyph(ButtonFlags button) { switch (button) diff --git a/HandheldCompanion/Devices/ASUS/AsusACPI.cs b/HandheldCompanion/Devices/ASUS/AsusACPI.cs new file mode 100644 index 000000000..caf644f03 --- /dev/null +++ b/HandheldCompanion/Devices/ASUS/AsusACPI.cs @@ -0,0 +1,511 @@ +using System.Management; +using System.Runtime.InteropServices; +using System; +using System.Threading; +using HandheldCompanion.Managers; + +public enum AsusFan +{ + CPU = 0, + GPU = 1, + Mid = 2, + XGM = 3 +} + +public enum AsusMode +{ + Balanced = 0, + Turbo = 1, + Silent = 2 +} + +public enum AsusGPU +{ + Eco = 0, + Standard = 1, + Ultimate = 2 +} + +namespace HandheldCompanion.Devices.ASUS +{ + public class AsusACPI + { + const string FILE_NAME = @"\\.\\ATKACPI"; + const uint CONTROL_CODE = 0x0022240C; + + const uint DSTS = 0x53545344; + const uint DEVS = 0x53564544; + const uint INIT = 0x54494E49; + + public const uint UniversalControl = 0x00100021; + + public const int KB_Light_Up = 0xc4; + public const int KB_Light_Down = 0xc5; + public const int Brightness_Down = 0x10; + public const int Brightness_Up = 0x20; + public const int KB_Sleep = 0x6c; + public const int KB_DUO_PgUpDn = 0x4B; + public const int KB_DUO_SecondDisplay = 0x6A; + + + public const int Touchpad_Toggle = 0x6B; + + public const int ChargerMode = 0x0012006C; + + public const int ChargerUSB = 2; + public const int ChargerBarrel = 1; + + public const uint CPU_Fan = 0x00110013; + public const uint GPU_Fan = 0x00110014; + public const uint Mid_Fan = 0x00110031; + + public const uint PerformanceMode = 0x00120075; // Performance modes + public const uint VivoBookMode = 0x00110019; // Vivobook performance modes + + public const uint GPUEco = 0x00090020; + public const uint GPUXGConnected = 0x00090018; + public const uint GPUXG = 0x00090019; + public const uint GPUMux = 0x00090016; + + public const uint BatteryLimit = 0x00120057; + public const uint ScreenOverdrive = 0x00050019; + public const uint ScreenMiniled = 0x0005001E; + + public const uint DevsCPUFan = 0x00110022; + public const uint DevsGPUFan = 0x00110023; + + public const uint DevsCPUFanCurve = 0x00110024; + public const uint DevsGPUFanCurve = 0x00110025; + public const uint DevsMidFanCurve = 0x00110032; + + public const int Temp_CPU = 0x00120094; + public const int Temp_GPU = 0x00120097; + + public const int PPT_TotalA0 = 0x001200A0; // SPL (Total limit for all-AMD models) / PL1 + public const int PPT_EDCA1 = 0x001200A1; // CPU EDC + public const int PPT_TDCA2 = 0x001200A2; // CPU TDC + public const int PPT_APUA3 = 0x001200A3; // sPPT (long boost limit) / PL2 + + public const int PPT_CPUB0 = 0x001200B0; // CPU PPT on 2022 (PPT_LIMIT_APU) + public const int PPT_CPUB1 = 0x001200B1; // Total PPT on 2022 (PPT_LIMIT_SLOW) + + public const int PPT_GPUC0 = 0x001200C0; // NVIDIA GPU Boost + public const int PPT_APUC1 = 0x001200C1; // fPPT (fast boost limit) + public const int PPT_GPUC2 = 0x001200C2; // NVIDIA GPU Temp Target (75.. 87 C) + + public const int TUF_KB_BRIGHTNESS = 0x00050021; + public const int TUF_KB = 0x00100056; + public const int TUF_KB_STATE = 0x00100057; + + public const int MICMUTE_LED = 0x00040017; + + public const int TabletState = 0x00060077; + public const int FnLock = 0x00100023; + + public const int ScreenPadToggle = 0x00050031; + public const int ScreenPadBrightness = 0x00050032; + + public const int Tablet_Notebook = 0; + public const int Tablet_Tablet = 1; + public const int Tablet_Tent = 2; + public const int Tablet_Rotated = 3; + + public const int PerformanceBalanced = 0; + public const int PerformanceTurbo = 1; + public const int PerformanceSilent = 2; + public const int PerformanceManual = 4; + + public const int GPUModeEco = 0; + public const int GPUModeStandard = 1; + public const int GPUModeUltimate = 2; + + public const int MinTotal = 5; + + public static int MaxTotal = 150; + public static int DefaultTotal = 125; + + public const int MinCPU = 5; + public const int MaxCPU = 100; + public const int DefaultCPU = 80; + + public const int MinGPUBoost = 5; + public const int MaxGPUBoost = 25; + + public const int MinGPUTemp = 75; + public const int MaxGPUTemp = 87; + + + [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)] + private static extern IntPtr CreateFile( + string lpFileName, + uint dwDesiredAccess, + uint dwShareMode, + IntPtr lpSecurityAttributes, + uint dwCreationDisposition, + uint dwFlagsAndAttributes, + IntPtr hTemplateFile + ); + + [DllImport("kernel32.dll", SetLastError = true)] + private static extern bool DeviceIoControl( + IntPtr hDevice, + uint dwIoControlCode, + byte[] lpInBuffer, + uint nInBufferSize, + byte[] lpOutBuffer, + uint nOutBufferSize, + ref uint lpBytesReturned, + IntPtr lpOverlapped + ); + + [DllImport("kernel32.dll", SetLastError = true)] + private static extern bool CloseHandle(IntPtr hObject); + + private const uint GENERIC_READ = 0x80000000; + private const uint GENERIC_WRITE = 0x40000000; + private const uint OPEN_EXISTING = 3; + private const uint FILE_ATTRIBUTE_NORMAL = 0x80; + private const uint FILE_SHARE_READ = 1; + private const uint FILE_SHARE_WRITE = 2; + + private const int ASUS_WMI_KEYBOARD_POWER_BOOT = 0x03 << 16; + private const int ASUS_WMI_KEYBOARD_POWER_AWAKE = 0x0C << 16; + private const int ASUS_WMI_KEYBOARD_POWER_SLEEP = 0x30 << 16; + private const int ASUS_WMI_KEYBOARD_POWER_SHUTDOWN = 0xC0 << 16; + + private IntPtr handle; + + // Event handling attempt + + [DllImport("kernel32.dll", SetLastError = true)] + private static extern IntPtr CreateEvent(IntPtr lpEventAttributes, bool bManualReset, bool bInitialState, string lpName); + + [DllImport("kernel32.dll", SetLastError = true)] + private static extern bool WaitForSingleObject(IntPtr hHandle, int dwMilliseconds); + + private IntPtr eventHandle; + + // still works only with asus optimization service on , if someone knows how to get ACPI events from asus without that - let me know + public void RunListener() + { + + eventHandle = CreateEvent(IntPtr.Zero, false, false, "ATK4001"); + + byte[] outBuffer = new byte[16]; + byte[] data = new byte[8]; + bool result; + + data[0] = BitConverter.GetBytes(eventHandle.ToInt32())[0]; + data[1] = BitConverter.GetBytes(eventHandle.ToInt32())[1]; + + Control(0x222400, data, outBuffer); + + while (true) + { + WaitForSingleObject(eventHandle, Timeout.Infinite); + Control(0x222408, new byte[0], outBuffer); + int code = BitConverter.ToInt32(outBuffer, 0); + } + } + + + public AsusACPI() + { + handle = CreateFile( + FILE_NAME, + GENERIC_READ | GENERIC_WRITE, + FILE_SHARE_READ | FILE_SHARE_WRITE, + IntPtr.Zero, + OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, + IntPtr.Zero + ); + + if (!IsOpen()) + { + LogManager.LogError("Can't connect to Asus ACPI"); + return; + } + + MaxTotal = 50; + DefaultTotal = 30; + } + + public bool IsOpen() + { + return handle != new IntPtr(-1); + } + + public void Control(uint dwIoControlCode, byte[] lpInBuffer, byte[] lpOutBuffer) + { + + uint lpBytesReturned = 0; + DeviceIoControl( + handle, + dwIoControlCode, + lpInBuffer, + (uint)lpInBuffer.Length, + lpOutBuffer, + (uint)lpOutBuffer.Length, + ref lpBytesReturned, + IntPtr.Zero + ); + } + + public void Close() + { + CloseHandle(handle); + } + + protected byte[] CallMethod(uint MethodID, byte[] args) + { + byte[] acpiBuf = new byte[8 + args.Length]; + byte[] outBuffer = new byte[16]; + + BitConverter.GetBytes((uint)MethodID).CopyTo(acpiBuf, 0); + BitConverter.GetBytes((uint)args.Length).CopyTo(acpiBuf, 4); + Array.Copy(args, 0, acpiBuf, 8, args.Length); + + // if (MethodID == DEVS) Debug.WriteLine(BitConverter.ToString(acpiBuf, 0, acpiBuf.Length)); + + Control(CONTROL_CODE, acpiBuf, outBuffer); + + return outBuffer; + + } + + public byte[] DeviceInit() + { + byte[] args = new byte[8]; + return CallMethod(INIT, args); + } + + public int DeviceSet(uint DeviceID, int Status) + { + byte[] args = new byte[8]; + BitConverter.GetBytes((uint)DeviceID).CopyTo(args, 0); + BitConverter.GetBytes((uint)Status).CopyTo(args, 4); + + byte[] status = CallMethod(DEVS, args); + int result = BitConverter.ToInt32(status, 0); + + return result; + } + + public int DeviceSet(uint DeviceID, byte[] Params, string logName) + { + byte[] args = new byte[4 + Params.Length]; + BitConverter.GetBytes((uint)DeviceID).CopyTo(args, 0); + Params.CopyTo(args, 4); + + byte[] status = CallMethod(DEVS, args); + int result = BitConverter.ToInt32(status, 0); + + return BitConverter.ToInt32(status, 0); + } + + public int DeviceGet(uint DeviceID) + { + byte[] args = new byte[8]; + BitConverter.GetBytes((uint)DeviceID).CopyTo(args, 0); + byte[] status = CallMethod(DSTS, args); + + return BitConverter.ToInt32(status, 0) - 65536; + + } + + public byte[] DeviceGetBuffer(uint DeviceID, uint Status = 0) + { + byte[] args = new byte[8]; + BitConverter.GetBytes((uint)DeviceID).CopyTo(args, 0); + BitConverter.GetBytes((uint)Status).CopyTo(args, 4); + + return CallMethod(DSTS, args); + } + + public int SetGPUEco(int eco) + { + int ecoFlag = DeviceGet(GPUEco); + if (ecoFlag < 0) return -1; + + if (ecoFlag == 1 && eco == 0) + return DeviceSet(GPUEco, eco); + + if (ecoFlag == 0 && eco == 1) + return DeviceSet(GPUEco, eco); + + return -1; + } + + public int SetFanRange(AsusFan device, byte[] curve) + { + byte min = (byte)(curve[8] * 255 / 100); + byte max = (byte)(curve[15] * 255 / 100); + byte[] range = { min, max }; + + int result; + switch (device) + { + case AsusFan.GPU: + result = DeviceSet(DevsGPUFan, range, "FanRangeGPU"); + break; + default: + result = DeviceSet(DevsCPUFan, range, "FanRangeCPU"); + break; + } + return result; + } + + public int SetFanSpeed(AsusFan device, byte speed) + { + byte[] curve = new byte[] { 0x1E, 0x28, 0x32, 0x3C, 0x46, 0x50, 0x5A, 0x5A, speed, speed, speed, speed, speed, speed, speed, speed }; + int result; + switch (device) + { + case AsusFan.GPU: + result = DeviceSet(DevsGPUFanCurve, curve, "FanGPU"); + break; + case AsusFan.Mid: + result = DeviceSet(DevsMidFanCurve, curve, "FanMid"); + break; + default: + result = DeviceSet(DevsCPUFanCurve, curve, "FanCPU"); + break; + } + return result; + } + + public int SetFanCurve(AsusFan device, byte[] curve) + { + + if (curve.Length != 16) return -1; + // if (curve.All(singleByte => singleByte == 0)) return -1; + + int result; + int fanScale = 100; //AppConfig.Get("fan_scale", 100); + + // if (fanScale != 100 && device == AsusFan.CPU) Logger.WriteLine("Custom fan scale: " + fanScale); + + // it seems to be a bug, when some old model's bios can go nuts if fan is set to 100% + + for (int i = 8; i < curve.Length; i++) curve[i] = (byte)(Math.Max((byte)0, Math.Min((byte)99, curve[i])) * fanScale / 100); + + switch (device) + { + case AsusFan.GPU: + result = DeviceSet(DevsGPUFanCurve, curve, "FanGPU"); + break; + case AsusFan.Mid: + result = DeviceSet(DevsMidFanCurve, curve, "FanMid"); + break; + default: + result = DeviceSet(DevsCPUFanCurve, curve, "FanCPU"); + break; + } + + return result; + } + + public byte[] GetFanCurve(AsusFan device, int mode = 0) + { + uint fan_mode; + + // because it's asus, and modes are swapped here + switch (mode) + { + case 1: fan_mode = 2; break; + case 2: fan_mode = 1; break; + default: fan_mode = 0; break; + } + + switch (device) + { + case AsusFan.GPU: + return DeviceGetBuffer(DevsGPUFanCurve, fan_mode); + case AsusFan.Mid: + return DeviceGetBuffer(DevsMidFanCurve, fan_mode); + default: + return DeviceGetBuffer(DevsCPUFanCurve, fan_mode); + } + + } + + public static bool IsInvalidCurve(byte[] curve) + { + return curve.Length != 16 || IsEmptyCurve(curve); + } + + public static bool IsEmptyCurve(byte[] curve) + { + return false; + } + + public static byte[] FixFanCurve(byte[] curve) + { + return curve; + + } + + public bool IsXGConnected() + { + //return true; + return DeviceGet(GPUXGConnected) == 1; + } + + public bool IsAllAmdPPT() + { + return DeviceGet(PPT_CPUB0) >= 0 && DeviceGet(PPT_GPUC0) < 0; + } + + public void TUFKeyboardBrightness(int brightness) + { + int param = 0x80 | (brightness & 0x7F); + DeviceSet(TUF_KB_BRIGHTNESS, param); + } + + public void TUFKeyboardRGB(int mode, System.Drawing.Color color, int speed) + { + + byte[] setting = new byte[12]; + setting[0] = (byte)0xB4; + setting[1] = (byte)mode; + setting[2] = color.R; + setting[3] = color.G; + setting[4] = color.B; + setting[5] = (byte)speed; + + DeviceSet(TUF_KB, setting, "TUF RGB"); + //Debug.WriteLine(BitConverter.ToString(setting)); + } + + public void TUFKeyboardPower(bool awake = true, bool boot = false, bool sleep = false, bool shutdown = false) + { + int state = 0xbd; + + if (boot) state = state | ASUS_WMI_KEYBOARD_POWER_BOOT; + if (awake) state = state | ASUS_WMI_KEYBOARD_POWER_AWAKE; + if (sleep) state = state | ASUS_WMI_KEYBOARD_POWER_SLEEP; + if (shutdown) state = state | ASUS_WMI_KEYBOARD_POWER_SHUTDOWN; + + state = state | 0x01 << 8; + + DeviceSet(TUF_KB_STATE, state); + } + + public void SubscribeToEvents(Action EventHandler) + { + try + { + ManagementEventWatcher watcher = new ManagementEventWatcher(); + watcher.EventArrived += new EventArrivedEventHandler(EventHandler); + watcher.Scope = new ManagementScope("root\\wmi"); + watcher.Query = new WqlEventQuery("SELECT * FROM AsusAtkWmiEvent"); + watcher.Start(); + } + catch + { + + } + } + } +} diff --git a/HandheldCompanion/Devices/ASUS/ROGAlly.cs b/HandheldCompanion/Devices/ASUS/ROGAlly.cs index 625d6372b..1aace0523 100644 --- a/HandheldCompanion/Devices/ASUS/ROGAlly.cs +++ b/HandheldCompanion/Devices/ASUS/ROGAlly.cs @@ -1,15 +1,18 @@ -using HandheldCompanion.Inputs; +using HandheldCompanion.Devices.ASUS; +using HandheldCompanion.Inputs; using HandheldCompanion.Managers; using HandheldCompanion.Utils; -using HidSharp; -using HidSharp.Reports.Input; +using HidLibrary; using Nefarius.Utilities.DeviceManagement.PnP; using System; using System.Collections.Generic; +using System.Drawing; using System.Linq; +using System.Management; using System.Numerics; -using System.Threading.Tasks; +using System.Text; using WindowsInput.Events; +using Task = System.Threading.Tasks.Task; namespace HandheldCompanion.Devices; @@ -27,8 +30,24 @@ public class ROGAlly : IDevice { 236, ButtonFlags.None } }; - private IEnumerable _hidDevices; - private List _hidStreams = new(); + private HidDevice hidDevice; + private AsusACPI asusACPI; + + private enum AuraMode + { + Static = 0, + Breathe = 1, + Cycle = 2, + Rainbow = 3, + Strobe = 4, + } + + private enum AuraSpeed + { + Slow = 0xeb, + Medium = 0xf5, + Fast = 0xe1, + } public ROGAlly() { @@ -62,6 +81,9 @@ public ROGAlly() { 'Z', 'Y' } }; + // device specific capacities + Capabilities = DeviceCapabilities.FanControl; + OEMChords.Add(new DeviceChord("CC", new List(), new List(), false, ButtonFlags.OEM1 @@ -84,71 +106,47 @@ public override bool Open() if (!success) return false; - // set exclusive connection with highest priority - var deviceConfiguration = new OpenConfiguration(); - deviceConfiguration.SetOption(OpenOption.Exclusive, true); - deviceConfiguration.SetOption(OpenOption.Transient, true); - deviceConfiguration.SetOption(OpenOption.Priority, OpenPriority.VeryHigh); + if (hidDevice is not null) + hidDevice.OpenDevice(); - foreach (var _hidDevice in _hidDevices) - { - try - { - // connect to hid device - var _stream = _hidDevice.Open(); - - // add stream to array - _hidStreams.Add(_stream); - - // get descriptor - var deviceDescriptor = _hidDevice.GetReportDescriptor(); - - foreach (var inputReport in deviceDescriptor.InputReports) - { - DeviceItemInputParser hiddeviceInputParser = inputReport.DeviceItem.CreateDeviceItemInputParser(); - HidDeviceInputReceiver hidDeviceInputReceiver = deviceDescriptor.CreateHidDeviceInputReceiver(); - - // listen for event(s) - hidDeviceInputReceiver.Received += (sender, e) => - InputReportReceiver_Received(_hidDevice, hiddeviceInputParser, hidDeviceInputReceiver); + // try open asus ACPI + asusACPI = new AsusACPI(); + if (asusACPI is null) + return false; - // start receiver - hidDeviceInputReceiver.Start(_stream); + asusACPI.SubscribeToEvents(WatcherEventArrived); - LogManager.LogInformation("HID connected: {0}", _stream.Device.DevicePath); - } - } - catch - { - LogManager.LogError("HID error: {0}", _hidDevice.DevicePath); - } - } return true; } public override void Close() { - // close stream(s) - foreach (HidStream stream in _hidStreams) - stream.Close(); + // close Asus ACPI + if (asusACPI is not null) + asusACPI.Close(); // clear array - _hidStreams.Clear(); + if (hidDevice is not null) + hidDevice.CloseDevice(); base.Close(); } - public override bool IsReady() - { - // get hid devices - _hidDevices = DeviceList.Local.GetHidDevices() - .Where(d => d.ProductID == _pid && d.VendorID == _vid); - var _hidDevice = _hidDevices.FirstOrDefault(); + public void WatcherEventArrived(object sender, EventArrivedEventArgs e) + { + if (e.NewEvent is null) return; + int EventID = int.Parse(e.NewEvent["EventID"].ToString()); + LogManager.LogDebug("WMI event {0}", EventID); + HandleEvent((byte)EventID); + } - if (_hidDevice is null) + public override bool IsReady() + { + hidDevice = GetHidDevices(_vid, _pid).FirstOrDefault(); + if (hidDevice is null) return false; - var pnpDevice = PnPDevice.GetDeviceByInterfaceId(_hidDevice.DevicePath); + var pnpDevice = PnPDevice.GetDeviceByInterfaceId(hidDevice.DevicePath); var device_parent = pnpDevice.GetProperty(DevicePropertyKey.Device_Parent); var pnpParent = PnPDevice.GetDeviceByInstanceId(device_parent); @@ -158,6 +156,35 @@ public override bool IsReady() return DeviceHelper.IsDeviceAvailable(parent_guid, parent_instanceId); } + public override void SetFanControl(bool enable) + { + if (!asusACPI.IsOpen()) + return; + + switch (enable) + { + case false: + asusACPI.DeviceSet(AsusACPI.PerformanceMode, (int)AsusMode.Turbo); + return; + } + } + + public override void SetFanDuty(double percent) + { + if (!asusACPI.IsOpen()) + return; + + asusACPI.SetFanSpeed(AsusFan.CPU, Convert.ToByte(percent)); + asusACPI.SetFanSpeed(AsusFan.GPU, Convert.ToByte(percent)); + } + + public override float ReadFanDuty() + { + int cpuFan = asusACPI.DeviceGet(AsusACPI.CPU_Fan); + int gpuFan = asusACPI.DeviceGet(AsusACPI.GPU_Fan); + return (cpuFan + gpuFan) / 2 * 100; + } + public override void SetKeyPressDelay(HIDmode controllerMode) { switch (controllerMode) @@ -171,80 +198,63 @@ public override void SetKeyPressDelay(HIDmode controllerMode) } } - private void InputReportReceiver_Received(HidDevice hidDevice, DeviceItemInputParser hiddeviceInputParser, - HidDeviceInputReceiver hidDeviceInputReceiver) + private void HandleEvent(byte key) { - var inputReportBuffer = new byte[hidDevice.GetMaxInputReportLength()]; + if (!keyMapping.ContainsKey(key)) + return; + + // get button + var button = keyMapping[key]; - while (hidDeviceInputReceiver.TryRead(inputReportBuffer, 0, out var report)) + // HID Report Item = hex = decimal + // Left or right paddle = A5 = 165 + // Left OEM key = A6 = 166 + // Right OEM key = 38 = 56 + // Right OEM key hold = A7 and A8 = 167 and 168 + + switch (key) { - switch (report.ReportID) - { - case 90: - break; - default: - return; - } - - if (!hiddeviceInputParser.TryParseReport(inputReportBuffer, 0, report)) continue; - var key = inputReportBuffer[1]; - - if (!keyMapping.ContainsKey(key)) + case 236: return; - // get button - var button = keyMapping[key]; + case 0: + { + KeyRelease(ButtonFlags.OEM3); + } + return; - // HID Report Item = hex = decimal - // Left or right paddle = A5 = 165 - // Left OEM key = A6 = 166 - // Right OEM key = 38 = 56 - // Right OEM key hold = A7 and A8 = 167 and 168 + case 56: + case 166: + { + // OEM1 and OEM2 key needs a key press delay based on emulated controller + Task.Run(async () => + { + KeyPress(button); + await Task.Delay(KeyPressDelay); + KeyRelease(button); + }); + } + break; - switch (key) - { - case 236: - return; + case 165: + case 167: + KeyPress(button); + break; - case 0: - { - KeyRelease(ButtonFlags.OEM3); - } - return; + case 168: + KeyRelease(button); + break; - case 56: - case 166: - { - // OEM1 and OEM2 key needs a key press delay based on emulated controller - Task.Factory.StartNew(async () => - { - KeyPress(button); - await Task.Delay(KeyPressDelay); - KeyRelease(button); - }); - } - break; - - case 165: - case 167: - KeyPress(button); - break; - - case 168: - KeyRelease(button); - break; - - default: + default: + { + Task.Run(async () => { - Task.Factory.StartNew(async () => - { - KeyPress(button); - await Task.Delay(20); - KeyRelease(button); - }); - } - break; - } + KeyPress(button); + await Task.Delay(20); + KeyRelease(button); + }); + } + break; } } } \ No newline at end of file diff --git a/HandheldCompanion/Devices/GPD/GPDWin4-2023-7640U.cs b/HandheldCompanion/Devices/GPD/GPDWin4-2023-7640U.cs new file mode 100644 index 000000000..9f0d0b341 --- /dev/null +++ b/HandheldCompanion/Devices/GPD/GPDWin4-2023-7640U.cs @@ -0,0 +1,74 @@ +using HandheldCompanion.Inputs; +using System.Collections.Generic; +using System.Numerics; +using WindowsInput.Events; + +namespace HandheldCompanion.Devices; + +public class GPDWin4_2023_7640U : IDevice +{ + public GPDWin4_2023_7640U() + { + // device specific settings + ProductIllustration = "device_gpd4"; + + // https://www.amd.com/en/products/apu/amd-ryzen-5-7640u + nTDP = new double[] { 15, 15, 28 }; + cTDP = new double[] { 5, 28 }; + GfxClock = new double[] { 200, 2600 }; + + AngularVelocityAxis = new Vector3(1.0f, 1.0f, -1.0f); + AngularVelocityAxisSwap = new SortedDictionary + { + { 'X', 'Y' }, + { 'Y', 'Z' }, + { 'Z', 'X' } + }; + + AccelerationAxis = new Vector3(1.0f, 1.0f, 1.0f); + AccelerationAxisSwap = new SortedDictionary + { + { 'X', 'X' }, + { 'Y', 'Z' }, + { 'Z', 'Y' } + }; + + // device specific capacities + Capabilities = DeviceCapabilities.FanControl; + + ECDetails = new ECDetails + { + AddressControl = 0x275, + AddressDuty = 0x1809, + AddressRegistry = 0x4E, + AddressData = 0x4F, + ValueMin = 0, + ValueMax = 184 + }; + + // Note, OEM1 not configured as this device has it's own Menu button for guide button + + // Note, chords need to be manually configured in GPD app first by end user + + // GPD Back buttons do not have a "hold", configured buttons are key down and up immediately + // Holding back buttons will result in same key down and up input every 2-3 seconds + // Configured chords in GPD app need unique characters otherwise this leads to a + // "mixed" result when pressing both buttons at the same time + OEMChords.Add(new DeviceChord("Bottom button left", + new List { KeyCode.F11, KeyCode.L }, + new List { KeyCode.F11, KeyCode.L }, + false, ButtonFlags.OEM2 + )); + + OEMChords.Add(new DeviceChord("Bottom button right", + new List { KeyCode.F12, KeyCode.R }, + new List { KeyCode.F12, KeyCode.R }, + false, ButtonFlags.OEM3 + )); + } + + public override void Close() + { + base.Close(); + } +} diff --git a/HandheldCompanion/Devices/GPD/GPDWin4-2023-7840U.cs b/HandheldCompanion/Devices/GPD/GPDWin4-2023-7840U.cs new file mode 100644 index 000000000..ed97f046d --- /dev/null +++ b/HandheldCompanion/Devices/GPD/GPDWin4-2023-7840U.cs @@ -0,0 +1,74 @@ +using HandheldCompanion.Inputs; +using System.Collections.Generic; +using System.Numerics; +using WindowsInput.Events; + +namespace HandheldCompanion.Devices; + +public class GPDWin4_2023_7840U : IDevice +{ + public GPDWin4_2023_7840U() + { + // device specific settings + ProductIllustration = "device_gpd4"; + + // https://www.amd.com/en/products/apu/amd-ryzen-7-7840u + nTDP = new double[] { 15, 15, 28 }; + cTDP = new double[] { 5, 28 }; + GfxClock = new double[] { 200, 2700 }; + + AngularVelocityAxis = new Vector3(1.0f, 1.0f, -1.0f); + AngularVelocityAxisSwap = new SortedDictionary + { + { 'X', 'Y' }, + { 'Y', 'Z' }, + { 'Z', 'X' } + }; + + AccelerationAxis = new Vector3(1.0f, 1.0f, 1.0f); + AccelerationAxisSwap = new SortedDictionary + { + { 'X', 'X' }, + { 'Y', 'Z' }, + { 'Z', 'Y' } + }; + + // device specific capacities + Capabilities = DeviceCapabilities.FanControl; + + ECDetails = new ECDetails + { + AddressControl = 0x275, + AddressDuty = 0x1809, + AddressRegistry = 0x4E, + AddressData = 0x4F, + ValueMin = 0, + ValueMax = 184 + }; + + // Note, OEM1 not configured as this device has it's own Menu button for guide button + + // Note, chords need to be manually configured in GPD app first by end user + + // GPD Back buttons do not have a "hold", configured buttons are key down and up immediately + // Holding back buttons will result in same key down and up input every 2-3 seconds + // Configured chords in GPD app need unique characters otherwise this leads to a + // "mixed" result when pressing both buttons at the same time + OEMChords.Add(new DeviceChord("Bottom button left", + new List { KeyCode.F11, KeyCode.L }, + new List { KeyCode.F11, KeyCode.L }, + false, ButtonFlags.OEM2 + )); + + OEMChords.Add(new DeviceChord("Bottom button right", + new List { KeyCode.F12, KeyCode.R }, + new List { KeyCode.F12, KeyCode.R }, + false, ButtonFlags.OEM3 + )); + } + + public override void Close() + { + base.Close(); + } +} diff --git a/HandheldCompanion/Devices/IDevice.cs b/HandheldCompanion/Devices/IDevice.cs index 5218d1a33..98b2614a4 100644 --- a/HandheldCompanion/Devices/IDevice.cs +++ b/HandheldCompanion/Devices/IDevice.cs @@ -2,6 +2,7 @@ using HandheldCompanion.Managers; using HandheldCompanion.Sensors; using HandheldCompanion.Utils; +using HidLibrary; using System; using System.Collections.Generic; using System.Linq; @@ -18,7 +19,7 @@ public enum DeviceCapabilities : ushort None = 0, InternalSensor = 1, ExternalSensor = 2, - FanControl = 4, + FanControl = 4 } public struct ECDetails @@ -224,7 +225,18 @@ public static IDevice GetDefault() device = new GPDWin3(); break; case "G1618-04": - device = new GPDWin4(); + switch (Processor) + { + case "AMD Ryzen 7 6800U with Radeon Graphics": + device = new GPDWin4(); + break; + case "AMD Ryzen 5 7640U w/ Radeon 760M Graphics": + device = new GPDWin4_2023_7640U(); + break; + case "AMD Ryzen 7 7840U w/ Radeon 780M Graphics": + device = new GPDWin4_2023_7840U(); + break; + } break; case "G1619-03": device = new GPDWinMax2Intel(); @@ -465,6 +477,15 @@ public virtual void SetFanControl(bool enable) ECRamDirectWrite(ECDetails.AddressControl, ECDetails, data); } + public virtual float ReadFanDuty() + { + if (ECDetails.AddressControl == 0) + return 0; + + // todo: implement me + return 0; + } + [Obsolete("ECRamReadByte is deprecated, please use ECRamReadByte with ECDetails instead.")] public static byte ECRamReadByte(ushort address) { @@ -549,4 +570,12 @@ protected void KeyRelease(ButtonFlags button) { KeyReleased?.Invoke(button); } + + protected static IEnumerable GetHidDevices(int vendorId, int deviceId, int minFeatures = 1) + { + HidDevice[] HidDeviceList = HidDevices.Enumerate(vendorId, new int[] { deviceId }).ToArray(); + foreach (HidDevice device in HidDeviceList) + if (device.IsConnected && device.Capabilities.FeatureReportByteLength >= minFeatures) + yield return device; + } } \ No newline at end of file diff --git a/HandheldCompanion/HandheldCompanion.csproj b/HandheldCompanion/HandheldCompanion.csproj index 84c4cb063..fa4073b5a 100644 --- a/HandheldCompanion/HandheldCompanion.csproj +++ b/HandheldCompanion/HandheldCompanion.csproj @@ -12,7 +12,7 @@ HandheldCompanion.App $(SolutionDir)bin\$(Configuration) Resources\icon.ico - 0.18.0.3 + 0.18.0.4 app.manifest AnyCPU;x64;x86 true @@ -139,7 +139,7 @@ - + @@ -148,7 +148,7 @@ - + diff --git a/HandheldCompanion/JoyShockLibrary.dll b/HandheldCompanion/JoyShockLibrary.dll index d27dd14a4b31e1740bc568e9786a301be30621c6..07c7a044301183870105689dc33c15c76e1c5f2f 100644 GIT binary patch delta 96230 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 pT@v-X{bGeog%QdE&MKi(Jx> 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 delta 94481 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 diff --git a/HandheldCompanion/Managers/ControllerManager.cs b/HandheldCompanion/Managers/ControllerManager.cs index 3123992f7..1c9455452 100644 --- a/HandheldCompanion/Managers/ControllerManager.cs +++ b/HandheldCompanion/Managers/ControllerManager.cs @@ -5,6 +5,8 @@ using HandheldCompanion.Utils; using HandheldCompanion.Views; using HandheldCompanion.Views.Classes; +using Inkore.UI.WPF.Modern; +using Microsoft.Win32; using Nefarius.Utilities.DeviceManagement.PnP; using SharpDX.DirectInput; using SharpDX.XInput; @@ -13,6 +15,7 @@ using System.Linq; using System.Windows; using System.Windows.Controls; +using Windows.UI.ViewManagement; using static HandheldCompanion.Utils.DeviceUtils; using static JSL; using DeviceType = SharpDX.DirectInput.DeviceType; @@ -32,6 +35,8 @@ public static class ControllerManager private static ProcessEx? foregroundProcess; private static bool ControllerMuted; + private static UISettings uiSettings; + public static bool IsInitialized; private static bool virtualControllerCreated; @@ -65,6 +70,9 @@ public static void Start() // enable HidHide HidHide.SetCloaking(true); + uiSettings = new UISettings(); + uiSettings.ColorValuesChanged += OnColorValuesChanged; + IsInitialized = true; Initialized?.Invoke(); @@ -75,6 +83,14 @@ public static void Start() LogManager.LogInformation("{0} has started", "ControllerManager"); } + private static void OnColorValuesChanged(UISettings sender, object args) + { + var _systemBackground = uiSettings.GetColorValue(UIColorType.Background); + var _systemAccent = uiSettings.GetColorValue(UIColorType.Accent); + + targetController?.SetLightColor(_systemAccent.R, _systemAccent.G, _systemAccent.B); + } + [Flags] private enum FocusedWindow { @@ -169,6 +185,9 @@ public static void Stop() IsInitialized = false; + // unplug on close + ClearTargetController(); + DeviceManager.XUsbDeviceArrived -= XUsbDeviceArrived; DeviceManager.XUsbDeviceRemoved -= XUsbDeviceRemoved; @@ -182,9 +201,8 @@ public static void Stop() foreach (var controller in GetPhysicalControllers()) controller.Unhide(false); - // unplug on close - var target = GetTargetController(); - target?.Unplug(); + // Flushing possible JoyShocks... + JslDisconnectAndDisposeAll(); LogManager.LogInformation("{0} has stopped", "ControllerManager"); } @@ -458,9 +476,12 @@ private static void HidDeviceRemoved(PnPDetails details, DeviceEventArgs obj) return; // XInput controller are handled elsewhere - if (controller.GetType() == typeof(XInputController)) + if (controller is XInputController) return; + if (controller is JSController) + JslDisconnect(controller.GetUserIndex()); + // are we power cycling ? PowerCyclers.TryGetValue(details.baseContainerDeviceInstanceId, out bool IsPowerCycling); @@ -565,16 +586,20 @@ private static void ClearTargetController() if (targetController is not null) { targetController.InputsUpdated -= UpdateInputs; + targetController.SetLightColor(0, 0, 0); targetController.Cleanup(); targetController.Unplug(); targetController = null; + + // update HIDInstancePath + SettingsManager.SetProperty("HIDInstancePath", string.Empty); } } public static void SetTargetController(string baseContainerDeviceInstanceId, bool IsPowerCycling) { // unplug current controller - if (targetController is not null && targetController.IsPlugged()) + if (targetController is not null) { string targetPath = targetController.GetContainerInstancePath(); @@ -605,22 +630,38 @@ public static void SetTargetController(string baseContainerDeviceInstanceId, boo targetController.InputsUpdated += UpdateInputs; targetController.Plug(); + var _systemBackground = uiSettings.GetColorValue(UIColorType.Background); + var _systemAccent = uiSettings.GetColorValue(UIColorType.Accent); + targetController.SetLightColor(_systemAccent.R, _systemAccent.G, _systemAccent.B); + + // update HIDInstancePath + SettingsManager.SetProperty("HIDInstancePath", baseContainerDeviceInstanceId); + if (!IsPowerCycling) { - if (SettingsManager.GetBoolean("HIDvibrateonconnect")) - targetController.Rumble(); - if (SettingsManager.GetBoolean("HIDcloakonconnect")) - targetController.Hide(); - - // update settings - SettingsManager.SetProperty("HIDInstancePath", baseContainerDeviceInstanceId); + if (!targetController.IsHidden()) + targetController.Hide(); } // check applicable scenarios CheckControllerScenario(); - // raise event + // check if controller is about to power cycle + PowerCyclers.TryGetValue(baseContainerDeviceInstanceId, out IsPowerCycling); + + if (!IsPowerCycling) + { + if (SettingsManager.GetBoolean("HIDvibrateonconnect")) + targetController.Rumble(); + } + else + { + // stop listening to device while it's power cycled + // only usefull for Xbox One bluetooth controllers + targetController.Unplug(); + } + ControllerSelected?.Invoke(targetController); } diff --git a/HandheldCompanion/Misc/HidHide.cs b/HandheldCompanion/Misc/HidHide.cs index ad2db0b4a..9b6f5e740 100644 --- a/HandheldCompanion/Misc/HidHide.cs +++ b/HandheldCompanion/Misc/HidHide.cs @@ -66,7 +66,7 @@ public static List GetRegisteredDevices() try { var service = new HidHideControlService(); - return service.BlockedInstanceIds.ToList(); + return service.BlockedInstanceIds.Select(x => x.ToUpper()).ToList(); } catch { @@ -80,7 +80,7 @@ public static bool IsRegistered(string InstanceId) try { var registered = GetRegisteredDevices(); - return registered.Contains(InstanceId); + return registered.Contains(InstanceId.ToUpper()); } catch { @@ -143,7 +143,7 @@ public static bool RegisterApplication(string fileName) return true; } - public static void SetCloaking(bool status) + public static bool SetCloaking(bool status) { try { @@ -153,13 +153,32 @@ public static void SetCloaking(bool status) } catch { + if (process is null) + return false; + + switch(status) + { + case true: + process.StartInfo.Arguments = $"--cloak-on"; + break; + case false: + process.StartInfo.Arguments = $"--cloak-off"; + break; + } + process.Start(); + process.WaitForExit(); + process.StandardOutput.ReadToEnd(); + + LogManager.LogInformation("HideDevice SetCloaking: {0}", status); } + + return true; } - public static void UnhidePath(string deviceInstancePath) + public static bool UnhidePath(string deviceInstancePath) { if (string.IsNullOrEmpty(deviceInstancePath)) - return; + return false; try { @@ -172,13 +191,24 @@ public static void UnhidePath(string deviceInstancePath) } catch { + if (process is null) + return false; + + process.StartInfo.Arguments = $"--dev-unhide \"{deviceInstancePath}\""; + process.Start(); + process.WaitForExit(); + process.StandardOutput.ReadToEnd(); + + LogManager.LogInformation("HideDevice AddBlockedInstanceId: {0}", deviceInstancePath); } + + return true; } - public static void HidePath(string deviceInstancePath) + public static bool HidePath(string deviceInstancePath) { if (string.IsNullOrEmpty(deviceInstancePath)) - return; + return false; try { @@ -191,10 +221,21 @@ public static void HidePath(string deviceInstancePath) } catch { + if (process is null) + return false; + + process.StartInfo.Arguments = $"--dev-hide \"{deviceInstancePath}\""; + process.Start(); + process.WaitForExit(); + process.StandardOutput.ReadToEnd(); + + LogManager.LogInformation("HideDevice AddBlockedInstanceId: {0}", deviceInstancePath); } + + return true; } - public static List GetHidHideDevices() + public static List GetHidHideDevices(string arg = "--dev-all") { try { diff --git a/HandheldCompanion/Misc/JoyShockLibrary.cs b/HandheldCompanion/Misc/JoyShockLibrary.cs index beb931fe5..5c134c18a 100644 --- a/HandheldCompanion/Misc/JoyShockLibrary.cs +++ b/HandheldCompanion/Misc/JoyShockLibrary.cs @@ -102,6 +102,8 @@ public delegate void EventCallback(int handle, JOY_SHOCK_STATE state, JOY_SHOCK_ public static extern void JslDisconnectAndDisposeAll(); [DllImport("JoyShockLibrary")] public static extern bool JslStillConnected(int deviceId); + [DllImport("JoyShockLibrary")] + public static extern void JslDisconnect(int deviceId); [DllImport("JoyShockLibrary", CallingConvention = CallingConvention.Cdecl)] public static extern JOY_SHOCK_STATE JslGetSimpleState(int deviceId); diff --git a/HandheldCompanion/Misc/PnPDetails.cs b/HandheldCompanion/Misc/PnPDetails.cs index 0bcd30082..9f4dc044d 100644 --- a/HandheldCompanion/Misc/PnPDetails.cs +++ b/HandheldCompanion/Misc/PnPDetails.cs @@ -60,31 +60,157 @@ public short GetMI() return -1; } + public string GetEnumerator() + { + PnPDevice device = GetBasePnPDevice(); + if (device is not null) + return device.GetProperty(DevicePropertyKey.Device_EnumeratorName); + + return string.Empty; + } + public UsbPnPDevice GetUsbPnPDevice() { - var pnpDevice = PnPDevice.GetDeviceByInstanceId(baseContainerDeviceInstanceId); - if (pnpDevice is null) + PnPDevice device = GetBasePnPDevice(); + if (device is null) return null; // is this a USB device - var enumerator = pnpDevice.GetProperty(DevicePropertyKey.Device_EnumeratorName); - if (!Equals(enumerator, "USB")) - return null; + string enumerator = GetEnumerator(); + + switch (enumerator) + { + default: + case "BTHENUM": + return null; + case "USB": + break; + } + + return device.ToUsbPnPDevice(); + } + + public PnPDevice GetPnPDevice() + { + try + { + return PnPDevice.GetDeviceByInstanceId(deviceInstanceId); + } + catch { } - return pnpDevice.ToUsbPnPDevice(); + return null; + } + + public PnPDevice GetBasePnPDevice() + { + try + { + return PnPDevice.GetDeviceByInstanceId(baseContainerDeviceInstanceId); + } + catch { } + + return null; } public bool CyclePort() { - var usbDevice = GetUsbPnPDevice(); + UsbPnPDevice device = GetUsbPnPDevice(); - if (usbDevice is null) - return false; + try + { + if (device is not null) + { + device.CyclePort(); + return true; + } + } + catch { } + + return false; + } + + public bool InstallNullDrivers(bool basedevice = true) + { + PnPDevice device; + + switch (basedevice) + { + case true: + device = GetBasePnPDevice(); + break; + case false: + device = GetPnPDevice(); + break; + } + + try + { + if (device is not null) + { + device.InstallNullDriver(); + return true; + } + } + catch { } + + return false; + } + + public bool InstallCustomDriver(string driverName, bool basedevice = true) + { + PnPDevice device; + + switch(basedevice) + { + case true: + device = GetBasePnPDevice(); + break; + case false: + device = GetPnPDevice(); + break; + } + + try + { + if (device is not null) + { + device.InstallCustomDriver(driverName); + return true; + } + } + catch { } + + return false; + } + + public bool Uninstall(bool basedevice = true, bool parent = false) + { + PnPDevice device; + + switch (basedevice) + { + case true: + device = GetBasePnPDevice(); + + if (parent) + { + var parentId = device.GetProperty(DevicePropertyKey.Device_Parent); + device = PnPDevice.GetDeviceByInstanceId(parentId); + } + + break; + case false: + device = GetPnPDevice(); + break; + } try { - usbDevice.CyclePort(); - return true; + if (device is not null) + { + device.Uninstall(); + return true; + } } catch { } diff --git a/HandheldCompanion/Properties/Resources.Designer.cs b/HandheldCompanion/Properties/Resources.Designer.cs index 556e0310d..c6f780fec 100644 --- a/HandheldCompanion/Properties/Resources.Designer.cs +++ b/HandheldCompanion/Properties/Resources.Designer.cs @@ -781,6 +781,33 @@ public static string ControllerPage_VibrationStrengthExpl { } } + ///

+ /// Looks up a localized string similar to Please switch your controller off and then on again by pressing and holding the Guide button to finalize pairing.. + /// + public static string ControllerPage_XInputControllerWarning { + get { + return ResourceManager.GetString("ControllerPage_XInputControllerWarning", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Device. + /// + public static string DevicePage_Device { + get { + return ResourceManager.GetString("DevicePage_Device", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Power options. + /// + public static string DevicePage_PowerOptions { + get { + return ResourceManager.GetString("DevicePage_PowerOptions", resourceCulture); + } + } + /// /// Looks up a localized string similar to DIRECTIONAL PAD. /// @@ -3627,6 +3654,15 @@ public static string MainWindow_navController { } } + /// + /// Looks up a localized string similar to Device. + /// + public static string MainWindow_navDevice { + get { + return ResourceManager.GetString("MainWindow_navDevice", resourceCulture); + } + } + /// /// Looks up a localized string similar to Hotkeys. /// @@ -6175,15 +6211,6 @@ public static string SettingsPage_OpenAppBackgroundDesc { } } - /// - /// Looks up a localized string similar to Power options. - /// - public static string SettingsPage_PowerOptions { - get { - return ResourceManager.GetString("SettingsPage_PowerOptions", resourceCulture); - } - } - /// /// Looks up a localized string similar to Quicktools backdrop, none, mica, tabbed, acrylic. /// diff --git a/HandheldCompanion/Properties/Resources.de-DE.resx b/HandheldCompanion/Properties/Resources.de-DE.resx index cb594f360..32d2cac13 100644 --- a/HandheldCompanion/Properties/Resources.de-DE.resx +++ b/HandheldCompanion/Properties/Resources.de-DE.resx @@ -1479,7 +1479,7 @@ Wenn die Bewegungseingabe aktiviert ist, verwenden Sie die ausgewählte(n) Taste Unten Links - + Energie-Optionen diff --git a/HandheldCompanion/Properties/Resources.es-ES.resx b/HandheldCompanion/Properties/Resources.es-ES.resx index 122838d1e..ce61f08d0 100644 --- a/HandheldCompanion/Properties/Resources.es-ES.resx +++ b/HandheldCompanion/Properties/Resources.es-ES.resx @@ -1429,7 +1429,7 @@ Fondo de herramientas rápidas, none, mica, tabbed, acrylic - + Opciones de energía diff --git a/HandheldCompanion/Properties/Resources.fr-FR.resx b/HandheldCompanion/Properties/Resources.fr-FR.resx index c64eb6cd9..3f69604b1 100644 --- a/HandheldCompanion/Properties/Resources.fr-FR.resx +++ b/HandheldCompanion/Properties/Resources.fr-FR.resx @@ -1518,7 +1518,7 @@ with motion input enabled, use selected button(s) to disable motion. Bottom left - + Power options diff --git a/HandheldCompanion/Properties/Resources.it-IT.resx b/HandheldCompanion/Properties/Resources.it-IT.resx index e1cc1da42..4cdf4aa09 100644 --- a/HandheldCompanion/Properties/Resources.it-IT.resx +++ b/HandheldCompanion/Properties/Resources.it-IT.resx @@ -1486,7 +1486,7 @@ Bottom left - + Power options diff --git a/HandheldCompanion/Properties/Resources.ja-JP.resx b/HandheldCompanion/Properties/Resources.ja-JP.resx index bef7d2f9a..5ed4fe329 100644 --- a/HandheldCompanion/Properties/Resources.ja-JP.resx +++ b/HandheldCompanion/Properties/Resources.ja-JP.resx @@ -1483,7 +1483,7 @@ Bottom left - + Power options diff --git a/HandheldCompanion/Properties/Resources.pt-BR.resx b/HandheldCompanion/Properties/Resources.pt-BR.resx index 5ac820cb9..48c123cf3 100644 --- a/HandheldCompanion/Properties/Resources.pt-BR.resx +++ b/HandheldCompanion/Properties/Resources.pt-BR.resx @@ -1481,7 +1481,7 @@ com a entrada de movimento ligada, use o(s) botão(ões) selecionado(s) para des Inferior esquerdo - + Opções de energia diff --git a/HandheldCompanion/Properties/Resources.resx b/HandheldCompanion/Properties/Resources.resx index d6f59b9ac..d366498b7 100644 --- a/HandheldCompanion/Properties/Resources.resx +++ b/HandheldCompanion/Properties/Resources.resx @@ -1526,7 +1526,7 @@ with motion input enabled, use selected button(s) to disable motion. Automatically turn HWiNFO off when companion is closed - + Power options @@ -2345,4 +2345,13 @@ with motion input enabled, use selected button(s) to disable motion. Steam Xbox Controller Enhanced Features Driver is installed + + Device + + + Device + + + Please switch your controller off and then on again by pressing and holding the Guide button to finalize pairing. + \ No newline at end of file diff --git a/HandheldCompanion/Properties/Resources.ru-RU.resx b/HandheldCompanion/Properties/Resources.ru-RU.resx index e14329011..7325a9147 100644 --- a/HandheldCompanion/Properties/Resources.ru-RU.resx +++ b/HandheldCompanion/Properties/Resources.ru-RU.resx @@ -2251,7 +2251,7 @@ Not set - + Power options diff --git a/HandheldCompanion/Properties/Resources.zh-CN.resx b/HandheldCompanion/Properties/Resources.zh-CN.resx index 4bca84411..fca65511b 100644 --- a/HandheldCompanion/Properties/Resources.zh-CN.resx +++ b/HandheldCompanion/Properties/Resources.zh-CN.resx @@ -1468,7 +1468,7 @@ 左下 - + 电源选项 diff --git a/HandheldCompanion/Properties/Resources.zh-Hant.resx b/HandheldCompanion/Properties/Resources.zh-Hant.resx index 44e86a42e..621fcef57 100644 --- a/HandheldCompanion/Properties/Resources.zh-Hant.resx +++ b/HandheldCompanion/Properties/Resources.zh-Hant.resx @@ -1468,7 +1468,7 @@ 左下 - + 電源選項 diff --git a/HandheldCompanion/Properties/Settings.Designer.cs b/HandheldCompanion/Properties/Settings.Designer.cs index 5548fe108..6a23d71a3 100644 --- a/HandheldCompanion/Properties/Settings.Designer.cs +++ b/HandheldCompanion/Properties/Settings.Designer.cs @@ -1,20 +1,19 @@ //------------------------------------------------------------------------------ // -// Ce code a été généré par un outil. -// Version du runtime :4.0.30319.42000 +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 // -// Les modifications apportées à ce fichier peuvent provoquer un comportement incorrect et seront perdues si -// le code est régénéré. +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. // //------------------------------------------------------------------------------ -using System.Configuration; namespace HandheldCompanion.Properties { - - - [SettingsProvider(typeof(CustomSettingsProvider))] - internal sealed partial class Settings : ApplicationSettingsBase - { + + + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.8.0.0")] + internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); diff --git a/HandheldCompanion/Utils/CommonUtils.cs b/HandheldCompanion/Utils/CommonUtils.cs index 1dd155fb2..eec25dd56 100644 --- a/HandheldCompanion/Utils/CommonUtils.cs +++ b/HandheldCompanion/Utils/CommonUtils.cs @@ -50,6 +50,13 @@ public static bool IsAdministrator() return principal.IsInRole(WindowsBuiltInRole.Administrator); } + public static int rgb_to_int(byte led_r, byte led_g, byte led_b) + { + int colour = 0; + colour = (led_r << 16) | (led_g << 8) | led_b; + return colour; + } + public static void OpenUrl(string url) { try diff --git a/HandheldCompanion/Utils/FileUtils.cs b/HandheldCompanion/Utils/FileUtils.cs index 012597303..5d3d31c49 100644 --- a/HandheldCompanion/Utils/FileUtils.cs +++ b/HandheldCompanion/Utils/FileUtils.cs @@ -1,5 +1,4 @@ using System.IO; -using System.IO.Packaging; using System.Security.AccessControl; using System.Security.Principal; diff --git a/HandheldCompanion/Views/Pages/ControllerPage.xaml b/HandheldCompanion/Views/Pages/ControllerPage.xaml index 8d9acf0e3..78c13a65b 100644 --- a/HandheldCompanion/Views/Pages/ControllerPage.xaml +++ b/HandheldCompanion/Views/Pages/ControllerPage.xaml @@ -62,7 +62,7 @@ Visibility="Collapsed"> - + - + - + - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/HandheldCompanion/Views/Pages/DevicePage.xaml.cs b/HandheldCompanion/Views/Pages/DevicePage.xaml.cs new file mode 100644 index 000000000..2da8e4e88 --- /dev/null +++ b/HandheldCompanion/Views/Pages/DevicePage.xaml.cs @@ -0,0 +1,125 @@ +using ColorPicker.Models; +using ColorPicker; +using HandheldCompanion.Devices; +using HandheldCompanion.Managers; +using HandheldCompanion.Misc; +using Inkore.UI.WPF.Modern.Controls; +using System; +using System.Windows; +using Page = System.Windows.Controls.Page; +using System.Windows.Media; + +namespace HandheldCompanion.Views.Pages +{ + /// + /// Interaction logic for DevicePage.xaml + /// + public partial class DevicePage : Page + { + public DevicePage() + { + InitializeComponent(); + + SettingsManager.SettingValueChanged += SettingsManager_SettingValueChanged; + } + + public DevicePage(string? Tag) : this() + { + this.Tag = Tag; + } + + private void Page_Loaded(object? sender, RoutedEventArgs? e) + { + } + + public void Page_Closed() + { + } + + private void SettingsManager_SettingValueChanged(string? name, object value) + { + // UI thread (async) + Application.Current.Dispatcher.BeginInvoke(() => + { + switch (name) + { + case "ConfigurableTDPOverride": + Toggle_cTDP.IsOn = Convert.ToBoolean(value); + break; + case "ConfigurableTDPOverrideDown": + NumberBox_TDPMin.Value = Convert.ToDouble(value); + break; + case "ConfigurableTDPOverrideUp": + NumberBox_TDPMax.Value = Convert.ToDouble(value); + break; + } + }); + } + + private async void Toggle_cTDP_Toggled(object? sender, RoutedEventArgs? e) + { + if (!IsLoaded) + return; + + if (Toggle_cTDP.IsOn) + { + // todo: localize me ! + var result = Dialog.ShowAsync( + "Warning", + "Altering minimum and maximum CPU power values might cause instabilities. Product warranties may not apply if the processor is operated beyond its specifications. Use at your own risk.", + ContentDialogButton.Primary, "Cancel", Properties.Resources.ProfilesPage_OK); + + await result; // sync call + + switch (result.Result) + { + case ContentDialogResult.Primary: + break; + default: + case ContentDialogResult.None: + // restore previous state + Toggle_cTDP.IsOn = false; + return; + } + } + + SettingsManager.SetProperty("ConfigurableTDPOverride", Toggle_cTDP.IsOn); + SettingsManager.SetProperty("ConfigurableTDPOverrideUp", NumberBox_TDPMax.Value); + SettingsManager.SetProperty("ConfigurableTDPOverrideDown", NumberBox_TDPMin.Value); + } + + private void NumberBox_TDPMax_ValueChanged(NumberBox? sender, NumberBoxValueChangedEventArgs? args) + { + var value = NumberBox_TDPMax.Value; + if (double.IsNaN(value)) + return; + + NumberBox_TDPMin.Maximum = value; + + if (!IsLoaded) + return; + + // update current device cTDP + MainWindow.CurrentDevice.cTDP[1] = value; + + SettingsManager.SetProperty("ConfigurableTDPOverrideUp", value); + } + + private void NumberBox_TDPMin_ValueChanged(NumberBox? sender, NumberBoxValueChangedEventArgs? args) + { + var value = NumberBox_TDPMin.Value; + if (double.IsNaN(value)) + return; + + NumberBox_TDPMax.Minimum = value; + + if (!IsLoaded) + return; + + // update current device cTDP + MainWindow.CurrentDevice.cTDP[0] = value; + + SettingsManager.SetProperty("ConfigurableTDPOverrideDown", value); + } + } +} diff --git a/HandheldCompanion/Views/Pages/SettingsPage.xaml b/HandheldCompanion/Views/Pages/SettingsPage.xaml index 9d6c8f18d..5634f0905 100644 --- a/HandheldCompanion/Views/Pages/SettingsPage.xaml +++ b/HandheldCompanion/Views/Pages/SettingsPage.xaml @@ -552,8 +552,8 @@ - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/HandheldCompanion/Views/Pages/SettingsPage.xaml.cs b/HandheldCompanion/Views/Pages/SettingsPage.xaml.cs index 4044a69d7..0963329db 100644 --- a/HandheldCompanion/Views/Pages/SettingsPage.xaml.cs +++ b/HandheldCompanion/Views/Pages/SettingsPage.xaml.cs @@ -217,15 +217,6 @@ private void SettingsManager_SettingValueChanged(string? name, object value) case "SensorPlacementUpsideDown": Toggle_SensorPlacementUpsideDown.IsOn = Convert.ToBoolean(value); break; - case "ConfigurableTDPOverride": - Toggle_cTDP.IsOn = Convert.ToBoolean(value); - break; - case "ConfigurableTDPOverrideDown": - NumberBox_TDPMin.Value = Convert.ToDouble(value); - break; - case "ConfigurableTDPOverrideUp": - NumberBox_TDPMax.Value = Convert.ToDouble(value); - break; case "CurrentCulture": cB_Language.SelectedItem = new CultureInfo((string)value); @@ -610,72 +601,6 @@ private void SwitchBackdrop(Window targetWindow, int idx) } } - private async void Toggle_cTDP_Toggled(object? sender, RoutedEventArgs? e) - { - if (!IsLoaded) - return; - - if (Toggle_cTDP.IsOn) - { - // todo: localize me ! - var result = Dialog.ShowAsync( - "Warning", - "Altering minimum and maximum CPU power values might cause instabilities. Product warranties may not apply if the processor is operated beyond its specifications. Use at your own risk.", - ContentDialogButton.Primary, "Cancel", Properties.Resources.ProfilesPage_OK); - - await result; // sync call - - switch (result.Result) - { - case ContentDialogResult.Primary: - break; - default: - case ContentDialogResult.None: - // restore previous state - Toggle_cTDP.IsOn = false; - return; - } - } - - SettingsManager.SetProperty("ConfigurableTDPOverride", Toggle_cTDP.IsOn); - SettingsManager.SetProperty("ConfigurableTDPOverrideUp", NumberBox_TDPMax.Value); - SettingsManager.SetProperty("ConfigurableTDPOverrideDown", NumberBox_TDPMin.Value); - } - - private void NumberBox_TDPMax_ValueChanged(NumberBox? sender, NumberBoxValueChangedEventArgs? args) - { - var value = NumberBox_TDPMax.Value; - if (double.IsNaN(value)) - return; - - NumberBox_TDPMin.Maximum = value; - - if (!IsLoaded) - return; - - // update current device cTDP - MainWindow.CurrentDevice.cTDP[1] = value; - - SettingsManager.SetProperty("ConfigurableTDPOverrideUp", value); - } - - private void NumberBox_TDPMin_ValueChanged(NumberBox? sender, NumberBoxValueChangedEventArgs? args) - { - var value = NumberBox_TDPMin.Value; - if (double.IsNaN(value)) - return; - - NumberBox_TDPMax.Minimum = value; - - if (!IsLoaded) - return; - - // update current device cTDP - MainWindow.CurrentDevice.cTDP[0] = value; - - SettingsManager.SetProperty("ConfigurableTDPOverrideDown", value); - } - private void cB_SensorSelection_SelectionChanged(object? sender, SelectionChangedEventArgs? e) { if (cB_SensorSelection.SelectedIndex == -1) diff --git a/HandheldCompanion/Views/SplashScreen.xaml b/HandheldCompanion/Views/SplashScreen.xaml index a7f76ba09..a4f479105 100644 --- a/HandheldCompanion/Views/SplashScreen.xaml +++ b/HandheldCompanion/Views/SplashScreen.xaml @@ -9,7 +9,6 @@ xmlns:ui="http://schemas.inkore.net/lib/ui/wpf/modern" Width="450" Height="450" - ui:ThemeManager.ActualThemeChanged="OverlayWindow_ActualThemeChanged" ui:ThemeManager.IsThemeAware="True" ui:WindowHelper.SystemBackdropType="Mica" ui:WindowHelper.UseAcrylicBackdrop="True" diff --git a/HandheldCompanion/Views/SplashScreen.xaml.cs b/HandheldCompanion/Views/SplashScreen.xaml.cs index e73a29053..a862cd15d 100644 --- a/HandheldCompanion/Views/SplashScreen.xaml.cs +++ b/HandheldCompanion/Views/SplashScreen.xaml.cs @@ -12,10 +12,5 @@ public SplashScreen() { InitializeComponent(); } - - private void OverlayWindow_ActualThemeChanged(object sender, RoutedEventArgs e) - { - // do something - } } } diff --git a/HandheldCompanion/Views/Windows/MainWindow.xaml b/HandheldCompanion/Views/Windows/MainWindow.xaml index 9fbbf5eb2..e0ce78bd0 100644 --- a/HandheldCompanion/Views/Windows/MainWindow.xaml +++ b/HandheldCompanion/Views/Windows/MainWindow.xaml @@ -47,6 +47,18 @@ Tag="ControllerPage"> + + + + + + + + + @@ -57,6 +69,7 @@ Tag="ProfilesPage"> + @@ -67,6 +80,7 @@ Tag="OverlayPage"> + @@ -77,6 +91,7 @@ Tag="HotkeysPage"> + @@ -87,6 +102,7 @@ Tag="AboutPage"> + @@ -97,6 +113,7 @@ Tag="SettingsPage"> + diff --git a/HandheldCompanion/Views/Windows/MainWindow.xaml.cs b/HandheldCompanion/Views/Windows/MainWindow.xaml.cs index b70c90a23..66c3b1622 100644 --- a/HandheldCompanion/Views/Windows/MainWindow.xaml.cs +++ b/HandheldCompanion/Views/Windows/MainWindow.xaml.cs @@ -43,6 +43,7 @@ public partial class MainWindow : GamepadWindow private static readonly Dictionary _pages = new(); public static ControllerPage controllerPage; + public static DevicePage devicePage; public static ProfilesPage profilesPage; public static SettingsPage settingsPage; public static AboutPage aboutPage; @@ -98,7 +99,7 @@ public MainWindow(FileVersionInfo _fileVersionInfo, Assembly CurrentAssembly) var tablets = Tablet.TabletDevices; // get first start - var FirstStart = SettingsManager.GetBoolean("FirstStart"); + bool FirstStart = SettingsManager.GetBoolean("FirstStart"); // define current directory InstallPath = AppDomain.CurrentDomain.BaseDirectory; @@ -184,6 +185,8 @@ public MainWindow(FileVersionInfo _fileVersionInfo, Assembly CurrentAssembly) { splashScreen = new SplashScreen(); splashScreen.Show(); + + SettingsManager.SetProperty("FirstStart", false); } // load manager(s) @@ -381,6 +384,7 @@ private void loadPages() controllerPage = new ControllerPage("controller"); controllerPage.Loaded += ControllerPage_Loaded; + devicePage = new DevicePage("device"); profilesPage = new ProfilesPage("profiles"); settingsPage = new SettingsPage("settings"); aboutPage = new AboutPage("about"); @@ -390,6 +394,7 @@ private void loadPages() // store pages _pages.Add("ControllerPage", controllerPage); + _pages.Add("DevicePage", devicePage); _pages.Add("ProfilesPage", profilesPage); _pages.Add("AboutPage", aboutPage); _pages.Add("OverlayPage", overlayPage);