From 1fbe7017c176cc0547e235bf05f8e1781bcac426 Mon Sep 17 00:00:00 2001 From: deckertron9000 <10391684+deckertron9000@users.noreply.github.com> Date: Sun, 31 Mar 2019 15:16:30 -0500 Subject: [PATCH 01/16] Adding marshaling information for sdk calls. --- RGB.NET.Devices.Msi/Native/_MsiSDK.cs | 83 ++++++++++++++++++++++----- 1 file changed, 68 insertions(+), 15 deletions(-) diff --git a/RGB.NET.Devices.Msi/Native/_MsiSDK.cs b/RGB.NET.Devices.Msi/Native/_MsiSDK.cs index 031918d..a67aa94 100644 --- a/RGB.NET.Devices.Msi/Native/_MsiSDK.cs +++ b/RGB.NET.Devices.Msi/Native/_MsiSDK.cs @@ -110,51 +110,104 @@ namespace RGB.NET.Devices.Msi.Native private delegate int InitializePointer(); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - private delegate int GetDeviceInfoPointer(out string[] pDevType, out int[] pLedCount); + private delegate int GetDeviceInfoPointer( + [Out, MarshalAs(UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_BSTR)] out string[] pDevType, + [Out, MarshalAs(UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_BSTR)] out string[] pLedCount); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - private delegate int GetLedInfoPointer(string type, int index, out string pName, out string[] pLedStyles); + private delegate int GetLedInfoPointer( + [In, MarshalAs(UnmanagedType.BStr)] string type, + [In, MarshalAs(UnmanagedType.I4)] int index, + [Out, MarshalAs(UnmanagedType.BStr)] out string pName, + [Out, MarshalAs(UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_BSTR)] out string[] pLedStyles); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - private delegate int GetLedColorPointer(string type, int index, out int r, out int g, out int b); + private delegate int GetLedColorPointer( + [In, MarshalAs(UnmanagedType.BStr)] string type, + [In, MarshalAs(UnmanagedType.I4)] int index, + [Out, MarshalAs(UnmanagedType.I4)] out int r, + [Out, MarshalAs(UnmanagedType.I4)] out int g, + [Out, MarshalAs(UnmanagedType.I4)] out int b); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - private delegate int GetLedStylePointer(string type, int index, out int style); + private delegate int GetLedStylePointer( + [In, MarshalAs(UnmanagedType.BStr)] string type, + [In, MarshalAs(UnmanagedType.I4)] int index, + [Out, MarshalAs(UnmanagedType.BStr)] out string style); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - private delegate int GetLedMaxBrightPointer(string type, int index, out int maxLevel); + private delegate int GetLedMaxBrightPointer( + [In, MarshalAs(UnmanagedType.BStr)] string type, + [In, MarshalAs(UnmanagedType.I4)] int index, + [Out, MarshalAs(UnmanagedType.I4)] out int maxLevel); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - private delegate int GetLedBrightPointer(string type, int index, out int currentLevel); + private delegate int GetLedBrightPointer( + [In, MarshalAs(UnmanagedType.BStr)] string type, + [In, MarshalAs(UnmanagedType.I4)] int index, + [Out, MarshalAs(UnmanagedType.I4)] out int currentLevel); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - private delegate int GetLedMaxSpeedPointer(string type, int index, out int maxSpeed); + private delegate int GetLedMaxSpeedPointer( + [In, MarshalAs(UnmanagedType.BStr)] string type, + [In, MarshalAs(UnmanagedType.I4)] int index, + [Out, MarshalAs(UnmanagedType.I4)] out int maxSpeed); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - private delegate int GetLedSpeedPointer(string type, int index, out int currentSpeed); + private delegate int GetLedSpeedPointer( + [In, MarshalAs(UnmanagedType.BStr)] string type, + [In, MarshalAs(UnmanagedType.I4)] int index, + [Out, MarshalAs(UnmanagedType.I4)] out int currentSpeed); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - private delegate int SetLedColorPointer(string type, int index, int r, int g, int b); + private delegate int SetLedColorPointer( + [In, MarshalAs(UnmanagedType.BStr)] string type, + [In, MarshalAs(UnmanagedType.I4)] int index, + [In, MarshalAs(UnmanagedType.I4)] int r, + [In, MarshalAs(UnmanagedType.I4)] int g, + [In, MarshalAs(UnmanagedType.I4)] int b); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - private delegate int SetLedStylePointer(string type, int index, string style); + private delegate int SetLedStylePointer( + [In, MarshalAs(UnmanagedType.BStr)] string type, + [In, MarshalAs(UnmanagedType.I4)] int index, + [In, MarshalAs(UnmanagedType.BStr)] string style); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - private delegate int SetLedBrightPointer(string type, int index, int level); + private delegate int SetLedBrightPointer( + [In, MarshalAs(UnmanagedType.BStr)] string type, + [In, MarshalAs(UnmanagedType.I4)] int index, + [In, MarshalAs(UnmanagedType.I4)] int level); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - private delegate int SetLedSpeedPointer(string type, int index, int speed); + private delegate int SetLedSpeedPointer( + [In, MarshalAs(UnmanagedType.BStr)] string type, + [In, MarshalAs(UnmanagedType.I4)] int index, + [In, MarshalAs(UnmanagedType.I4)] int speed); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - private delegate int GetErrorMessagePointer(int errorCode, out string pDesc); + private delegate int GetErrorMessagePointer( + [In, MarshalAs(UnmanagedType.I4)] int errorCode, + [Out, MarshalAs(UnmanagedType.BStr)] out string pDesc); #endregion internal static int Initialize() => _initializePointer(); - internal static int GetDeviceInfo(out string[] pDevType, out int[] pLedCount) => _getDeviceInfoPointer(out pDevType, out pLedCount); + internal static int GetDeviceInfo(out string[] pDevType, out int[] pLedCount) + { + // HACK - SDK GetDeviceInfo returns a string[] for ledCount, so we'll parse that to int. + int result = _getDeviceInfoPointer(out pDevType, out string[] ledCount); + pLedCount = new int[ledCount.Length]; + + for (int i = 0; i < ledCount.Length; i++) + pLedCount[i] = int.Parse(ledCount[i]); + + return result; + } + internal static int GetLedInfo(string type, int index, out string pName, out string[] pLedStyles) => _getLedInfoPointer(type, index, out pName, out pLedStyles); internal static int GetLedColor(string type, int index, out int r, out int g, out int b) => _getLedColorPointer(type, index, out r, out g, out b); - internal static int GetLedStyle(string type, int index, out int style) => _getLedStylePointer(type, index, out style); + internal static int GetLedStyle(string type, int index, out string style) => _getLedStylePointer(type, index, out style); internal static int GetLedMaxBright(string type, int index, out int maxLevel) => _getLedMaxBrightPointer(type, index, out maxLevel); internal static int GetLedBright(string type, int index, out int currentLevel) => _getLedBrightPointer(type, index, out currentLevel); internal static int GetLedMaxSpeed(string type, int index, out int maxSpeed) => _getLedMaxSpeedPointer(type, index, out maxSpeed); From 4d5728a8be2382b45d8d2c607c1d32ebb8f805da Mon Sep 17 00:00:00 2001 From: Robert Date: Wed, 11 Dec 2019 09:51:21 +0100 Subject: [PATCH 02/16] Fixed AbtractRGBDevice not updating DeviceRectangle on Location change --- RGB.NET.Core/Devices/AbstractRGBDevice.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/RGB.NET.Core/Devices/AbstractRGBDevice.cs b/RGB.NET.Core/Devices/AbstractRGBDevice.cs index cd76493..2ed8377 100644 --- a/RGB.NET.Core/Devices/AbstractRGBDevice.cs +++ b/RGB.NET.Core/Devices/AbstractRGBDevice.cs @@ -32,7 +32,11 @@ namespace RGB.NET.Core public Point Location { get => _location; - set => SetProperty(ref _location, value); + set + { + if (SetProperty(ref _location, value)) + UpdateActualData(); + } } private Size _size = Size.Invalid; From 7690a49e43e533194bfd74cb6698a645e5e72574 Mon Sep 17 00:00:00 2001 From: SpoinkyNL Date: Wed, 11 Dec 2019 22:34:19 +0100 Subject: [PATCH 03/16] Wooting device provider --- .../Enum/WootingDevicesIndexes.cs | 21 ++ .../Enum/WootingLogicalKeyboardLayout.cs | 16 ++ .../Enum/WootingPhysicalKeyboardLayout.cs | 16 ++ .../Generic/IWootingRGBDevice.cs | 12 + .../Generic/WootingRGBDevice.cs | 71 +++++ .../Generic/WootingRGBDeviceInfo.cs | 62 +++++ .../Helper/EnumExtension.cs | 41 +++ .../Keyboard/WootingKeyboardLedMappings.cs | 262 ++++++++++++++++++ .../Keyboard/WootingKeyboardRGBDevice.cs | 53 ++++ .../Keyboard/WootingKeyboardRGBDeviceInfo.cs | 57 ++++ RGB.NET.Devices.Wooting/Native/_WootingSDK.cs | 123 ++++++++ .../RGB.NET.Devices.Wooting.csproj | 68 +++++ .../WootingDeviceProvider.cs | 120 ++++++++ .../WootingDeviceProviderLoader.cs | 24 ++ RGB.NET.sln | 11 +- 15 files changed, 955 insertions(+), 2 deletions(-) create mode 100644 RGB.NET.Devices.Wooting/Enum/WootingDevicesIndexes.cs create mode 100644 RGB.NET.Devices.Wooting/Enum/WootingLogicalKeyboardLayout.cs create mode 100644 RGB.NET.Devices.Wooting/Enum/WootingPhysicalKeyboardLayout.cs create mode 100644 RGB.NET.Devices.Wooting/Generic/IWootingRGBDevice.cs create mode 100644 RGB.NET.Devices.Wooting/Generic/WootingRGBDevice.cs create mode 100644 RGB.NET.Devices.Wooting/Generic/WootingRGBDeviceInfo.cs create mode 100644 RGB.NET.Devices.Wooting/Helper/EnumExtension.cs create mode 100644 RGB.NET.Devices.Wooting/Keyboard/WootingKeyboardLedMappings.cs create mode 100644 RGB.NET.Devices.Wooting/Keyboard/WootingKeyboardRGBDevice.cs create mode 100644 RGB.NET.Devices.Wooting/Keyboard/WootingKeyboardRGBDeviceInfo.cs create mode 100644 RGB.NET.Devices.Wooting/Native/_WootingSDK.cs create mode 100644 RGB.NET.Devices.Wooting/RGB.NET.Devices.Wooting.csproj create mode 100644 RGB.NET.Devices.Wooting/WootingDeviceProvider.cs create mode 100644 RGB.NET.Devices.Wooting/WootingDeviceProviderLoader.cs diff --git a/RGB.NET.Devices.Wooting/Enum/WootingDevicesIndexes.cs b/RGB.NET.Devices.Wooting/Enum/WootingDevicesIndexes.cs new file mode 100644 index 0000000..c25afa4 --- /dev/null +++ b/RGB.NET.Devices.Wooting/Enum/WootingDevicesIndexes.cs @@ -0,0 +1,21 @@ +// ReSharper disable InconsistentNaming +// ReSharper disable UnusedMember.Global + +using System.ComponentModel; + +#pragma warning disable 1591 // Missing XML comment for publicly visible type or member + +namespace RGB.NET.Devices.Wooting.Enum +{ + /// + /// Contains a list of available device-indexes. + /// + public enum WootingDevicesIndexes + { + [Description("Wooting One")] + WootingOne = 0, + + [Description("Wooting Two")] + WootingTwo = 1 + } +} diff --git a/RGB.NET.Devices.Wooting/Enum/WootingLogicalKeyboardLayout.cs b/RGB.NET.Devices.Wooting/Enum/WootingLogicalKeyboardLayout.cs new file mode 100644 index 0000000..f21929d --- /dev/null +++ b/RGB.NET.Devices.Wooting/Enum/WootingLogicalKeyboardLayout.cs @@ -0,0 +1,16 @@ +// ReSharper disable InconsistentNaming +// ReSharper disable UnusedMember.Global + +#pragma warning disable 1591 // Missing XML comment for publicly visible type or member + +namespace RGB.NET.Devices.Wooting.Enum +{ + /// + /// Contains list of available logical layouts for cooler master keyboards. + /// + public enum WootingLogicalKeyboardLayout + { + US = 0, + EU = 1 + }; +} diff --git a/RGB.NET.Devices.Wooting/Enum/WootingPhysicalKeyboardLayout.cs b/RGB.NET.Devices.Wooting/Enum/WootingPhysicalKeyboardLayout.cs new file mode 100644 index 0000000..2142d50 --- /dev/null +++ b/RGB.NET.Devices.Wooting/Enum/WootingPhysicalKeyboardLayout.cs @@ -0,0 +1,16 @@ +// ReSharper disable InconsistentNaming +// ReSharper disable UnusedMember.Global + +#pragma warning disable 1591 // Missing XML comment for publicly visible type or member + +namespace RGB.NET.Devices.Wooting.Enum +{ + /// + /// Contains list of available physical layouts for Wooting keyboards. + /// + public enum WootingPhysicalKeyboardLayout + { + US = 0, + EU = 1 + } +} diff --git a/RGB.NET.Devices.Wooting/Generic/IWootingRGBDevice.cs b/RGB.NET.Devices.Wooting/Generic/IWootingRGBDevice.cs new file mode 100644 index 0000000..42c6995 --- /dev/null +++ b/RGB.NET.Devices.Wooting/Generic/IWootingRGBDevice.cs @@ -0,0 +1,12 @@ +using RGB.NET.Core; + +namespace RGB.NET.Devices.Wooting.Generic +{ + /// + /// Represents a Wooting RGB-device. + /// + internal interface IWootingRGBDevice : IRGBDevice + { + void Initialize(UpdateQueue updateQueue); + } +} diff --git a/RGB.NET.Devices.Wooting/Generic/WootingRGBDevice.cs b/RGB.NET.Devices.Wooting/Generic/WootingRGBDevice.cs new file mode 100644 index 0000000..6fd6af7 --- /dev/null +++ b/RGB.NET.Devices.Wooting/Generic/WootingRGBDevice.cs @@ -0,0 +1,71 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using RGB.NET.Core; +using RGB.NET.Devices.Wooting.Native; + +namespace RGB.NET.Devices.Wooting.Generic +{ + /// + /// + /// + /// Represents a Wooting-device + /// + public abstract class WootingRGBDevice : AbstractRGBDevice, IWootingRGBDevice + where TDeviceInfo : WootingRGBDeviceInfo + { + #region Properties & Fields + + /// + /// + /// Gets information about the . + /// + public override TDeviceInfo DeviceInfo { get; } + + /// + /// Gets or sets the update queue performing updates for this device. + /// + // ReSharper disable once MemberCanBePrivate.Global + protected UpdateQueue UpdateQueue { get; set; } + + #endregion + + #region Constructors + + /// + /// Initializes a new instance of the class. + /// + /// The generic information provided by Wooting for the device. + protected WootingRGBDevice(TDeviceInfo info) + { + this.DeviceInfo = info; + } + + #endregion + + #region Methods + + /// + /// Initializes the device. + /// + public void Initialize(UpdateQueue updateQueue) + { + InitializeLayout(); + + if (Size == Size.Invalid) + { + Rectangle ledRectangle = new Rectangle(this.Select(x => x.LedRectangle)); + Size = ledRectangle.Size + new Size(ledRectangle.Location.X, ledRectangle.Location.Y); + } + + UpdateQueue = updateQueue; + } + + /// + /// Initializes the and of the device. + /// + protected abstract void InitializeLayout(); + + #endregion + } +} diff --git a/RGB.NET.Devices.Wooting/Generic/WootingRGBDeviceInfo.cs b/RGB.NET.Devices.Wooting/Generic/WootingRGBDeviceInfo.cs new file mode 100644 index 0000000..bf91f8d --- /dev/null +++ b/RGB.NET.Devices.Wooting/Generic/WootingRGBDeviceInfo.cs @@ -0,0 +1,62 @@ +using System; +using RGB.NET.Core; +using RGB.NET.Devices.Wooting.Enum; +using RGB.NET.Devices.Wooting.Helper; + +namespace RGB.NET.Devices.Wooting.Generic +{ + /// + /// + /// Represents a generic information for a Wooting-. + /// + public class WootingRGBDeviceInfo : IRGBDeviceInfo + { + #region Properties & Fields + + /// + public RGBDeviceType DeviceType { get; } + + /// + public string DeviceName { get; } + + /// + public string Manufacturer => "Wooting"; + + /// + public string Model { get; } + + /// + public Uri Image { get; set; } + + /// + public RGBDeviceLighting Lighting => RGBDeviceLighting.Key; + + /// + public bool SupportsSyncBack => false; + + /// + /// Gets the of the . + /// + public WootingDevicesIndexes DeviceIndex { get; } + + #endregion + + #region Constructors + + /// + /// Internal constructor of managed . + /// + /// The type of the . + /// The of the . + internal WootingRGBDeviceInfo(RGBDeviceType deviceType, WootingDevicesIndexes deviceIndex) + { + this.DeviceType = deviceType; + this.DeviceIndex = deviceIndex; + + Model = deviceIndex.GetDescription(); + DeviceName = $"{Manufacturer} {Model}"; + } + + #endregion + } +} diff --git a/RGB.NET.Devices.Wooting/Helper/EnumExtension.cs b/RGB.NET.Devices.Wooting/Helper/EnumExtension.cs new file mode 100644 index 0000000..7c2e8b3 --- /dev/null +++ b/RGB.NET.Devices.Wooting/Helper/EnumExtension.cs @@ -0,0 +1,41 @@ +using System; +using System.ComponentModel; +using System.Reflection; +using RGB.NET.Core; + +namespace RGB.NET.Devices.Wooting.Helper +{ + /// + /// Offers some extensions and helper-methods for enum related things. + /// + internal static class EnumExtension + { + /// + /// Gets the value of the . + /// + /// The enum value to get the description from. + /// The generic enum-type + /// The value of the or the result of the source. + internal static string GetDescription(this T source) + where T : struct + { + return source.GetAttribute()?.Description ?? source.ToString(); + } + + /// + /// Gets the attribute of type T. + /// + /// The enum value to get the attribute from + /// The generic attribute type + /// The generic enum-type + /// The . + private static T GetAttribute(this TEnum source) + where T : Attribute + where TEnum : struct + { + FieldInfo fi = source.GetType().GetField(source.ToString()); + T[] attributes = (T[])fi.GetCustomAttributes(typeof(T), false); + return attributes.Length > 0 ? attributes[0] : null; + } + } +} diff --git a/RGB.NET.Devices.Wooting/Keyboard/WootingKeyboardLedMappings.cs b/RGB.NET.Devices.Wooting/Keyboard/WootingKeyboardLedMappings.cs new file mode 100644 index 0000000..ebc62d3 --- /dev/null +++ b/RGB.NET.Devices.Wooting/Keyboard/WootingKeyboardLedMappings.cs @@ -0,0 +1,262 @@ +// ReSharper disable InconsistentNaming + +using System.Collections.Generic; +using RGB.NET.Core; +using RGB.NET.Devices.Wooting.Enum; + +namespace RGB.NET.Devices.Wooting.Keyboard +{ + /// + /// Contains all the hardware-id mappings for Wooting devices. + /// + internal static class WootingKeyboardLedMappings + { + #region Properties & Fields + + #region Wooting One + + private static readonly Dictionary WootingOne_US = new Dictionary + { + { LedId.Keyboard_Escape, (0,0) }, + { LedId.Keyboard_F1, (0,2) }, + { LedId.Keyboard_F2, (0,3) }, + { LedId.Keyboard_F3, (0,4) }, + { LedId.Keyboard_F4, (0,5) }, + { LedId.Keyboard_F5, (0,6) }, + { LedId.Keyboard_F6, (0,7) }, + { LedId.Keyboard_F7, (0,8) }, + { LedId.Keyboard_F8, (0,9) }, + { LedId.Keyboard_F9, (0,10) }, + { LedId.Keyboard_F10, (0,11) }, + { LedId.Keyboard_F11, (0,12) }, + { LedId.Keyboard_F12, (0,13) }, + { LedId.Keyboard_PrintScreen, (0,14) }, + { LedId.Keyboard_PauseBreak, (0,15) }, + { LedId.Keyboard_Custom1, (0,20) }, // TODO: Make sure it is not 0,16 + + { LedId.Keyboard_GraveAccentAndTilde, (1,0) }, + { LedId.Keyboard_1, (1,1) }, + { LedId.Keyboard_2, (1,2) }, + { LedId.Keyboard_3, (1,3) }, + { LedId.Keyboard_4, (1,4) }, + { LedId.Keyboard_5, (1,5) }, + { LedId.Keyboard_6, (1,6) }, + { LedId.Keyboard_7, (1,7) }, + { LedId.Keyboard_8, (1,8) }, + { LedId.Keyboard_9, (1,9) }, + { LedId.Keyboard_0, (1,10) }, + { LedId.Keyboard_MinusAndUnderscore, (1,11) }, + { LedId.Keyboard_EqualsAndPlus, (1,12) }, + { LedId.Keyboard_Backspace, (1,13) }, + { LedId.Keyboard_Insert, (1,14) }, + { LedId.Keyboard_Home, (1,15) }, + { LedId.Keyboard_PageUp, (1,16) }, + + { LedId.Keyboard_Tab, (2,0) }, + { LedId.Keyboard_Q, (2,1) }, + { LedId.Keyboard_W, (2,2) }, + { LedId.Keyboard_E, (2,3) }, + { LedId.Keyboard_R, (2,4) }, + { LedId.Keyboard_T, (2,5) }, + { LedId.Keyboard_Y, (2,6) }, + { LedId.Keyboard_U, (2,7) }, + { LedId.Keyboard_I, (2,8) }, + { LedId.Keyboard_O, (2,9) }, + { LedId.Keyboard_P, (2,10) }, + { LedId.Keyboard_BracketLeft, (2,11) }, + { LedId.Keyboard_BracketRight, (2,12) }, + { LedId.Keyboard_Backslash, (2,13) }, + { LedId.Keyboard_Delete, (2,14) }, + { LedId.Keyboard_End, (2,15) }, + { LedId.Keyboard_PageDown, (2,16) }, + + { LedId.Keyboard_CapsLock, (3,0) }, + { LedId.Keyboard_A, (3,1) }, + { LedId.Keyboard_S, (3,2) }, + { LedId.Keyboard_D, (3,3) }, + { LedId.Keyboard_F, (3,4) }, + { LedId.Keyboard_G, (3,5) }, + { LedId.Keyboard_H, (3,6) }, + { LedId.Keyboard_J, (3,7) }, + { LedId.Keyboard_K, (3,8) }, + { LedId.Keyboard_L, (3,9) }, + { LedId.Keyboard_SemicolonAndColon, (3,10) }, + { LedId.Keyboard_ApostropheAndDoubleQuote, (3,11) }, + { LedId.Keyboard_Enter, (3,13) }, + + { LedId.Keyboard_LeftShift, (4,0) }, + { LedId.Keyboard_NonUsBackslash, (4,1) }, + { LedId.Keyboard_Z, (4,2) }, + { LedId.Keyboard_X, (4,3) }, + { LedId.Keyboard_C, (4,4) }, + { LedId.Keyboard_V, (4,5) }, + { LedId.Keyboard_B, (4,6) }, + { LedId.Keyboard_N, (4,7) }, + { LedId.Keyboard_M, (4,8) }, + { LedId.Keyboard_CommaAndLessThan, (4,9) }, + { LedId.Keyboard_PeriodAndBiggerThan, (4,10) }, + { LedId.Keyboard_SlashAndQuestionMark, (4,11) }, + { LedId.Keyboard_RightShift, (4,13) }, + { LedId.Keyboard_ArrowUp, (4,15) }, + + { LedId.Keyboard_LeftCtrl, (5,0) }, + { LedId.Keyboard_LeftGui, (5,1) }, + { LedId.Keyboard_LeftAlt, (5,2) }, + { LedId.Keyboard_Space, (5,6) }, + { LedId.Keyboard_RightAlt, (5,10) }, + { LedId.Keyboard_RightGui, (5,11) }, + { LedId.Keyboard_Application, (5,12) }, + { LedId.Keyboard_RightCtrl, (5,13) }, + { LedId.Keyboard_ArrowLeft, (5,14) }, + { LedId.Keyboard_ArrowDown, (5,15) }, + { LedId.Keyboard_ArrowRight, (5,16) } + }; + + #endregion + + #region Wooting Two + + private static readonly Dictionary WootingTwo_US = new Dictionary + { + { LedId.Keyboard_Escape, (0,0) }, + { LedId.Keyboard_F1, (0,2) }, + { LedId.Keyboard_F2, (0,3) }, + { LedId.Keyboard_F3, (0,4) }, + { LedId.Keyboard_F4, (0,5) }, + { LedId.Keyboard_F5, (0,6) }, + { LedId.Keyboard_F6, (0,7) }, + { LedId.Keyboard_F7, (0,8) }, + { LedId.Keyboard_F8, (0,9) }, + { LedId.Keyboard_F9, (0,10) }, + { LedId.Keyboard_F10, (0,11) }, + { LedId.Keyboard_F11, (0,12) }, + { LedId.Keyboard_F12, (0,13) }, + { LedId.Keyboard_PrintScreen, (0,14) }, + { LedId.Keyboard_PauseBreak, (0,15) }, + { LedId.Keyboard_ScrollLock, (0,16) }, + { LedId.Keyboard_Custom1, (0,17) }, + { LedId.Keyboard_Custom2, (0,18) }, + { LedId.Keyboard_Custom3, (0,19) }, + { LedId.Keyboard_Custom4, (0,20) }, + + { LedId.Keyboard_GraveAccentAndTilde, (1,0) }, + { LedId.Keyboard_1, (1,1) }, + { LedId.Keyboard_2, (1,2) }, + { LedId.Keyboard_3, (1,3) }, + { LedId.Keyboard_4, (1,4) }, + { LedId.Keyboard_5, (1,5) }, + { LedId.Keyboard_6, (1,6) }, + { LedId.Keyboard_7, (1,7) }, + { LedId.Keyboard_8, (1,8) }, + { LedId.Keyboard_9, (1,9) }, + { LedId.Keyboard_0, (1,10) }, + { LedId.Keyboard_MinusAndUnderscore, (1,11) }, + { LedId.Keyboard_EqualsAndPlus, (1,12) }, + { LedId.Keyboard_Backspace, (1,13) }, + { LedId.Keyboard_Insert, (1,14) }, + { LedId.Keyboard_Home, (1,15) }, + { LedId.Keyboard_PageUp, (1,16) }, + { LedId.Keyboard_NumLock, (1,17) }, + { LedId.Keyboard_NumSlash, (1,18) }, + { LedId.Keyboard_NumAsterisk, (1,19) }, + { LedId.Keyboard_NumMinus, (1,20) }, + + { LedId.Keyboard_Tab, (2,0) }, + { LedId.Keyboard_Q, (2,1) }, + { LedId.Keyboard_W, (2,2) }, + { LedId.Keyboard_E, (2,3) }, + { LedId.Keyboard_R, (2,4) }, + { LedId.Keyboard_T, (2,5) }, + { LedId.Keyboard_Y, (2,6) }, + { LedId.Keyboard_U, (2,7) }, + { LedId.Keyboard_I, (2,8) }, + { LedId.Keyboard_O, (2,9) }, + { LedId.Keyboard_P, (2,10) }, + { LedId.Keyboard_BracketLeft, (2,11) }, + { LedId.Keyboard_BracketRight, (2,12) }, + { LedId.Keyboard_Backslash, (2,13) }, + { LedId.Keyboard_Delete, (2,14) }, + { LedId.Keyboard_End, (2,15) }, + { LedId.Keyboard_PageDown, (2,16) }, + { LedId.Keyboard_Num7, (2,17) }, + { LedId.Keyboard_Num8, (2,18) }, + { LedId.Keyboard_Num9, (2,19) }, + { LedId.Keyboard_NumPlus, (2,20) }, + + { LedId.Keyboard_CapsLock, (3,0) }, + { LedId.Keyboard_A, (3,1) }, + { LedId.Keyboard_S, (3,2) }, + { LedId.Keyboard_D, (3,3) }, + { LedId.Keyboard_F, (3,4) }, + { LedId.Keyboard_G, (3,5) }, + { LedId.Keyboard_H, (3,6) }, + { LedId.Keyboard_J, (3,7) }, + { LedId.Keyboard_K, (3,8) }, + { LedId.Keyboard_L, (3,9) }, + { LedId.Keyboard_SemicolonAndColon, (3,10) }, + { LedId.Keyboard_ApostropheAndDoubleQuote, (3,11) }, + { LedId.Keyboard_Enter, (3,13) }, + { LedId.Keyboard_Num4, (3,17) }, + { LedId.Keyboard_Num5, (3,18) }, + { LedId.Keyboard_Num6, (3,19) }, + + { LedId.Keyboard_LeftShift, (4,0) }, + { LedId.Keyboard_NonUsBackslash, (4,1) }, + { LedId.Keyboard_Z, (4,2) }, + { LedId.Keyboard_X, (4,3) }, + { LedId.Keyboard_C, (4,4) }, + { LedId.Keyboard_V, (4,5) }, + { LedId.Keyboard_B, (4,6) }, + { LedId.Keyboard_N, (4,7) }, + { LedId.Keyboard_M, (4,8) }, + { LedId.Keyboard_CommaAndLessThan, (4,9) }, + { LedId.Keyboard_PeriodAndBiggerThan, (4,10) }, + { LedId.Keyboard_SlashAndQuestionMark, (4,11) }, + { LedId.Keyboard_RightShift, (4,13) }, + { LedId.Keyboard_ArrowUp, (4,15) }, + { LedId.Keyboard_Num1, (4,17) }, + { LedId.Keyboard_Num2, (4,18) }, + { LedId.Keyboard_Num3, (4,19) }, + { LedId.Keyboard_NumEnter, (4,20) }, + + { LedId.Keyboard_LeftCtrl, (5,0) }, + { LedId.Keyboard_LeftGui, (5,1) }, + { LedId.Keyboard_LeftAlt, (5,2) }, + { LedId.Keyboard_Space, (5,6) }, + { LedId.Keyboard_RightAlt, (5,10) }, + { LedId.Keyboard_RightGui, (5,11) }, + { LedId.Keyboard_Application, (5,12) }, + { LedId.Keyboard_RightCtrl, (5,13) }, + { LedId.Keyboard_ArrowLeft, (5,14) }, + { LedId.Keyboard_ArrowDown, (5,15) }, + { LedId.Keyboard_ArrowRight, (5,16) }, + { LedId.Keyboard_Num0, (5,18) }, + { LedId.Keyboard_NumPeriodAndDelete, (5,19) } + }; + + #endregion + + /// + /// Contains all the hardware-id mappings for Wooting devices. + /// + public static readonly Dictionary>> Mapping = + new Dictionary>> + { + { WootingDevicesIndexes.WootingOne, new Dictionary> + { + { WootingPhysicalKeyboardLayout.US, WootingOne_US }, + { WootingPhysicalKeyboardLayout.EU, WootingOne_US } + } + }, + + { WootingDevicesIndexes.WootingTwo, new Dictionary> + { + { WootingPhysicalKeyboardLayout.US, WootingTwo_US }, + { WootingPhysicalKeyboardLayout.EU, WootingTwo_US } + } + } + }; + + #endregion + } +} diff --git a/RGB.NET.Devices.Wooting/Keyboard/WootingKeyboardRGBDevice.cs b/RGB.NET.Devices.Wooting/Keyboard/WootingKeyboardRGBDevice.cs new file mode 100644 index 0000000..0b3334a --- /dev/null +++ b/RGB.NET.Devices.Wooting/Keyboard/WootingKeyboardRGBDevice.cs @@ -0,0 +1,53 @@ +using System.Collections.Generic; +using System.Linq; +using RGB.NET.Core; +using RGB.NET.Devices.Wooting.Generic; + +namespace RGB.NET.Devices.Wooting.Keyboard +{ + /// + /// + /// Represents a Wooting keyboard. + /// + public class WootingKeyboardRGBDevice : WootingRGBDevice + { + #region Constructors + + /// + /// + /// Initializes a new instance of the class. + /// + /// The specific information provided by Wooting for the keyboard + internal WootingKeyboardRGBDevice(WootingKeyboardRGBDeviceInfo info) + : base(info) + { } + + #endregion + + #region Methods + + /// + protected override void InitializeLayout() + { + + Dictionary mapping = WootingKeyboardLedMappings.Mapping[DeviceInfo.DeviceIndex][DeviceInfo.PhysicalLayout]; + + foreach (KeyValuePair led in mapping) + { + InitializeLed(led.Key, new Point(led.Value.column * 19, led.Value.row * 19), new Size(19,19)); + } + + string model = DeviceInfo.Model.Replace(" ", string.Empty).ToUpper(); + ApplyLayoutFromFile(PathHelper.GetAbsolutePath(this, $@"Layouts\Wooting\Keyboards\{model}", $"{DeviceInfo.PhysicalLayout.ToString().ToUpper()}.xml"), + DeviceInfo.LogicalLayout.ToString()); + } + + /// + protected override void UpdateLeds(IEnumerable ledsToUpdate) => UpdateQueue.SetData(ledsToUpdate.Where(x => x.Color.A > 0)); + + /// + protected override object CreateLedCustomData(LedId ledId) => WootingKeyboardLedMappings.Mapping[DeviceInfo.DeviceIndex][DeviceInfo.PhysicalLayout][ledId]; + + #endregion + } +} diff --git a/RGB.NET.Devices.Wooting/Keyboard/WootingKeyboardRGBDeviceInfo.cs b/RGB.NET.Devices.Wooting/Keyboard/WootingKeyboardRGBDeviceInfo.cs new file mode 100644 index 0000000..f7806f0 --- /dev/null +++ b/RGB.NET.Devices.Wooting/Keyboard/WootingKeyboardRGBDeviceInfo.cs @@ -0,0 +1,57 @@ +using System; +using System.Globalization; +using RGB.NET.Core; +using RGB.NET.Devices.Wooting.Enum; +using RGB.NET.Devices.Wooting.Generic; + +namespace RGB.NET.Devices.Wooting.Keyboard +{ + /// + /// + /// Represents a generic information for a . + /// + public class WootingKeyboardRGBDeviceInfo : WootingRGBDeviceInfo + { + #region Properties & Fields + + /// + /// Gets the of the . + /// + public WootingPhysicalKeyboardLayout PhysicalLayout { get; } + + /// + /// Gets the of the . + /// + public WootingLogicalKeyboardLayout LogicalLayout { get; private set; } + + #endregion + + #region Constructors + + /// + /// + /// Internal constructor of managed . + /// + /// The index of the . + /// The of the . + /// The of the layout this keyboard is using + internal WootingKeyboardRGBDeviceInfo(WootingDevicesIndexes deviceIndex, WootingPhysicalKeyboardLayout physicalKeyboardLayout, CultureInfo culture) + : base(RGBDeviceType.Keyboard, deviceIndex) + { + this.PhysicalLayout = physicalKeyboardLayout; + + // For now just go for this + switch (physicalKeyboardLayout) + { + case WootingPhysicalKeyboardLayout.US: + this.LogicalLayout = WootingLogicalKeyboardLayout.US; + break; + case WootingPhysicalKeyboardLayout.EU: + this.LogicalLayout = WootingLogicalKeyboardLayout.EU; + break; + } + } + + #endregion + } +} diff --git a/RGB.NET.Devices.Wooting/Native/_WootingSDK.cs b/RGB.NET.Devices.Wooting/Native/_WootingSDK.cs new file mode 100644 index 0000000..402f6f4 --- /dev/null +++ b/RGB.NET.Devices.Wooting/Native/_WootingSDK.cs @@ -0,0 +1,123 @@ +// ReSharper disable UnusedMethodReturnValue.Global +// ReSharper disable UnusedMember.Global + +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Runtime.InteropServices; +using System.Text; +using RGB.NET.Core; + +namespace RGB.NET.Devices.Wooting.Native +{ + // ReSharper disable once InconsistentNaming + public class _WootingSDK + { + #region Library management + + private static IntPtr _dllHandle = IntPtr.Zero; + + /// + /// Gets the loaded architecture (x64/x86). + /// + internal static string LoadedArchitecture { get; private set; } + + /// + /// Reloads the SDK. + /// + internal static void Reload() + { + UnloadWootingSDK(); + LoadWootingSDK(); + } + + private static void LoadWootingSDK() + { + if (_dllHandle != IntPtr.Zero) return; + + // HACK: Load library at runtime to support both, x86 and x64 with one managed dll + List possiblePathList = Environment.Is64BitProcess ? WootingDeviceProvider.PossibleX64NativePaths : WootingDeviceProvider.PossibleX86NativePaths; + string dllPath = possiblePathList.FirstOrDefault(File.Exists); + if (dllPath == null) throw new RGBDeviceException($"Can't find the Wooting-SDK at one of the expected locations:\r\n '{string.Join("\r\n", possiblePathList.Select(Path.GetFullPath))}'"); + + SetDllDirectory(Path.GetDirectoryName(Path.GetFullPath(dllPath))); + + _dllHandle = LoadLibrary(dllPath); + + _isWootingOnePointer = (IsWootingOnePointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "wooting_rgb_kbd_is_wooting_one"), typeof(IsWootingOnePointer)); + _isWootingTwoPointer = (IsWootingTwoPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "wooting_rgb_kbd_is_wooting_two"), typeof(IsWootingTwoPointer)); + _keyboardConnectedPointer = (KeyboardConnectedPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "wooting_rgb_kbd_connected"), typeof(KeyboardConnectedPointer)); + _resetPointer = (ResetPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "wooting_rgb_reset"), typeof(ResetPointer)); + _arrayUpdateKeyboardPointer = (ArrayUpdateKeyboardPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "wooting_rgb_array_update_keyboard"), typeof(ArrayUpdateKeyboardPointer)); + _arraySetSinglePointer = (ArraySetSinglePointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "wooting_rgb_array_set_single"), typeof(ArraySetSinglePointer)); + } + + private static void UnloadWootingSDK() + { + if (_dllHandle == IntPtr.Zero) return; + + // ReSharper disable once EmptyEmbeddedStatement - DarthAffe 20.02.2016: We might need to reduce the internal reference counter more than once to set the library free + while (FreeLibrary(_dllHandle)) ; + _dllHandle = IntPtr.Zero; + } + + [DllImport("kernel32.dll")] + private static extern bool SetDllDirectory(string lpPathName); + + [DllImport("kernel32.dll")] + private static extern IntPtr LoadLibrary(string dllToLoad); + + [DllImport("kernel32.dll")] + private static extern bool FreeLibrary(IntPtr dllHandle); + + [DllImport("kernel32.dll")] + private static extern IntPtr GetProcAddress(IntPtr dllHandle, string name); + + #endregion + + #region SDK-METHODS + + #region Pointers + + private static IsWootingOnePointer _isWootingOnePointer; + private static IsWootingTwoPointer _isWootingTwoPointer; + private static KeyboardConnectedPointer _keyboardConnectedPointer; + private static ResetPointer _resetPointer; + private static ArrayUpdateKeyboardPointer _arrayUpdateKeyboardPointer; + private static ArraySetSinglePointer _arraySetSinglePointer; + + #endregion + + #region Delegates + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + private delegate bool IsWootingOnePointer(); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + private delegate bool IsWootingTwoPointer(); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + private delegate bool KeyboardConnectedPointer(); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + private delegate bool ResetPointer(); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + private delegate bool ArrayUpdateKeyboardPointer(); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + private delegate bool ArraySetSinglePointer(byte row, byte column, byte red, byte green, byte blue); + + #endregion + + internal static bool IsWootingOne() => _isWootingOnePointer(); + internal static bool IsWootingTwo() => _isWootingTwoPointer(); + internal static bool KeyboardConnected() => _keyboardConnectedPointer(); + internal static bool Reset() => _resetPointer(); + internal static bool ArrayUpdateKeyboard() => _arrayUpdateKeyboardPointer(); + internal static bool ArraySetSingle(byte row, byte column, byte red, byte green, byte blue) => _arraySetSinglePointer(row, column, red, green, blue); + + #endregion + } +} diff --git a/RGB.NET.Devices.Wooting/RGB.NET.Devices.Wooting.csproj b/RGB.NET.Devices.Wooting/RGB.NET.Devices.Wooting.csproj new file mode 100644 index 0000000..128556f --- /dev/null +++ b/RGB.NET.Devices.Wooting/RGB.NET.Devices.Wooting.csproj @@ -0,0 +1,68 @@ + + + netstandard2.0;net45 + win7-x86;win7-x64 + + Darth Affe + Wyrez + en-US + en-US + RGB.NET.Devices.Wooting + RGB.NET.Devices.Wooting + RGB.NET.Devices.Wooting + RGB.NET.Devices.Wooting + RGB.NET.Devices.Wooting + Wooting-Device-Implementations of RGB.NET + Wooting-Device-Implementations of RGB.NET, a C# (.NET) library for accessing various RGB-peripherals + Copyright © Wyrez 2017 + Copyright © Wyrez 2017 + http://lib.arge.be/icon.png + https://github.com/DarthAffe/RGB.NET + https://raw.githubusercontent.com/DarthAffe/RGB.NET/master/LICENSE + Github + https://github.com/DarthAffe/RGB.NET + False + + + + 0.0.1 + 0.0.1 + 0.0.1 + + ..\bin\ + true + True + True + latest + + + + NETCORE;NETSTANDARD;NETSTANDARD2_0 + + + + NET45;NETFULL + + + + $(DefineConstants);TRACE;DEBUG + true + full + false + + + + pdbonly + true + $(NoWarn);CS1591;CS1572;CS1573 + $(DefineConstants);RELEASE + + + + + + + + + + \ No newline at end of file diff --git a/RGB.NET.Devices.Wooting/WootingDeviceProvider.cs b/RGB.NET.Devices.Wooting/WootingDeviceProvider.cs new file mode 100644 index 0000000..417b967 --- /dev/null +++ b/RGB.NET.Devices.Wooting/WootingDeviceProvider.cs @@ -0,0 +1,120 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using RGB.NET.Core; +using RGB.NET.Devices.Wooting.Native; + +namespace RGB.NET.Devices.Wooting +{ + /// + /// + /// Represents a device provider responsible for Wooting devices. + /// + public class WootingDeviceProvider : IRGBDeviceProvider + { + #region Properties & Fields + + private static WootingDeviceProvider _instance; + /// + /// Gets the singleton instance. + /// + public static WootingDeviceProvider Instance => _instance ?? new WootingDeviceProvider(); + + /// + /// Gets a modifiable list of paths used to find the native SDK-dlls for x86 applications. + /// The first match will be used. + /// + public static List PossibleX86NativePaths { get; } = new List { "x86/wooting-rgb-sdk.dll" }; + + /// + /// Gets a modifiable list of paths used to find the native SDK-dlls for x64 applications. + /// The first match will be used. + /// + public static List PossibleX64NativePaths { get; } = new List { "x64/wooting-rgb-sdk64.dll" }; + + /// + /// + /// Indicates if the SDK is initialized and ready to use. + /// + public bool IsInitialized { get; private set; } + + /// + /// Gets the loaded architecture (x64/x86). + /// + public string LoadedArchitecture => _WootingSDK.LoadedArchitecture; + + /// + /// + /// Gets whether the application has exclusive access to the SDK or not. + /// + public bool HasExclusiveAccess => false; + + /// + public IEnumerable Devices { get; private set; } + + #endregion + + #region Constructors + + /// + /// Initializes a new instance of the class. + /// + /// Thrown if this constructor is called even if there is already an instance of this class. + public WootingDeviceProvider() + { + if (_instance != null) throw new InvalidOperationException($"There can be only one instance of type {nameof(WootingDeviceProvider)}"); + _instance = this; + } + + #endregion + + #region Methods + + /// + /// Thrown if the SDK failed to initialize + public bool Initialize(RGBDeviceType loadFilter = RGBDeviceType.All, bool exclusiveAccessIfPossible = false, bool throwExceptions = false) + { + IsInitialized = false; + + try + { + _WootingSDK.Reload(); + + IList devices = new List(); + if (_WootingSDK.KeyboardConnected()) + { + if (_WootingSDK.IsWootingOne()) + { + + } + else if (_WootingSDK.IsWootingTwo()) + { + + } + } + Devices = new ReadOnlyCollection(devices); + IsInitialized = true; + } + catch + { + if (throwExceptions) throw; + return false; + } + + return true; + } + + /// + public void ResetDevices() + { } + + /// + public void Dispose() + { + try { _WootingSDK.Reset(); } + catch { /* Unlucky.. */} + } + + #endregion + } +} diff --git a/RGB.NET.Devices.Wooting/WootingDeviceProviderLoader.cs b/RGB.NET.Devices.Wooting/WootingDeviceProviderLoader.cs new file mode 100644 index 0000000..5daf314 --- /dev/null +++ b/RGB.NET.Devices.Wooting/WootingDeviceProviderLoader.cs @@ -0,0 +1,24 @@ +using RGB.NET.Core; + +namespace RGB.NET.Devices.Wooting +{ + /// + /// Represents a device provider loaded used to dynamically load Wooting devices into an application. + /// + public class WootingDeviceProviderLoader : IRGBDeviceProviderLoader + { + #region Properties & Fields + + /// + public bool RequiresInitialization => false; + + #endregion + + #region Methods + + /// + public IRGBDeviceProvider GetDeviceProvider() => WootingDeviceProvider.Instance; + + #endregion + } +} diff --git a/RGB.NET.sln b/RGB.NET.sln index e3edb01..2d2701e 100644 --- a/RGB.NET.sln +++ b/RGB.NET.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 15 -VisualStudioVersion = 15.0.27703.2035 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.29424.173 MinimumVisualStudioVersion = 10.0.40219.1 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Devices", "Devices", "{D13032C6-432E-4F43-8A32-071133C22B16}" EndProject @@ -47,6 +47,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RGB.NET.Core.Tests", "Tests EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RGB.NET.Devices.Asus", "RGB.NET.Devices.Asus\RGB.NET.Devices.Asus.csproj", "{E0732B34-3F96-4DD9-AFD5-0E34B833AD6D}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RGB.NET.Devices.Wooting", "RGB.NET.Devices.Wooting\RGB.NET.Devices.Wooting.csproj", "{DD46DB2D-85BE-4962-86AE-E38C9053A548}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -129,6 +131,10 @@ Global {E0732B34-3F96-4DD9-AFD5-0E34B833AD6D}.Debug|Any CPU.Build.0 = Debug|Any CPU {E0732B34-3F96-4DD9-AFD5-0E34B833AD6D}.Release|Any CPU.ActiveCfg = Release|Any CPU {E0732B34-3F96-4DD9-AFD5-0E34B833AD6D}.Release|Any CPU.Build.0 = Release|Any CPU + {DD46DB2D-85BE-4962-86AE-E38C9053A548}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {DD46DB2D-85BE-4962-86AE-E38C9053A548}.Debug|Any CPU.Build.0 = Debug|Any CPU + {DD46DB2D-85BE-4962-86AE-E38C9053A548}.Release|Any CPU.ActiveCfg = Release|Any CPU + {DD46DB2D-85BE-4962-86AE-E38C9053A548}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -152,6 +158,7 @@ Global {FFDE4387-60F2-47B6-9704-3A57D02B8C64} = {D13032C6-432E-4F43-8A32-071133C22B16} {A3FD5AD7-040A-47CA-A278-53493A25FF8A} = {92D7C263-D4C9-4D26-93E2-93C1F9C2CD16} {E0732B34-3F96-4DD9-AFD5-0E34B833AD6D} = {D13032C6-432E-4F43-8A32-071133C22B16} + {DD46DB2D-85BE-4962-86AE-E38C9053A548} = {D13032C6-432E-4F43-8A32-071133C22B16} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {7F222AD4-1F9E-4AAB-9D69-D62372D4C1BA} From a94509dfcb7b653d8636ec2600e2868883af70f6 Mon Sep 17 00:00:00 2001 From: SpoinkyNL Date: Fri, 13 Dec 2019 10:01:05 +0100 Subject: [PATCH 04/16] Implemented update queue and corrected the LED mappings --- .../Enum/WootingLogicalKeyboardLayout.cs | 2 +- .../Enum/WootingPhysicalKeyboardLayout.cs | 2 +- .../Generic/IWootingRGBDevice.cs | 2 +- .../Generic/WootingRGBDevice.cs | 11 ++-- .../Generic/WootingUpdateQueue.cs | 42 +++++++++++++++ .../Keyboard/WootingKeyboardLedMappings.cs | 4 +- .../Keyboard/WootingKeyboardRGBDeviceInfo.cs | 5 +- .../WootingDeviceProvider.cs | 54 +++++++++++++++---- 8 files changed, 96 insertions(+), 26 deletions(-) create mode 100644 RGB.NET.Devices.Wooting/Generic/WootingUpdateQueue.cs diff --git a/RGB.NET.Devices.Wooting/Enum/WootingLogicalKeyboardLayout.cs b/RGB.NET.Devices.Wooting/Enum/WootingLogicalKeyboardLayout.cs index f21929d..59976fb 100644 --- a/RGB.NET.Devices.Wooting/Enum/WootingLogicalKeyboardLayout.cs +++ b/RGB.NET.Devices.Wooting/Enum/WootingLogicalKeyboardLayout.cs @@ -11,6 +11,6 @@ namespace RGB.NET.Devices.Wooting.Enum public enum WootingLogicalKeyboardLayout { US = 0, - EU = 1 + UK = 1 }; } diff --git a/RGB.NET.Devices.Wooting/Enum/WootingPhysicalKeyboardLayout.cs b/RGB.NET.Devices.Wooting/Enum/WootingPhysicalKeyboardLayout.cs index 2142d50..2b37cbf 100644 --- a/RGB.NET.Devices.Wooting/Enum/WootingPhysicalKeyboardLayout.cs +++ b/RGB.NET.Devices.Wooting/Enum/WootingPhysicalKeyboardLayout.cs @@ -11,6 +11,6 @@ namespace RGB.NET.Devices.Wooting.Enum public enum WootingPhysicalKeyboardLayout { US = 0, - EU = 1 + UK = 1 } } diff --git a/RGB.NET.Devices.Wooting/Generic/IWootingRGBDevice.cs b/RGB.NET.Devices.Wooting/Generic/IWootingRGBDevice.cs index 42c6995..b7356eb 100644 --- a/RGB.NET.Devices.Wooting/Generic/IWootingRGBDevice.cs +++ b/RGB.NET.Devices.Wooting/Generic/IWootingRGBDevice.cs @@ -7,6 +7,6 @@ namespace RGB.NET.Devices.Wooting.Generic /// internal interface IWootingRGBDevice : IRGBDevice { - void Initialize(UpdateQueue updateQueue); + void Initialize(IDeviceUpdateTrigger updateTrigger); } } diff --git a/RGB.NET.Devices.Wooting/Generic/WootingRGBDevice.cs b/RGB.NET.Devices.Wooting/Generic/WootingRGBDevice.cs index 6fd6af7..7647a3d 100644 --- a/RGB.NET.Devices.Wooting/Generic/WootingRGBDevice.cs +++ b/RGB.NET.Devices.Wooting/Generic/WootingRGBDevice.cs @@ -1,8 +1,5 @@ -using System; -using System.Collections.Generic; -using System.Linq; +using System.Linq; using RGB.NET.Core; -using RGB.NET.Devices.Wooting.Native; namespace RGB.NET.Devices.Wooting.Generic { @@ -44,11 +41,11 @@ namespace RGB.NET.Devices.Wooting.Generic #endregion #region Methods - + /// /// Initializes the device. /// - public void Initialize(UpdateQueue updateQueue) + public void Initialize(IDeviceUpdateTrigger updateTrigger) { InitializeLayout(); @@ -58,7 +55,7 @@ namespace RGB.NET.Devices.Wooting.Generic Size = ledRectangle.Size + new Size(ledRectangle.Location.X, ledRectangle.Location.Y); } - UpdateQueue = updateQueue; + UpdateQueue = new WootingUpdateQueue(updateTrigger); } /// diff --git a/RGB.NET.Devices.Wooting/Generic/WootingUpdateQueue.cs b/RGB.NET.Devices.Wooting/Generic/WootingUpdateQueue.cs new file mode 100644 index 0000000..8342768 --- /dev/null +++ b/RGB.NET.Devices.Wooting/Generic/WootingUpdateQueue.cs @@ -0,0 +1,42 @@ +using System.Collections.Generic; +using RGB.NET.Core; +using RGB.NET.Devices.Wooting.Native; + +namespace RGB.NET.Devices.Wooting.Generic +{ + /// + /// + /// Represents the update-queue performing updates for cooler master devices. + /// + public class WootingUpdateQueue : UpdateQueue + { + #region Constructors + + /// + /// Initializes a new instance of the class. + /// + /// The update trigger used by this queue. + public WootingUpdateQueue(IDeviceUpdateTrigger updateTrigger) + : base(updateTrigger) + { + } + + #endregion + + #region Methods + + /// + protected override void Update(Dictionary dataSet) + { + foreach (KeyValuePair data in dataSet) + { + (int row, int column) = ((int, int))data.Key; + _WootingSDK.ArraySetSingle((byte)row, (byte)column, data.Value.GetR(), data.Value.GetG(), data.Value.GetB()); + } + + _WootingSDK.ArrayUpdateKeyboard(); + } + + #endregion + } +} diff --git a/RGB.NET.Devices.Wooting/Keyboard/WootingKeyboardLedMappings.cs b/RGB.NET.Devices.Wooting/Keyboard/WootingKeyboardLedMappings.cs index ebc62d3..8993654 100644 --- a/RGB.NET.Devices.Wooting/Keyboard/WootingKeyboardLedMappings.cs +++ b/RGB.NET.Devices.Wooting/Keyboard/WootingKeyboardLedMappings.cs @@ -245,14 +245,14 @@ namespace RGB.NET.Devices.Wooting.Keyboard { WootingDevicesIndexes.WootingOne, new Dictionary> { { WootingPhysicalKeyboardLayout.US, WootingOne_US }, - { WootingPhysicalKeyboardLayout.EU, WootingOne_US } + { WootingPhysicalKeyboardLayout.UK, WootingOne_US } } }, { WootingDevicesIndexes.WootingTwo, new Dictionary> { { WootingPhysicalKeyboardLayout.US, WootingTwo_US }, - { WootingPhysicalKeyboardLayout.EU, WootingTwo_US } + { WootingPhysicalKeyboardLayout.UK, WootingTwo_US } } } }; diff --git a/RGB.NET.Devices.Wooting/Keyboard/WootingKeyboardRGBDeviceInfo.cs b/RGB.NET.Devices.Wooting/Keyboard/WootingKeyboardRGBDeviceInfo.cs index f7806f0..3df72f8 100644 --- a/RGB.NET.Devices.Wooting/Keyboard/WootingKeyboardRGBDeviceInfo.cs +++ b/RGB.NET.Devices.Wooting/Keyboard/WootingKeyboardRGBDeviceInfo.cs @@ -40,14 +40,13 @@ namespace RGB.NET.Devices.Wooting.Keyboard { this.PhysicalLayout = physicalKeyboardLayout; - // For now just go for this switch (physicalKeyboardLayout) { case WootingPhysicalKeyboardLayout.US: this.LogicalLayout = WootingLogicalKeyboardLayout.US; break; - case WootingPhysicalKeyboardLayout.EU: - this.LogicalLayout = WootingLogicalKeyboardLayout.EU; + case WootingPhysicalKeyboardLayout.UK: + this.LogicalLayout = WootingLogicalKeyboardLayout.UK; break; } } diff --git a/RGB.NET.Devices.Wooting/WootingDeviceProvider.cs b/RGB.NET.Devices.Wooting/WootingDeviceProvider.cs index 417b967..dbcb883 100644 --- a/RGB.NET.Devices.Wooting/WootingDeviceProvider.cs +++ b/RGB.NET.Devices.Wooting/WootingDeviceProvider.cs @@ -2,6 +2,9 @@ using System.Collections.Generic; using System.Collections.ObjectModel; using RGB.NET.Core; +using RGB.NET.Devices.Wooting.Enum; +using RGB.NET.Devices.Wooting.Generic; +using RGB.NET.Devices.Wooting.Keyboard; using RGB.NET.Devices.Wooting.Native; namespace RGB.NET.Devices.Wooting @@ -24,13 +27,13 @@ namespace RGB.NET.Devices.Wooting /// Gets a modifiable list of paths used to find the native SDK-dlls for x86 applications. /// The first match will be used. /// - public static List PossibleX86NativePaths { get; } = new List { "x86/wooting-rgb-sdk.dll" }; + public static List PossibleX86NativePaths { get; } = new List {"x86/wooting-rgb-sdk.dll"}; /// /// Gets a modifiable list of paths used to find the native SDK-dlls for x64 applications. /// The first match will be used. /// - public static List PossibleX64NativePaths { get; } = new List { "x64/wooting-rgb-sdk64.dll" }; + public static List PossibleX64NativePaths { get; } = new List {"x64/wooting-rgb-sdk64.dll"}; /// /// @@ -52,6 +55,11 @@ namespace RGB.NET.Devices.Wooting /// public IEnumerable Devices { get; private set; } + /// + /// The used to trigger the updates for cooler master devices. + /// + public DeviceUpdateTrigger UpdateTrigger { get; private set; } + #endregion #region Constructors @@ -62,8 +70,11 @@ namespace RGB.NET.Devices.Wooting /// Thrown if this constructor is called even if there is already an instance of this class. public WootingDeviceProvider() { - if (_instance != null) throw new InvalidOperationException($"There can be only one instance of type {nameof(WootingDeviceProvider)}"); + if (_instance != null) + throw new InvalidOperationException($"There can be only one instance of type {nameof(WootingDeviceProvider)}"); _instance = this; + + UpdateTrigger = new DeviceUpdateTrigger(); } #endregion @@ -72,26 +83,45 @@ namespace RGB.NET.Devices.Wooting /// /// Thrown if the SDK failed to initialize - public bool Initialize(RGBDeviceType loadFilter = RGBDeviceType.All, bool exclusiveAccessIfPossible = false, bool throwExceptions = false) + public bool Initialize(RGBDeviceType loadFilter = RGBDeviceType.All, bool exclusiveAccessIfPossible = false, + bool throwExceptions = false) { IsInitialized = false; try { + UpdateTrigger?.Stop(); + _WootingSDK.Reload(); IList devices = new List(); if (_WootingSDK.KeyboardConnected()) { - if (_WootingSDK.IsWootingOne()) + IWootingRGBDevice device; + // TODO: Find an accurate way to determine physical and logical layouts + if (_WootingSDK.IsWootingTwo()) { - - } - else if (_WootingSDK.IsWootingTwo()) - { - + device = new WootingKeyboardRGBDevice(new WootingKeyboardRGBDeviceInfo(WootingDevicesIndexes.WootingTwo, + WootingPhysicalKeyboardLayout.US, + CultureHelper.GetCurrentCulture())); } + else if (_WootingSDK.IsWootingOne()) + { + device = new WootingKeyboardRGBDevice(new WootingKeyboardRGBDeviceInfo(WootingDevicesIndexes.WootingOne, + WootingPhysicalKeyboardLayout.US, + CultureHelper.GetCurrentCulture())); + } + else + { + throw new RGBDeviceException("No supported Wooting keyboard connected"); + } + + device.Initialize(UpdateTrigger); + devices.Add(device); } + + UpdateTrigger?.Start(); + Devices = new ReadOnlyCollection(devices); IsInitialized = true; } @@ -112,7 +142,9 @@ namespace RGB.NET.Devices.Wooting public void Dispose() { try { _WootingSDK.Reset(); } - catch { /* Unlucky.. */} + catch + { /* Unlucky.. */ + } } #endregion From 866a672e67d1c041474ad2241fcda021bab1db17 Mon Sep 17 00:00:00 2001 From: Darth Affe Date: Sun, 15 Dec 2019 12:18:39 +0100 Subject: [PATCH 05/16] Added locks to TimerUpdateTrigger --- RGB.NET.Core/Update/TimerUpdateTrigger.cs | 33 ++++++++++++++--------- 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/RGB.NET.Core/Update/TimerUpdateTrigger.cs b/RGB.NET.Core/Update/TimerUpdateTrigger.cs index 996b86f..23eaa96 100644 --- a/RGB.NET.Core/Update/TimerUpdateTrigger.cs +++ b/RGB.NET.Core/Update/TimerUpdateTrigger.cs @@ -14,11 +14,13 @@ namespace RGB.NET.Core { #region Properties & Fields + private object _lock = new object(); + private CancellationTokenSource _updateTokenSource; private CancellationToken _updateToken; private Task _updateTask; private Stopwatch _sleepCounter; - + private double _updateFrequency = 1.0 / 30.0; /// /// Gets or sets the update-frequency in seconds. (Calculate by using '1.0 / updates per second') @@ -33,7 +35,7 @@ namespace RGB.NET.Core /// Gets the time it took the last update-loop cycle to run. /// public double LastUpdateTime { get; private set; } - + #endregion #region Constructors @@ -59,25 +61,32 @@ namespace RGB.NET.Core /// public void Start() { - if (_updateTask == null) + lock (_lock) { - _updateTokenSource?.Dispose(); - _updateTokenSource = new CancellationTokenSource(); - _updateTask = Task.Factory.StartNew(UpdateLoop, (_updateToken = _updateTokenSource.Token), TaskCreationOptions.LongRunning, TaskScheduler.Default); + if (_updateTask == null) + { + _updateTokenSource?.Dispose(); + _updateTokenSource = new CancellationTokenSource(); + _updateTask = Task.Factory.StartNew(UpdateLoop, (_updateToken = _updateTokenSource.Token), TaskCreationOptions.LongRunning, TaskScheduler.Default); + } } } /// /// Stops the trigger if running, causing it to stop performing updates. /// - public async void Stop() + public void Stop() { - if (_updateTask != null) + lock (_lock) { - _updateTokenSource.Cancel(); - await _updateTask; - _updateTask.Dispose(); - _updateTask = null; + if (_updateTask != null) + { + _updateTokenSource.Cancel(); + // ReSharper disable once MethodSupportsCancellation + _updateTask.Wait(); + _updateTask.Dispose(); + _updateTask = null; + } } } From 6a89222c34d22a752eca9e257b01298de93b61ea Mon Sep 17 00:00:00 2001 From: SpoinkyNL Date: Sun, 15 Dec 2019 22:52:30 +0100 Subject: [PATCH 06/16] Added ANSI layouts --- .../Enum/WootingLogicalKeyboardLayout.cs | 7 +- .../Enum/WootingPhysicalKeyboardLayout.cs | 3 + .../Keyboard/WootingKeyboardLedMappings.cs | 223 +++++++++++++++++- .../Keyboard/WootingKeyboardRGBDeviceInfo.cs | 29 ++- 4 files changed, 246 insertions(+), 16 deletions(-) diff --git a/RGB.NET.Devices.Wooting/Enum/WootingLogicalKeyboardLayout.cs b/RGB.NET.Devices.Wooting/Enum/WootingLogicalKeyboardLayout.cs index 59976fb..640bfee 100644 --- a/RGB.NET.Devices.Wooting/Enum/WootingLogicalKeyboardLayout.cs +++ b/RGB.NET.Devices.Wooting/Enum/WootingLogicalKeyboardLayout.cs @@ -8,9 +8,14 @@ namespace RGB.NET.Devices.Wooting.Enum /// /// Contains list of available logical layouts for cooler master keyboards. /// + /// + /// Based on what is available in the shop: https://wooting.store/collections/wooting-keyboards/products/wooting-two + /// public enum WootingLogicalKeyboardLayout { US = 0, - UK = 1 + UK = 1, + DE = 2, + ND = 3 }; } diff --git a/RGB.NET.Devices.Wooting/Enum/WootingPhysicalKeyboardLayout.cs b/RGB.NET.Devices.Wooting/Enum/WootingPhysicalKeyboardLayout.cs index 2b37cbf..07d830f 100644 --- a/RGB.NET.Devices.Wooting/Enum/WootingPhysicalKeyboardLayout.cs +++ b/RGB.NET.Devices.Wooting/Enum/WootingPhysicalKeyboardLayout.cs @@ -8,6 +8,9 @@ namespace RGB.NET.Devices.Wooting.Enum /// /// Contains list of available physical layouts for Wooting keyboards. /// + /// + /// Shop states ANSI (US) and ISO (UK/German/Nodics) - https://wooting.store/collections/wooting-keyboards/products/wooting-two + /// public enum WootingPhysicalKeyboardLayout { US = 0, diff --git a/RGB.NET.Devices.Wooting/Keyboard/WootingKeyboardLedMappings.cs b/RGB.NET.Devices.Wooting/Keyboard/WootingKeyboardLedMappings.cs index 8993654..2f032f6 100644 --- a/RGB.NET.Devices.Wooting/Keyboard/WootingKeyboardLedMappings.cs +++ b/RGB.NET.Devices.Wooting/Keyboard/WootingKeyboardLedMappings.cs @@ -32,7 +32,7 @@ namespace RGB.NET.Devices.Wooting.Keyboard { LedId.Keyboard_F12, (0,13) }, { LedId.Keyboard_PrintScreen, (0,14) }, { LedId.Keyboard_PauseBreak, (0,15) }, - { LedId.Keyboard_Custom1, (0,20) }, // TODO: Make sure it is not 0,16 + { LedId.Keyboard_Custom1, (0,20) }, { LedId.Keyboard_GraveAccentAndTilde, (1,0) }, { LedId.Keyboard_1, (1,1) }, @@ -85,7 +85,6 @@ namespace RGB.NET.Devices.Wooting.Keyboard { LedId.Keyboard_Enter, (3,13) }, { LedId.Keyboard_LeftShift, (4,0) }, - { LedId.Keyboard_NonUsBackslash, (4,1) }, { LedId.Keyboard_Z, (4,2) }, { LedId.Keyboard_X, (4,3) }, { LedId.Keyboard_C, (4,4) }, @@ -112,6 +111,104 @@ namespace RGB.NET.Devices.Wooting.Keyboard { LedId.Keyboard_ArrowRight, (5,16) } }; + private static readonly Dictionary WootingOne_UK = new Dictionary + { + { LedId.Keyboard_Escape, (0,0) }, + { LedId.Keyboard_F1, (0,2) }, + { LedId.Keyboard_F2, (0,3) }, + { LedId.Keyboard_F3, (0,4) }, + { LedId.Keyboard_F4, (0,5) }, + { LedId.Keyboard_F5, (0,6) }, + { LedId.Keyboard_F6, (0,7) }, + { LedId.Keyboard_F7, (0,8) }, + { LedId.Keyboard_F8, (0,9) }, + { LedId.Keyboard_F9, (0,10) }, + { LedId.Keyboard_F10, (0,11) }, + { LedId.Keyboard_F11, (0,12) }, + { LedId.Keyboard_F12, (0,13) }, + { LedId.Keyboard_PrintScreen, (0,14) }, + { LedId.Keyboard_PauseBreak, (0,15) }, + { LedId.Keyboard_Custom1, (0,20) }, + + { LedId.Keyboard_GraveAccentAndTilde, (1,0) }, + { LedId.Keyboard_1, (1,1) }, + { LedId.Keyboard_2, (1,2) }, + { LedId.Keyboard_3, (1,3) }, + { LedId.Keyboard_4, (1,4) }, + { LedId.Keyboard_5, (1,5) }, + { LedId.Keyboard_6, (1,6) }, + { LedId.Keyboard_7, (1,7) }, + { LedId.Keyboard_8, (1,8) }, + { LedId.Keyboard_9, (1,9) }, + { LedId.Keyboard_0, (1,10) }, + { LedId.Keyboard_MinusAndUnderscore, (1,11) }, + { LedId.Keyboard_EqualsAndPlus, (1,12) }, + { LedId.Keyboard_Backspace, (1,13) }, + { LedId.Keyboard_Insert, (1,14) }, + { LedId.Keyboard_Home, (1,15) }, + { LedId.Keyboard_PageUp, (1,16) }, + + { LedId.Keyboard_Tab, (2,0) }, + { LedId.Keyboard_Q, (2,1) }, + { LedId.Keyboard_W, (2,2) }, + { LedId.Keyboard_E, (2,3) }, + { LedId.Keyboard_R, (2,4) }, + { LedId.Keyboard_T, (2,5) }, + { LedId.Keyboard_Y, (2,6) }, + { LedId.Keyboard_U, (2,7) }, + { LedId.Keyboard_I, (2,8) }, + { LedId.Keyboard_O, (2,9) }, + { LedId.Keyboard_P, (2,10) }, + { LedId.Keyboard_BracketLeft, (2,11) }, + { LedId.Keyboard_BracketRight, (2,12) }, + { LedId.Keyboard_Backslash, (2,13) }, + { LedId.Keyboard_Delete, (2,14) }, + { LedId.Keyboard_End, (2,15) }, + { LedId.Keyboard_PageDown, (2,16) }, + + { LedId.Keyboard_CapsLock, (3,0) }, + { LedId.Keyboard_A, (3,1) }, + { LedId.Keyboard_S, (3,2) }, + { LedId.Keyboard_D, (3,3) }, + { LedId.Keyboard_F, (3,4) }, + { LedId.Keyboard_G, (3,5) }, + { LedId.Keyboard_H, (3,6) }, + { LedId.Keyboard_J, (3,7) }, + { LedId.Keyboard_K, (3,8) }, + { LedId.Keyboard_L, (3,9) }, + { LedId.Keyboard_SemicolonAndColon, (3,10) }, + { LedId.Keyboard_ApostropheAndDoubleQuote, (3,11) }, + { LedId.Keyboard_NonUsTilde, (3,11) }, + { LedId.Keyboard_Enter, (3,13) }, + + { LedId.Keyboard_LeftShift, (4,0) }, + { LedId.Keyboard_NonUsBackslash, (4,1) }, + { LedId.Keyboard_Z, (4,2) }, + { LedId.Keyboard_X, (4,3) }, + { LedId.Keyboard_C, (4,4) }, + { LedId.Keyboard_V, (4,5) }, + { LedId.Keyboard_B, (4,6) }, + { LedId.Keyboard_N, (4,7) }, + { LedId.Keyboard_M, (4,8) }, + { LedId.Keyboard_CommaAndLessThan, (4,9) }, + { LedId.Keyboard_PeriodAndBiggerThan, (4,10) }, + { LedId.Keyboard_SlashAndQuestionMark, (4,11) }, + { LedId.Keyboard_RightShift, (4,13) }, + { LedId.Keyboard_ArrowUp, (4,15) }, + + { LedId.Keyboard_LeftCtrl, (5,0) }, + { LedId.Keyboard_LeftGui, (5,1) }, + { LedId.Keyboard_LeftAlt, (5,2) }, + { LedId.Keyboard_Space, (5,6) }, + { LedId.Keyboard_RightAlt, (5,10) }, + { LedId.Keyboard_RightGui, (5,11) }, + { LedId.Keyboard_Application, (5,12) }, + { LedId.Keyboard_RightCtrl, (5,13) }, + { LedId.Keyboard_ArrowLeft, (5,14) }, + { LedId.Keyboard_ArrowDown, (5,15) }, + { LedId.Keyboard_ArrowRight, (5,16) } + }; + #endregion #region Wooting Two @@ -200,6 +297,124 @@ namespace RGB.NET.Devices.Wooting.Keyboard { LedId.Keyboard_Num5, (3,18) }, { LedId.Keyboard_Num6, (3,19) }, + { LedId.Keyboard_LeftShift, (4,0) }, + { LedId.Keyboard_Z, (4,2) }, + { LedId.Keyboard_X, (4,3) }, + { LedId.Keyboard_C, (4,4) }, + { LedId.Keyboard_V, (4,5) }, + { LedId.Keyboard_B, (4,6) }, + { LedId.Keyboard_N, (4,7) }, + { LedId.Keyboard_M, (4,8) }, + { LedId.Keyboard_CommaAndLessThan, (4,9) }, + { LedId.Keyboard_PeriodAndBiggerThan, (4,10) }, + { LedId.Keyboard_SlashAndQuestionMark, (4,11) }, + { LedId.Keyboard_RightShift, (4,13) }, + { LedId.Keyboard_ArrowUp, (4,15) }, + { LedId.Keyboard_Num1, (4,17) }, + { LedId.Keyboard_Num2, (4,18) }, + { LedId.Keyboard_Num3, (4,19) }, + { LedId.Keyboard_NumEnter, (4,20) }, + + { LedId.Keyboard_LeftCtrl, (5,0) }, + { LedId.Keyboard_LeftGui, (5,1) }, + { LedId.Keyboard_LeftAlt, (5,2) }, + { LedId.Keyboard_Space, (5,6) }, + { LedId.Keyboard_RightAlt, (5,10) }, + { LedId.Keyboard_RightGui, (5,11) }, + { LedId.Keyboard_Application, (5,12) }, + { LedId.Keyboard_RightCtrl, (5,13) }, + { LedId.Keyboard_ArrowLeft, (5,14) }, + { LedId.Keyboard_ArrowDown, (5,15) }, + { LedId.Keyboard_ArrowRight, (5,16) }, + { LedId.Keyboard_Num0, (5,18) }, + { LedId.Keyboard_NumPeriodAndDelete, (5,19) } + }; + + private static readonly Dictionary WootingTwo_UK = new Dictionary + { + { LedId.Keyboard_Escape, (0,0) }, + { LedId.Keyboard_F1, (0,2) }, + { LedId.Keyboard_F2, (0,3) }, + { LedId.Keyboard_F3, (0,4) }, + { LedId.Keyboard_F4, (0,5) }, + { LedId.Keyboard_F5, (0,6) }, + { LedId.Keyboard_F6, (0,7) }, + { LedId.Keyboard_F7, (0,8) }, + { LedId.Keyboard_F8, (0,9) }, + { LedId.Keyboard_F9, (0,10) }, + { LedId.Keyboard_F10, (0,11) }, + { LedId.Keyboard_F11, (0,12) }, + { LedId.Keyboard_F12, (0,13) }, + { LedId.Keyboard_PrintScreen, (0,14) }, + { LedId.Keyboard_PauseBreak, (0,15) }, + { LedId.Keyboard_ScrollLock, (0,16) }, + { LedId.Keyboard_Custom1, (0,17) }, + { LedId.Keyboard_Custom2, (0,18) }, + { LedId.Keyboard_Custom3, (0,19) }, + { LedId.Keyboard_Custom4, (0,20) }, + + { LedId.Keyboard_GraveAccentAndTilde, (1,0) }, + { LedId.Keyboard_1, (1,1) }, + { LedId.Keyboard_2, (1,2) }, + { LedId.Keyboard_3, (1,3) }, + { LedId.Keyboard_4, (1,4) }, + { LedId.Keyboard_5, (1,5) }, + { LedId.Keyboard_6, (1,6) }, + { LedId.Keyboard_7, (1,7) }, + { LedId.Keyboard_8, (1,8) }, + { LedId.Keyboard_9, (1,9) }, + { LedId.Keyboard_0, (1,10) }, + { LedId.Keyboard_MinusAndUnderscore, (1,11) }, + { LedId.Keyboard_EqualsAndPlus, (1,12) }, + { LedId.Keyboard_Backspace, (1,13) }, + { LedId.Keyboard_Insert, (1,14) }, + { LedId.Keyboard_Home, (1,15) }, + { LedId.Keyboard_PageUp, (1,16) }, + { LedId.Keyboard_NumLock, (1,17) }, + { LedId.Keyboard_NumSlash, (1,18) }, + { LedId.Keyboard_NumAsterisk, (1,19) }, + { LedId.Keyboard_NumMinus, (1,20) }, + + { LedId.Keyboard_Tab, (2,0) }, + { LedId.Keyboard_Q, (2,1) }, + { LedId.Keyboard_W, (2,2) }, + { LedId.Keyboard_E, (2,3) }, + { LedId.Keyboard_R, (2,4) }, + { LedId.Keyboard_T, (2,5) }, + { LedId.Keyboard_Y, (2,6) }, + { LedId.Keyboard_U, (2,7) }, + { LedId.Keyboard_I, (2,8) }, + { LedId.Keyboard_O, (2,9) }, + { LedId.Keyboard_P, (2,10) }, + { LedId.Keyboard_BracketLeft, (2,11) }, + { LedId.Keyboard_BracketRight, (2,12) }, + { LedId.Keyboard_Backslash, (2,13) }, + { LedId.Keyboard_Delete, (2,14) }, + { LedId.Keyboard_End, (2,15) }, + { LedId.Keyboard_PageDown, (2,16) }, + { LedId.Keyboard_Num7, (2,17) }, + { LedId.Keyboard_Num8, (2,18) }, + { LedId.Keyboard_Num9, (2,19) }, + { LedId.Keyboard_NumPlus, (2,20) }, + + { LedId.Keyboard_CapsLock, (3,0) }, + { LedId.Keyboard_A, (3,1) }, + { LedId.Keyboard_S, (3,2) }, + { LedId.Keyboard_D, (3,3) }, + { LedId.Keyboard_F, (3,4) }, + { LedId.Keyboard_G, (3,5) }, + { LedId.Keyboard_H, (3,6) }, + { LedId.Keyboard_J, (3,7) }, + { LedId.Keyboard_K, (3,8) }, + { LedId.Keyboard_L, (3,9) }, + { LedId.Keyboard_SemicolonAndColon, (3,10) }, + { LedId.Keyboard_ApostropheAndDoubleQuote, (3,11) }, + { LedId.Keyboard_NonUsTilde, (3,12) }, + { LedId.Keyboard_Enter, (3,13) }, + { LedId.Keyboard_Num4, (3,17) }, + { LedId.Keyboard_Num5, (3,18) }, + { LedId.Keyboard_Num6, (3,19) }, + { LedId.Keyboard_LeftShift, (4,0) }, { LedId.Keyboard_NonUsBackslash, (4,1) }, { LedId.Keyboard_Z, (4,2) }, @@ -245,14 +460,14 @@ namespace RGB.NET.Devices.Wooting.Keyboard { WootingDevicesIndexes.WootingOne, new Dictionary> { { WootingPhysicalKeyboardLayout.US, WootingOne_US }, - { WootingPhysicalKeyboardLayout.UK, WootingOne_US } + { WootingPhysicalKeyboardLayout.UK, WootingOne_UK } } }, { WootingDevicesIndexes.WootingTwo, new Dictionary> { { WootingPhysicalKeyboardLayout.US, WootingTwo_US }, - { WootingPhysicalKeyboardLayout.UK, WootingTwo_US } + { WootingPhysicalKeyboardLayout.UK, WootingTwo_UK } } } }; diff --git a/RGB.NET.Devices.Wooting/Keyboard/WootingKeyboardRGBDeviceInfo.cs b/RGB.NET.Devices.Wooting/Keyboard/WootingKeyboardRGBDeviceInfo.cs index 3df72f8..b2bcc70 100644 --- a/RGB.NET.Devices.Wooting/Keyboard/WootingKeyboardRGBDeviceInfo.cs +++ b/RGB.NET.Devices.Wooting/Keyboard/WootingKeyboardRGBDeviceInfo.cs @@ -1,5 +1,4 @@ -using System; -using System.Globalization; +using System.Globalization; using RGB.NET.Core; using RGB.NET.Devices.Wooting.Enum; using RGB.NET.Devices.Wooting.Generic; @@ -35,22 +34,30 @@ namespace RGB.NET.Devices.Wooting.Keyboard /// The index of the . /// The of the . /// The of the layout this keyboard is using - internal WootingKeyboardRGBDeviceInfo(WootingDevicesIndexes deviceIndex, WootingPhysicalKeyboardLayout physicalKeyboardLayout, CultureInfo culture) - : base(RGBDeviceType.Keyboard, deviceIndex) + internal WootingKeyboardRGBDeviceInfo(WootingDevicesIndexes deviceIndex, WootingPhysicalKeyboardLayout physicalKeyboardLayout, + CultureInfo culture) + : base(RGBDeviceType.Keyboard, deviceIndex) { this.PhysicalLayout = physicalKeyboardLayout; - switch (physicalKeyboardLayout) + DetermineLogicalLayout(culture.KeyboardLayoutId); + } + + private void DetermineLogicalLayout(int keyboardLayoutId) + { + switch (keyboardLayoutId) { - case WootingPhysicalKeyboardLayout.US: - this.LogicalLayout = WootingLogicalKeyboardLayout.US; - break; - case WootingPhysicalKeyboardLayout.UK: - this.LogicalLayout = WootingLogicalKeyboardLayout.UK; + // TODO SpoinkyNL 15-12-2019: There doesn't seem to be an accurate way to determine this, perhaps it should be a configurable thing.. + // I'm using US International and it's reporting nl-NL's 1043. Also you can after all just swap your keycaps + default: + if (PhysicalLayout == WootingPhysicalKeyboardLayout.US) + LogicalLayout = WootingLogicalKeyboardLayout.US; + else + LogicalLayout = WootingLogicalKeyboardLayout.UK; break; } } - + #endregion } } From 7f62fbc1c29f2c4d912ecbbff303056916cb2ddd Mon Sep 17 00:00:00 2001 From: Xeevis Date: Thu, 19 Dec 2019 00:06:21 +0100 Subject: [PATCH 07/16] Added Corsair M65 RGB Elite --- RGB.NET.Devices.Corsair/Mouse/CorsairMouseRGBDevice.cs | 2 ++ RGB.NET.Devices.Corsair/Mouse/MouseIdMapping.cs | 6 ++++++ 2 files changed, 8 insertions(+) diff --git a/RGB.NET.Devices.Corsair/Mouse/CorsairMouseRGBDevice.cs b/RGB.NET.Devices.Corsair/Mouse/CorsairMouseRGBDevice.cs index 6fcbffb..479b771 100644 --- a/RGB.NET.Devices.Corsair/Mouse/CorsairMouseRGBDevice.cs +++ b/RGB.NET.Devices.Corsair/Mouse/CorsairMouseRGBDevice.cs @@ -62,6 +62,8 @@ namespace RGB.NET.Devices.Corsair { if (string.Equals(DeviceInfo.Model, "GLAIVE RGB", StringComparison.OrdinalIgnoreCase)) return MouseIdMapping.GLAIVE.TryGetValue(ledId, out CorsairLedId id) ? id : CorsairLedId.Invalid; + else if (string.Equals(DeviceInfo.Model, "M65 RGB ELITE", StringComparison.OrdinalIgnoreCase)) + return MouseIdMapping.M65_RGB_ELITE.TryGetValue(ledId, out CorsairLedId id) ? id : CorsairLedId.Invalid; else return MouseIdMapping.DEFAULT.TryGetValue(ledId, out CorsairLedId id) ? id : CorsairLedId.Invalid; } diff --git a/RGB.NET.Devices.Corsair/Mouse/MouseIdMapping.cs b/RGB.NET.Devices.Corsair/Mouse/MouseIdMapping.cs index f01ac58..00dea5b 100644 --- a/RGB.NET.Devices.Corsair/Mouse/MouseIdMapping.cs +++ b/RGB.NET.Devices.Corsair/Mouse/MouseIdMapping.cs @@ -21,5 +21,11 @@ namespace RGB.NET.Devices.Corsair { LedId.Mouse2, CorsairLedId.B2 }, { LedId.Mouse3, CorsairLedId.B5 }, }; + + internal static readonly Dictionary M65_RGB_ELITE = new Dictionary + { + { LedId.Mouse1, CorsairLedId.B1 }, + { LedId.Mouse2, CorsairLedId.B3 }, + }; } } From 6ba50ba88ed1343d13eab8174ba447b39d83af31 Mon Sep 17 00:00:00 2001 From: Felix Lehmann Date: Thu, 21 Nov 2019 23:28:28 +0100 Subject: [PATCH 08/16] g910v2 --- RGB.NET.Devices.Logitech/HID/DeviceChecker.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/RGB.NET.Devices.Logitech/HID/DeviceChecker.cs b/RGB.NET.Devices.Logitech/HID/DeviceChecker.cs index db8209d..e58b99a 100644 --- a/RGB.NET.Devices.Logitech/HID/DeviceChecker.cs +++ b/RGB.NET.Devices.Logitech/HID/DeviceChecker.cs @@ -17,6 +17,7 @@ namespace RGB.NET.Devices.Logitech.HID = new List<(string model, RGBDeviceType deviceType, int id, int zones, string imageLayout, string layoutPath)> { ("G910", RGBDeviceType.Keyboard, 0xC32B, 0, "DE", @"Keyboards\G910\UK"), //TODO DarthAffe 15.11.2017: Somehow detect the current layout + ("G910v2", RGBDeviceType.Keyboard, 0xC335, 0, "DE", @"Keyboards\G910\UK"), ("G810", RGBDeviceType.Keyboard, 0xC337, 0, "DE", @"Keyboards\G810\UK"), ("G610", RGBDeviceType.Keyboard, 0xC333, 0, "DE", @"Keyboards\G610\UK"), ("G410", RGBDeviceType.Keyboard, 0xC330, 0, "DE", @"Keyboards\G410\UK"), From 1bdbc7b021181c495603d6ef99f57543207db1a0 Mon Sep 17 00:00:00 2001 From: SpoinkyNL Date: Tue, 28 Jan 2020 19:43:15 +0100 Subject: [PATCH 09/16] Updated for official v1.1.0 Wooting SDK --- .../Enum/WootingDeviceType.cs | 11 ++++++++++ .../Native/_WootingDeviceInfo.cs | 21 +++++++++++++++++++ RGB.NET.Devices.Wooting/Native/_WootingSDK.cs | 18 ++++++---------- .../WootingDeviceProvider.cs | 6 ++++-- 4 files changed, 42 insertions(+), 14 deletions(-) create mode 100644 RGB.NET.Devices.Wooting/Enum/WootingDeviceType.cs create mode 100644 RGB.NET.Devices.Wooting/Native/_WootingDeviceInfo.cs diff --git a/RGB.NET.Devices.Wooting/Enum/WootingDeviceType.cs b/RGB.NET.Devices.Wooting/Enum/WootingDeviceType.cs new file mode 100644 index 0000000..86f79cf --- /dev/null +++ b/RGB.NET.Devices.Wooting/Enum/WootingDeviceType.cs @@ -0,0 +1,11 @@ +namespace RGB.NET.Devices.Wooting.Enum +{ + public enum WootingDeviceType + { + /// 10 Keyless Keyboard. E.g. Wooting One + KeyboardTKL = 1, + + /// Full Size keyboard. E.g. Wooting Two + Keyboard = 2 + } +} diff --git a/RGB.NET.Devices.Wooting/Native/_WootingDeviceInfo.cs b/RGB.NET.Devices.Wooting/Native/_WootingDeviceInfo.cs new file mode 100644 index 0000000..5855a7b --- /dev/null +++ b/RGB.NET.Devices.Wooting/Native/_WootingDeviceInfo.cs @@ -0,0 +1,21 @@ +using System.Runtime.InteropServices; +using RGB.NET.Devices.Wooting.Enum; + +namespace RGB.NET.Devices.Wooting.Native +{ + [StructLayout(LayoutKind.Sequential)] + public struct _WootingDeviceInfo + { + public bool Connected { get; private set; } + + public string Model { get; private set; } + + public byte MaxRows { get; private set; } + + public byte MaxColumns { get; private set; } + + public byte KeycodeLimit { get; private set; } + + public WootingDeviceType DeviceType { get; private set; } + } +} diff --git a/RGB.NET.Devices.Wooting/Native/_WootingSDK.cs b/RGB.NET.Devices.Wooting/Native/_WootingSDK.cs index 402f6f4..a9017f3 100644 --- a/RGB.NET.Devices.Wooting/Native/_WootingSDK.cs +++ b/RGB.NET.Devices.Wooting/Native/_WootingSDK.cs @@ -45,8 +45,7 @@ namespace RGB.NET.Devices.Wooting.Native _dllHandle = LoadLibrary(dllPath); - _isWootingOnePointer = (IsWootingOnePointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "wooting_rgb_kbd_is_wooting_one"), typeof(IsWootingOnePointer)); - _isWootingTwoPointer = (IsWootingTwoPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "wooting_rgb_kbd_is_wooting_two"), typeof(IsWootingTwoPointer)); + _getDeviceInfoPointer = (GetDeviceInfoPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "wooting_rgb_device_info"), typeof(GetDeviceInfoPointer)); _keyboardConnectedPointer = (KeyboardConnectedPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "wooting_rgb_kbd_connected"), typeof(KeyboardConnectedPointer)); _resetPointer = (ResetPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "wooting_rgb_reset"), typeof(ResetPointer)); _arrayUpdateKeyboardPointer = (ArrayUpdateKeyboardPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "wooting_rgb_array_update_keyboard"), typeof(ArrayUpdateKeyboardPointer)); @@ -80,8 +79,7 @@ namespace RGB.NET.Devices.Wooting.Native #region Pointers - private static IsWootingOnePointer _isWootingOnePointer; - private static IsWootingTwoPointer _isWootingTwoPointer; + private static GetDeviceInfoPointer _getDeviceInfoPointer; private static KeyboardConnectedPointer _keyboardConnectedPointer; private static ResetPointer _resetPointer; private static ArrayUpdateKeyboardPointer _arrayUpdateKeyboardPointer; @@ -92,11 +90,8 @@ namespace RGB.NET.Devices.Wooting.Native #region Delegates [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - private delegate bool IsWootingOnePointer(); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - private delegate bool IsWootingTwoPointer(); - + private delegate IntPtr GetDeviceInfoPointer(); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] private delegate bool KeyboardConnectedPointer(); @@ -108,11 +103,10 @@ namespace RGB.NET.Devices.Wooting.Native [UnmanagedFunctionPointer(CallingConvention.Cdecl)] private delegate bool ArraySetSinglePointer(byte row, byte column, byte red, byte green, byte blue); - + #endregion - internal static bool IsWootingOne() => _isWootingOnePointer(); - internal static bool IsWootingTwo() => _isWootingTwoPointer(); + internal static IntPtr GetDeviceInfo() => _getDeviceInfoPointer(); internal static bool KeyboardConnected() => _keyboardConnectedPointer(); internal static bool Reset() => _resetPointer(); internal static bool ArrayUpdateKeyboard() => _arrayUpdateKeyboardPointer(); diff --git a/RGB.NET.Devices.Wooting/WootingDeviceProvider.cs b/RGB.NET.Devices.Wooting/WootingDeviceProvider.cs index dbcb883..5a1113c 100644 --- a/RGB.NET.Devices.Wooting/WootingDeviceProvider.cs +++ b/RGB.NET.Devices.Wooting/WootingDeviceProvider.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Collections.ObjectModel; +using System.Runtime.InteropServices; using RGB.NET.Core; using RGB.NET.Devices.Wooting.Enum; using RGB.NET.Devices.Wooting.Generic; @@ -97,15 +98,16 @@ namespace RGB.NET.Devices.Wooting IList devices = new List(); if (_WootingSDK.KeyboardConnected()) { + _WootingDeviceInfo nativeDeviceInfo = (_WootingDeviceInfo)Marshal.PtrToStructure(_WootingSDK.GetDeviceInfo(), typeof(_WootingDeviceInfo)); IWootingRGBDevice device; // TODO: Find an accurate way to determine physical and logical layouts - if (_WootingSDK.IsWootingTwo()) + if (nativeDeviceInfo.Model == "Wooting two") { device = new WootingKeyboardRGBDevice(new WootingKeyboardRGBDeviceInfo(WootingDevicesIndexes.WootingTwo, WootingPhysicalKeyboardLayout.US, CultureHelper.GetCurrentCulture())); } - else if (_WootingSDK.IsWootingOne()) + else if (nativeDeviceInfo.Model == "Wooting one") { device = new WootingKeyboardRGBDevice(new WootingKeyboardRGBDeviceInfo(WootingDevicesIndexes.WootingOne, WootingPhysicalKeyboardLayout.US, From ddbf00d894a8fbc2d2535f3c67528777bd6f0550 Mon Sep 17 00:00:00 2001 From: Darth Affe Date: Tue, 11 Feb 2020 18:46:26 +0100 Subject: [PATCH 10/16] Added logitech HIDs. Resolves #104 --- RGB.NET.Devices.Logitech/HID/DeviceChecker.cs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/RGB.NET.Devices.Logitech/HID/DeviceChecker.cs b/RGB.NET.Devices.Logitech/HID/DeviceChecker.cs index e58b99a..5ec7a69 100644 --- a/RGB.NET.Devices.Logitech/HID/DeviceChecker.cs +++ b/RGB.NET.Devices.Logitech/HID/DeviceChecker.cs @@ -20,6 +20,7 @@ namespace RGB.NET.Devices.Logitech.HID ("G910v2", RGBDeviceType.Keyboard, 0xC335, 0, "DE", @"Keyboards\G910\UK"), ("G810", RGBDeviceType.Keyboard, 0xC337, 0, "DE", @"Keyboards\G810\UK"), ("G610", RGBDeviceType.Keyboard, 0xC333, 0, "DE", @"Keyboards\G610\UK"), + ("G512", RGBDeviceType.Keyboard, 0xC33C, 0, "DE", @"Keyboards\G512\UK"), ("G410", RGBDeviceType.Keyboard, 0xC330, 0, "DE", @"Keyboards\G410\UK"), ("G213", RGBDeviceType.Keyboard, 0xC336, 0, "DE", @"Keyboards\G213\UK"), ("Pro", RGBDeviceType.Keyboard, 0xC339, 0, "DE", @"Keyboards\Pro\UK"), @@ -30,8 +31,6 @@ namespace RGB.NET.Devices.Logitech.HID { ("G19", RGBDeviceType.Keyboard, 0xC228, 0, "DE", @"Keyboards\G19\UK"), ("G19s", RGBDeviceType.Keyboard, 0xC229, 0, "DE", @"Keyboards\G19s\UK"), - ("G502", RGBDeviceType.Mouse, 0xC332, 0, "default", @"Mice\G502"), - ("G502 HERO", RGBDeviceType.Mouse, 0xC08B, 0, "default", @"Mice\G502"), ("G600", RGBDeviceType.Mouse, 0xC24A, 0, "default", @"Mice\G600"), ("G300s", RGBDeviceType.Mouse, 0xC246, 0, "default", @"Mice\G300s"), ("G510", RGBDeviceType.Keyboard, 0xC22D, 0, "DE", @"Keyboards\G510\UK"), @@ -47,15 +46,19 @@ namespace RGB.NET.Devices.Logitech.HID private static readonly List<(string model, RGBDeviceType deviceType, int id, int zones, string imageLayout, string layoutPath)> ZONE_DEVICES = new List<(string model, RGBDeviceType deviceType, int id, int zones, string imageLayout, string layoutPath)> { + ("G213", RGBDeviceType.Keyboard, 0xC336, 5, "default", @"Keyboards\G213"), ("G903", RGBDeviceType.Mouse, 0xC086, 2, "default", @"Mice\G903"), ("G900", RGBDeviceType.Mouse, 0xC539, 2, "default", @"Mice\G900"), ("G703", RGBDeviceType.Mouse, 0xC087, 2, "default", @"Mice\G703"), + ("G502 HERO", RGBDeviceType.Mouse, 0xC08B, 2, "default", @"Mice\G502"), + ("G502", RGBDeviceType.Mouse, 0xC332, 2, "default", @"Mice\G502"), ("G403", RGBDeviceType.Mouse, 0xC083, 2, "default", @"Mice\G403"), ("G303", RGBDeviceType.Mouse, 0xC080, 2, "default", @"Mice\G303"), ("G203", RGBDeviceType.Mouse, 0xC084, 1, "default", @"Mice\G203"), ("G Pro", RGBDeviceType.Mouse, 0xC085, 1, "default", @"Mice\GPro"), ("G633", RGBDeviceType.Headset, 0x0A5C, 2, "default", @"Headsets\G633"), ("G933", RGBDeviceType.Headset, 0x0A5B, 2, "default", @"Headsets\G933"), + ("G935", RGBDeviceType.Headset, 0x0A87, 2, "default", @"Headsets\G935"), ("G560", RGBDeviceType.Speaker, 0x0A78, 4, "default", @"Speakers\G560"), }; From b92f121379bee5b51ecdf56bf1cc38c4f7a22d89 Mon Sep 17 00:00:00 2001 From: Hex3l Date: Sat, 15 Feb 2020 17:28:08 +0100 Subject: [PATCH 11/16] Adds support to MSI_MB device (motherboard) --- .../Mainboard/MsiMainboardRGBDevice.cs | 68 +++++++++++++++++++ RGB.NET.Devices.Msi/MsiDeviceProvider.cs | 10 +++ 2 files changed, 78 insertions(+) create mode 100644 RGB.NET.Devices.Msi/Mainboard/MsiMainboardRGBDevice.cs diff --git a/RGB.NET.Devices.Msi/Mainboard/MsiMainboardRGBDevice.cs b/RGB.NET.Devices.Msi/Mainboard/MsiMainboardRGBDevice.cs new file mode 100644 index 0000000..7901ffb --- /dev/null +++ b/RGB.NET.Devices.Msi/Mainboard/MsiMainboardRGBDevice.cs @@ -0,0 +1,68 @@ +using System; +using RGB.NET.Core; +using RGB.NET.Devices.Msi.Native; +using RGB.NET.Devices.Msi.Exceptions; + +namespace RGB.NET.Devices.Msi +{ + /// + /// + /// Represents a Msi mainboard. + /// + public class MsiMainboardRGBDevice : MsiRGBDevice + { + #region Constructors + + /// + /// + /// Initializes a new instance of the class. + /// + /// The specific information provided by Asus for the mainboard. + internal MsiMainboardRGBDevice(MsiRGBDeviceInfo info) + : base(info) + { } + + #endregion + + #region Methods + + /// + protected override void InitializeLayout() + { + // Should errors be handled? + _MsiSDK.GetDeviceInfo(out string[] deviceTypes, out int[] ledCounts); + + for (int i = 0; i < deviceTypes.Length; i++) + { + // DeviceInfo.MsiDeviceType = "MSI_MB" + if (deviceTypes[i].Equals(DeviceInfo.MsiDeviceType)) + { + for (int j = 0; j < ledCounts[i]; j++) + { + // Should it be configurable in order to provide style access? + // Sets led style to "Steady" in order to have a solid color output therefore a controllable led color + // This is a string defined by the output of _MsiSDK.GetLedStyle, "Steady" should be always present + string style = "Steady"; + + _MsiSDK.SetLedStyle(DeviceInfo.MsiDeviceType, j, style); + InitializeLed(LedId.Mainboard1 + j, new Rectangle(j * 40, 0, 40, 8)); + } + } + } + + //TODO DarthAffe 07.10.2017: We don't know the model, how to save layouts and images? + ApplyLayoutFromFile(PathHelper.GetAbsolutePath($@"Layouts\Asus\Mainboards\{DeviceInfo.Model.Replace(" ", string.Empty).ToUpper()}.xml"), null); + } + + /// + protected override object CreateLedCustomData(LedId ledId) => (int)ledId - (int)LedId.Mainboard1; + + /// + public override void SyncBack() + { } + + /// + + #endregion + } +} diff --git a/RGB.NET.Devices.Msi/MsiDeviceProvider.cs b/RGB.NET.Devices.Msi/MsiDeviceProvider.cs index 2eba9a0..2d1e377 100644 --- a/RGB.NET.Devices.Msi/MsiDeviceProvider.cs +++ b/RGB.NET.Devices.Msi/MsiDeviceProvider.cs @@ -103,6 +103,16 @@ namespace RGB.NET.Devices.Msi try { //TODO DarthAffe 11.11.2017: What is this deviceType? Find someone to try that out + + // MSI_MB provide access to the motherboard "leds" where a led must be intended as a led header (JRGB, JRAINBOW etc..) (Tested on MSI X570 Unify) + if (deviceTypes[i].Equals("MSI_MB")) + { + IMsiRGBDevice motherboard = new MsiMainboardRGBDevice(new MsiRGBDeviceInfo(RGBDeviceType.Mainboard, deviceTypes[i], "Msi", "Motherboard")); + motherboard.Initialize(); + devices.Add(motherboard); + } + + // Other devices? } catch { if (throwExceptions) throw; } } From 18887a048efa90f4c77f225e025b64e2174e9128 Mon Sep 17 00:00:00 2001 From: Darth Affe Date: Sat, 22 Feb 2020 15:59:22 +0100 Subject: [PATCH 12/16] Refactored MSI --- RGB.NET.Devices.Msi/Generic/IMsiRGBDevice.cs | 4 +- .../Generic/MsiDeviceUpdateQueue.cs | 45 +++++++++++++++++++ RGB.NET.Devices.Msi/Generic/MsiRGBDevice.cs | 26 +++++------ .../Generic/MsiRGBDeviceInfo.cs | 2 +- .../Mainboard/MsiMainboardRGBDevice.cs | 24 +++++----- RGB.NET.Devices.Msi/MsiDeviceProvider.cs | 30 ++++++++----- .../MsiDeviceProviderLoader.cs | 2 +- .../RGB.NET.Devices.Msi.csproj.DotSettings | 3 +- 8 files changed, 93 insertions(+), 43 deletions(-) create mode 100644 RGB.NET.Devices.Msi/Generic/MsiDeviceUpdateQueue.cs diff --git a/RGB.NET.Devices.Msi/Generic/IMsiRGBDevice.cs b/RGB.NET.Devices.Msi/Generic/IMsiRGBDevice.cs index f8b35a8..13caa17 100644 --- a/RGB.NET.Devices.Msi/Generic/IMsiRGBDevice.cs +++ b/RGB.NET.Devices.Msi/Generic/IMsiRGBDevice.cs @@ -3,10 +3,10 @@ namespace RGB.NET.Devices.Msi { /// - /// Represents a msi RGB-device. + /// Represents a MSI RGB-device. /// internal interface IMsiRGBDevice : IRGBDevice { - void Initialize(); + void Initialize(MsiDeviceUpdateQueue updateQueue); } } diff --git a/RGB.NET.Devices.Msi/Generic/MsiDeviceUpdateQueue.cs b/RGB.NET.Devices.Msi/Generic/MsiDeviceUpdateQueue.cs new file mode 100644 index 0000000..b2dffc0 --- /dev/null +++ b/RGB.NET.Devices.Msi/Generic/MsiDeviceUpdateQueue.cs @@ -0,0 +1,45 @@ +using System.Collections.Generic; +using RGB.NET.Core; +using RGB.NET.Devices.Msi.Native; + +namespace RGB.NET.Devices.Msi +{ + /// + /// + /// Represents the update-queue performing updates for MSI devices. + /// + public class MsiDeviceUpdateQueue : UpdateQueue + { + #region Properties & Fields + + private string _deviceType; + + #endregion + + #region Constructors + + /// + /// Initializes a new instance of the class. + /// + /// The update trigger used by this queue. + /// The device-type used to identify the device. + public MsiDeviceUpdateQueue(IDeviceUpdateTrigger updateTrigger, string deviceType) + : base(updateTrigger) + { + this._deviceType = deviceType; + } + + #endregion + + #region Methods + + /// + protected override void Update(Dictionary dataSet) + { + foreach (KeyValuePair data in dataSet) + _MsiSDK.SetLedColor(_deviceType, (int)data.Key, data.Value.GetR(), data.Value.GetG(), data.Value.GetB()); + } + + #endregion + } +} diff --git a/RGB.NET.Devices.Msi/Generic/MsiRGBDevice.cs b/RGB.NET.Devices.Msi/Generic/MsiRGBDevice.cs index 5fe18ab..6c83ad0 100644 --- a/RGB.NET.Devices.Msi/Generic/MsiRGBDevice.cs +++ b/RGB.NET.Devices.Msi/Generic/MsiRGBDevice.cs @@ -1,14 +1,13 @@ using System.Collections.Generic; using System.Linq; using RGB.NET.Core; -using RGB.NET.Devices.Msi.Native; namespace RGB.NET.Devices.Msi { /// /// /// - /// Represents a generic Msi-device. (keyboard, mouse, headset, mousepad). + /// Represents a generic MSI-device. (keyboard, mouse, headset, mousepad). /// public abstract class MsiRGBDevice : AbstractRGBDevice, IMsiRGBDevice where TDeviceInfo : MsiRGBDeviceInfo @@ -21,6 +20,12 @@ namespace RGB.NET.Devices.Msi /// public override TDeviceInfo DeviceInfo { get; } + /// + /// Gets or sets the update queue performing updates for this device. + /// + // ReSharper disable once MemberCanBePrivate.Global + protected MsiDeviceUpdateQueue DeviceUpdateQueue { get; set; } + #endregion #region Constructors @@ -28,7 +33,7 @@ namespace RGB.NET.Devices.Msi /// /// Initializes a new instance of the class. /// - /// The generic information provided by Msi for the device. + /// The generic information provided by MSI for the device. protected MsiRGBDevice(TDeviceInfo info) { this.DeviceInfo = info; @@ -41,8 +46,10 @@ namespace RGB.NET.Devices.Msi /// /// Initializes the device. /// - public void Initialize() + public void Initialize(MsiDeviceUpdateQueue updateQueue) { + DeviceUpdateQueue = updateQueue; + InitializeLayout(); if (Size == Size.Invalid) @@ -59,16 +66,7 @@ namespace RGB.NET.Devices.Msi /// protected override void UpdateLeds(IEnumerable ledsToUpdate) - { - List leds = ledsToUpdate.Where(x => x.Color.A > 0).ToList(); - - if (leds.Count > 0) - { - string deviceType = DeviceInfo.MsiDeviceType; - foreach (Led led in leds) - _MsiSDK.SetLedColor(deviceType, (int)led.CustomData, led.Color.GetR(), led.Color.GetG(), led.Color.GetB()); - } - } + => DeviceUpdateQueue.SetData(ledsToUpdate.Where(x => (x.Color.A > 0) && (x.CustomData is int))); #endregion } diff --git a/RGB.NET.Devices.Msi/Generic/MsiRGBDeviceInfo.cs b/RGB.NET.Devices.Msi/Generic/MsiRGBDeviceInfo.cs index 1d8e942..d846266 100644 --- a/RGB.NET.Devices.Msi/Generic/MsiRGBDeviceInfo.cs +++ b/RGB.NET.Devices.Msi/Generic/MsiRGBDeviceInfo.cs @@ -5,7 +5,7 @@ namespace RGB.NET.Devices.Msi { /// /// - /// Represents a generic information for a Corsair-. + /// Represents a generic information for a MSI-. /// public class MsiRGBDeviceInfo : IRGBDeviceInfo { diff --git a/RGB.NET.Devices.Msi/Mainboard/MsiMainboardRGBDevice.cs b/RGB.NET.Devices.Msi/Mainboard/MsiMainboardRGBDevice.cs index 7901ffb..afb4f98 100644 --- a/RGB.NET.Devices.Msi/Mainboard/MsiMainboardRGBDevice.cs +++ b/RGB.NET.Devices.Msi/Mainboard/MsiMainboardRGBDevice.cs @@ -1,13 +1,11 @@ -using System; using RGB.NET.Core; using RGB.NET.Devices.Msi.Native; -using RGB.NET.Devices.Msi.Exceptions; namespace RGB.NET.Devices.Msi { /// /// - /// Represents a Msi mainboard. + /// Represents a MSI mainboard. /// public class MsiMainboardRGBDevice : MsiRGBDevice { @@ -17,7 +15,7 @@ namespace RGB.NET.Devices.Msi /// /// Initializes a new instance of the class. /// - /// The specific information provided by Asus for the mainboard. + /// The specific information provided by MSI for the mainboard. internal MsiMainboardRGBDevice(MsiRGBDeviceInfo info) : base(info) { } @@ -29,7 +27,7 @@ namespace RGB.NET.Devices.Msi /// protected override void InitializeLayout() { - // Should errors be handled? + // Should errors be handled? _MsiSDK.GetDeviceInfo(out string[] deviceTypes, out int[] ledCounts); for (int i = 0; i < deviceTypes.Length; i++) @@ -39,30 +37,28 @@ namespace RGB.NET.Devices.Msi { for (int j = 0; j < ledCounts[i]; j++) { - // Should it be configurable in order to provide style access? - // Sets led style to "Steady" in order to have a solid color output therefore a controllable led color - // This is a string defined by the output of _MsiSDK.GetLedStyle, "Steady" should be always present - string style = "Steady"; + //Hex3l: Should it be configurable in order to provide style access? + //Hex3l: Sets led style to "Steady" in order to have a solid color output therefore a controllable led color + //Hex3l: This is a string defined by the output of _MsiSDK.GetLedStyle, "Steady" should be always present + const string LED_STYLE = "Steady"; - _MsiSDK.SetLedStyle(DeviceInfo.MsiDeviceType, j, style); + _MsiSDK.SetLedStyle(DeviceInfo.MsiDeviceType, j, LED_STYLE); InitializeLed(LedId.Mainboard1 + j, new Rectangle(j * 40, 0, 40, 8)); } } } //TODO DarthAffe 07.10.2017: We don't know the model, how to save layouts and images? - ApplyLayoutFromFile(PathHelper.GetAbsolutePath($@"Layouts\Asus\Mainboards\{DeviceInfo.Model.Replace(" ", string.Empty).ToUpper()}.xml"), null); + ApplyLayoutFromFile(PathHelper.GetAbsolutePath($@"Layouts\MSI\Mainboards\{DeviceInfo.Model.Replace(" ", string.Empty).ToUpper()}.xml"), null); } /// protected override object CreateLedCustomData(LedId ledId) => (int)ledId - (int)LedId.Mainboard1; /// - public override void SyncBack() + public override void SyncBack() { } - /// - #endregion } } diff --git a/RGB.NET.Devices.Msi/MsiDeviceProvider.cs b/RGB.NET.Devices.Msi/MsiDeviceProvider.cs index 2d1e377..f233857 100644 --- a/RGB.NET.Devices.Msi/MsiDeviceProvider.cs +++ b/RGB.NET.Devices.Msi/MsiDeviceProvider.cs @@ -13,7 +13,7 @@ namespace RGB.NET.Devices.Msi { /// /// - /// Represents a device provider responsible for Cooler Master devices. + /// Represents a device provider responsible for MSI devices. /// public class MsiDeviceProvider : IRGBDeviceProvider { @@ -62,6 +62,11 @@ namespace RGB.NET.Devices.Msi /// public Func GetCulture { get; set; } = CultureHelper.GetCurrentCulture; + /// + /// The used to trigger the updates for corsair devices. + /// + public DeviceUpdateTrigger UpdateTrigger { get; } + #endregion #region Constructors @@ -74,6 +79,8 @@ namespace RGB.NET.Devices.Msi { if (_instance != null) throw new InvalidOperationException($"There can be only one instance of type {nameof(MsiDeviceProvider)}"); _instance = this; + + UpdateTrigger = new DeviceUpdateTrigger(); } #endregion @@ -87,6 +94,8 @@ namespace RGB.NET.Devices.Msi try { + UpdateTrigger?.Stop(); + _MsiSDK.Reload(); IList devices = new List(); @@ -95,28 +104,29 @@ namespace RGB.NET.Devices.Msi if ((errorCode = _MsiSDK.Initialize()) != 0) ThrowMsiError(errorCode); - if ((errorCode = _MsiSDK.GetDeviceInfo(out string[] deviceTypes, out int[] ledCounts)) != 0) + if ((errorCode = _MsiSDK.GetDeviceInfo(out string[] deviceTypes, out int[] _)) != 0) ThrowMsiError(errorCode); - for (int i = 0; i < deviceTypes.Length; i++) + foreach (string deviceType in deviceTypes) { try { - //TODO DarthAffe 11.11.2017: What is this deviceType? Find someone to try that out - - // MSI_MB provide access to the motherboard "leds" where a led must be intended as a led header (JRGB, JRAINBOW etc..) (Tested on MSI X570 Unify) - if (deviceTypes[i].Equals("MSI_MB")) + //Hex3l: MSI_MB provide access to the motherboard "leds" where a led must be intended as a led header (JRGB, JRAINBOW etc..) (Tested on MSI X570 Unify) + if (deviceType.Equals("MSI_MB")) { - IMsiRGBDevice motherboard = new MsiMainboardRGBDevice(new MsiRGBDeviceInfo(RGBDeviceType.Mainboard, deviceTypes[i], "Msi", "Motherboard")); - motherboard.Initialize(); + MsiDeviceUpdateQueue updateQueue = new MsiDeviceUpdateQueue(UpdateTrigger, deviceType); + IMsiRGBDevice motherboard = new MsiMainboardRGBDevice(new MsiRGBDeviceInfo(RGBDeviceType.Mainboard, deviceType, "Msi", "Motherboard")); + motherboard.Initialize(updateQueue); devices.Add(motherboard); } - // Other devices? + //TODO DarthAffe 22.02.2020: Add other devices } catch { if (throwExceptions) throw; } } + UpdateTrigger?.Start(); + Devices = new ReadOnlyCollection(devices); IsInitialized = true; } diff --git a/RGB.NET.Devices.Msi/MsiDeviceProviderLoader.cs b/RGB.NET.Devices.Msi/MsiDeviceProviderLoader.cs index 0aef5c4..b059f85 100644 --- a/RGB.NET.Devices.Msi/MsiDeviceProviderLoader.cs +++ b/RGB.NET.Devices.Msi/MsiDeviceProviderLoader.cs @@ -3,7 +3,7 @@ namespace RGB.NET.Devices.Msi { /// - /// Represents a device provider loaded used to dynamically load msi devices into an application. + /// Represents a device provider loaded used to dynamically load MSI devices into an application. /// public class MsiDeviceProviderLoader : IRGBDeviceProviderLoader { diff --git a/RGB.NET.Devices.Msi/RGB.NET.Devices.Msi.csproj.DotSettings b/RGB.NET.Devices.Msi/RGB.NET.Devices.Msi.csproj.DotSettings index bcc9d7d..1071e1b 100644 --- a/RGB.NET.Devices.Msi/RGB.NET.Devices.Msi.csproj.DotSettings +++ b/RGB.NET.Devices.Msi/RGB.NET.Devices.Msi.csproj.DotSettings @@ -1,3 +1,4 @@  True - True \ No newline at end of file + True + True \ No newline at end of file From 7fea5fbde599a333d64589988f1f63aafcfa3d15 Mon Sep 17 00:00:00 2001 From: Hex3l Date: Sat, 22 Feb 2020 20:13:41 +0100 Subject: [PATCH 13/16] Adds MSI VGA support --- .../GraphicsCard/MsiGraphicsCardRGBDevice.cs | 66 +++++++++++++++++++ RGB.NET.Devices.Msi/MsiDeviceProvider.cs | 12 ++++ 2 files changed, 78 insertions(+) create mode 100644 RGB.NET.Devices.Msi/GraphicsCard/MsiGraphicsCardRGBDevice.cs diff --git a/RGB.NET.Devices.Msi/GraphicsCard/MsiGraphicsCardRGBDevice.cs b/RGB.NET.Devices.Msi/GraphicsCard/MsiGraphicsCardRGBDevice.cs new file mode 100644 index 0000000..54ab51b --- /dev/null +++ b/RGB.NET.Devices.Msi/GraphicsCard/MsiGraphicsCardRGBDevice.cs @@ -0,0 +1,66 @@ +using RGB.NET.Core; +using RGB.NET.Devices.Msi.Native; + +namespace RGB.NET.Devices.Msi +{ + /// + /// + /// Represents MSI VGA adapters. + /// + public class MsiGraphicsCardRGBDevice : MsiRGBDevice + { + #region Constructors + + /// + /// + /// Initializes a new instance of the class. + /// + /// The specific information provided by MSI for graphics cards. + internal MsiGraphicsCardRGBDevice(MsiRGBDeviceInfo info) + : base(info) + { } + + #endregion + + #region Methods + + /// + protected override void InitializeLayout() + { + // Should errors be handled? + _MsiSDK.GetDeviceInfo(out string[] deviceTypes, out int[] ledCounts); + + for (int i = 0; i < deviceTypes.Length; i++) + { + // DeviceInfo.MsiDeviceType = "MSI_VGA" + if (deviceTypes[i].Equals(DeviceInfo.MsiDeviceType)) + { + for (int j = 0; j < ledCounts[i]; j++) + { + //Hex3l: Should it be configurable in order to provide style access? + //Hex3l: Sets led style to "Steady" in order to have a solid color output therefore a controllable led color + //Hex3l: This is a string defined by the output of _MsiSDK.GetLedStyle, "Steady" should be always present + const string LED_STYLE = "Steady"; + + //Hex3l: Every led is a video card adapter. + + _MsiSDK.SetLedStyle(DeviceInfo.MsiDeviceType, j, LED_STYLE); + InitializeLed(LedId.GraphicsCard1 + j, new Rectangle(j * 10, 0, 10, 10)); + } + } + } + + //TODO DarthAffe 07.10.2017: We don't know the model, how to save layouts and images? + ApplyLayoutFromFile(PathHelper.GetAbsolutePath($@"Layouts\MSI\GraphicsCard\{DeviceInfo.Model.Replace(" ", string.Empty).ToUpper()}.xml"), null); + } + + /// + protected override object CreateLedCustomData(LedId ledId) => (int)ledId - (int)LedId.GraphicsCard1; + + /// + public override void SyncBack() + { } + + #endregion + } +} diff --git a/RGB.NET.Devices.Msi/MsiDeviceProvider.cs b/RGB.NET.Devices.Msi/MsiDeviceProvider.cs index f233857..591050a 100644 --- a/RGB.NET.Devices.Msi/MsiDeviceProvider.cs +++ b/RGB.NET.Devices.Msi/MsiDeviceProvider.cs @@ -120,6 +120,18 @@ namespace RGB.NET.Devices.Msi devices.Add(motherboard); } + + if (deviceTypes.Equals("MSI_VGA")) + { + //Hex3l: Every led under MSI_VGA should be a different graphics card. Handling all the cards together seems a good way to avoid overlapping of leds + //Hex3l: The led name is the name of the card (e.g. NVIDIA GeForce RTX 2080 Ti) we could provide it in device info. + + MsiDeviceUpdateQueue updateQueue = new MsiDeviceUpdateQueue(UpdateTrigger, deviceType); + IMsiRGBDevice graphicscard = new MsiGraphicsCardRGBDevice(new MsiRGBDeviceInfo(RGBDeviceType.GraphicsCard, deviceType, "Msi", "GraphicsCard")); + graphicscard.Initialize(updateQueue); + devices.Add(graphicscard); + } + //TODO DarthAffe 22.02.2020: Add other devices } catch { if (throwExceptions) throw; } From 711f8621f2e45f5ebff4cadda3d77743225781d6 Mon Sep 17 00:00:00 2001 From: Hex3l Date: Sat, 22 Feb 2020 20:19:02 +0100 Subject: [PATCH 14/16] fixes typo --- RGB.NET.Devices.Msi/MsiDeviceProvider.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RGB.NET.Devices.Msi/MsiDeviceProvider.cs b/RGB.NET.Devices.Msi/MsiDeviceProvider.cs index 591050a..703aaea 100644 --- a/RGB.NET.Devices.Msi/MsiDeviceProvider.cs +++ b/RGB.NET.Devices.Msi/MsiDeviceProvider.cs @@ -121,7 +121,7 @@ namespace RGB.NET.Devices.Msi } - if (deviceTypes.Equals("MSI_VGA")) + if (deviceType.Equals("MSI_VGA")) { //Hex3l: Every led under MSI_VGA should be a different graphics card. Handling all the cards together seems a good way to avoid overlapping of leds //Hex3l: The led name is the name of the card (e.g. NVIDIA GeForce RTX 2080 Ti) we could provide it in device info. From 93e7e7d0042d91c6deff3c534a676c1327673cb2 Mon Sep 17 00:00:00 2001 From: Darth Affe Date: Sun, 23 Feb 2020 01:08:47 +0100 Subject: [PATCH 15/16] Small refactorings --- .../Exceptions/MysticLightException.cs | 1 + RGB.NET.Devices.Msi/Generic/IMsiRGBDevice.cs | 2 +- RGB.NET.Devices.Msi/Generic/MsiRGBDevice.cs | 6 ++-- .../GraphicsCard/MsiGraphicsCardRGBDevice.cs | 30 +++++++------------ .../Mainboard/MsiMainboardRGBDevice.cs | 26 +++++----------- RGB.NET.Devices.Msi/MsiDeviceProvider.cs | 15 +++++----- .../RGB.NET.Devices.Msi.csproj.DotSettings | 1 + 7 files changed, 32 insertions(+), 49 deletions(-) diff --git a/RGB.NET.Devices.Msi/Exceptions/MysticLightException.cs b/RGB.NET.Devices.Msi/Exceptions/MysticLightException.cs index d36665b..0b12582 100644 --- a/RGB.NET.Devices.Msi/Exceptions/MysticLightException.cs +++ b/RGB.NET.Devices.Msi/Exceptions/MysticLightException.cs @@ -34,6 +34,7 @@ namespace RGB.NET.Devices.Msi.Exceptions /// The raw error code provided by the SDK. /// The text-description of the error. public MysticLightException(int errorCode, string description) + : base($"MSI error code {errorCode} ({description})") { this.ErrorCode = errorCode; this.Description = description; diff --git a/RGB.NET.Devices.Msi/Generic/IMsiRGBDevice.cs b/RGB.NET.Devices.Msi/Generic/IMsiRGBDevice.cs index 13caa17..cd09af0 100644 --- a/RGB.NET.Devices.Msi/Generic/IMsiRGBDevice.cs +++ b/RGB.NET.Devices.Msi/Generic/IMsiRGBDevice.cs @@ -7,6 +7,6 @@ namespace RGB.NET.Devices.Msi /// internal interface IMsiRGBDevice : IRGBDevice { - void Initialize(MsiDeviceUpdateQueue updateQueue); + void Initialize(MsiDeviceUpdateQueue updateQueue, int ledCount); } } diff --git a/RGB.NET.Devices.Msi/Generic/MsiRGBDevice.cs b/RGB.NET.Devices.Msi/Generic/MsiRGBDevice.cs index 6c83ad0..e6a5210 100644 --- a/RGB.NET.Devices.Msi/Generic/MsiRGBDevice.cs +++ b/RGB.NET.Devices.Msi/Generic/MsiRGBDevice.cs @@ -46,11 +46,11 @@ namespace RGB.NET.Devices.Msi /// /// Initializes the device. /// - public void Initialize(MsiDeviceUpdateQueue updateQueue) + public void Initialize(MsiDeviceUpdateQueue updateQueue, int ledCount) { DeviceUpdateQueue = updateQueue; - InitializeLayout(); + InitializeLayout(ledCount); if (Size == Size.Invalid) { @@ -62,7 +62,7 @@ namespace RGB.NET.Devices.Msi /// /// Initializes the and of the device. /// - protected abstract void InitializeLayout(); + protected abstract void InitializeLayout(int ledCount); /// protected override void UpdateLeds(IEnumerable ledsToUpdate) diff --git a/RGB.NET.Devices.Msi/GraphicsCard/MsiGraphicsCardRGBDevice.cs b/RGB.NET.Devices.Msi/GraphicsCard/MsiGraphicsCardRGBDevice.cs index 54ab51b..ee0800a 100644 --- a/RGB.NET.Devices.Msi/GraphicsCard/MsiGraphicsCardRGBDevice.cs +++ b/RGB.NET.Devices.Msi/GraphicsCard/MsiGraphicsCardRGBDevice.cs @@ -25,29 +25,19 @@ namespace RGB.NET.Devices.Msi #region Methods /// - protected override void InitializeLayout() + protected override void InitializeLayout(int ledCount) { - // Should errors be handled? - _MsiSDK.GetDeviceInfo(out string[] deviceTypes, out int[] ledCounts); - - for (int i = 0; i < deviceTypes.Length; i++) + for (int i = 0; i < ledCount; i++) { - // DeviceInfo.MsiDeviceType = "MSI_VGA" - if (deviceTypes[i].Equals(DeviceInfo.MsiDeviceType)) - { - for (int j = 0; j < ledCounts[i]; j++) - { - //Hex3l: Should it be configurable in order to provide style access? - //Hex3l: Sets led style to "Steady" in order to have a solid color output therefore a controllable led color - //Hex3l: This is a string defined by the output of _MsiSDK.GetLedStyle, "Steady" should be always present - const string LED_STYLE = "Steady"; + //Hex3l: Should it be configurable in order to provide style access? + //Hex3l: Sets led style to "Steady" in order to have a solid color output therefore a controllable led color + //Hex3l: This is a string defined by the output of _MsiSDK.GetLedStyle, "Steady" should be always present + const string LED_STYLE = "Steady"; - //Hex3l: Every led is a video card adapter. + //Hex3l: Every led is a video card adapter. - _MsiSDK.SetLedStyle(DeviceInfo.MsiDeviceType, j, LED_STYLE); - InitializeLed(LedId.GraphicsCard1 + j, new Rectangle(j * 10, 0, 10, 10)); - } - } + _MsiSDK.SetLedStyle(DeviceInfo.MsiDeviceType, i, LED_STYLE); + InitializeLed(LedId.GraphicsCard1 + i, new Rectangle(i * 10, 0, 10, 10)); } //TODO DarthAffe 07.10.2017: We don't know the model, how to save layouts and images? @@ -58,7 +48,7 @@ namespace RGB.NET.Devices.Msi protected override object CreateLedCustomData(LedId ledId) => (int)ledId - (int)LedId.GraphicsCard1; /// - public override void SyncBack() + public override void SyncBack() { } #endregion diff --git a/RGB.NET.Devices.Msi/Mainboard/MsiMainboardRGBDevice.cs b/RGB.NET.Devices.Msi/Mainboard/MsiMainboardRGBDevice.cs index afb4f98..f80dab0 100644 --- a/RGB.NET.Devices.Msi/Mainboard/MsiMainboardRGBDevice.cs +++ b/RGB.NET.Devices.Msi/Mainboard/MsiMainboardRGBDevice.cs @@ -25,27 +25,17 @@ namespace RGB.NET.Devices.Msi #region Methods /// - protected override void InitializeLayout() + protected override void InitializeLayout(int ledCount) { - // Should errors be handled? - _MsiSDK.GetDeviceInfo(out string[] deviceTypes, out int[] ledCounts); - - for (int i = 0; i < deviceTypes.Length; i++) + for (int i = 0; i < ledCount; i++) { - // DeviceInfo.MsiDeviceType = "MSI_MB" - if (deviceTypes[i].Equals(DeviceInfo.MsiDeviceType)) - { - for (int j = 0; j < ledCounts[i]; j++) - { - //Hex3l: Should it be configurable in order to provide style access? - //Hex3l: Sets led style to "Steady" in order to have a solid color output therefore a controllable led color - //Hex3l: This is a string defined by the output of _MsiSDK.GetLedStyle, "Steady" should be always present - const string LED_STYLE = "Steady"; + //Hex3l: Should it be configurable in order to provide style access? + //Hex3l: Sets led style to "Steady" in order to have a solid color output therefore a controllable led color + //Hex3l: This is a string defined by the output of _MsiSDK.GetLedStyle, "Steady" should be always present + const string LED_STYLE = "Steady"; - _MsiSDK.SetLedStyle(DeviceInfo.MsiDeviceType, j, LED_STYLE); - InitializeLed(LedId.Mainboard1 + j, new Rectangle(j * 40, 0, 40, 8)); - } - } + _MsiSDK.SetLedStyle(DeviceInfo.MsiDeviceType, i, LED_STYLE); + InitializeLed(LedId.Mainboard1 + i, new Rectangle(i * 40, 0, 40, 8)); } //TODO DarthAffe 07.10.2017: We don't know the model, how to save layouts and images? diff --git a/RGB.NET.Devices.Msi/MsiDeviceProvider.cs b/RGB.NET.Devices.Msi/MsiDeviceProvider.cs index 703aaea..59a3980 100644 --- a/RGB.NET.Devices.Msi/MsiDeviceProvider.cs +++ b/RGB.NET.Devices.Msi/MsiDeviceProvider.cs @@ -104,31 +104,32 @@ namespace RGB.NET.Devices.Msi if ((errorCode = _MsiSDK.Initialize()) != 0) ThrowMsiError(errorCode); - if ((errorCode = _MsiSDK.GetDeviceInfo(out string[] deviceTypes, out int[] _)) != 0) + if ((errorCode = _MsiSDK.GetDeviceInfo(out string[] deviceTypes, out int[] ledCounts)) != 0) ThrowMsiError(errorCode); - foreach (string deviceType in deviceTypes) + for (int i = 0; i < deviceTypes.Length; i++) { try { + string deviceType = deviceTypes[i]; + int ledCount = ledCounts[i]; + //Hex3l: MSI_MB provide access to the motherboard "leds" where a led must be intended as a led header (JRGB, JRAINBOW etc..) (Tested on MSI X570 Unify) if (deviceType.Equals("MSI_MB")) { MsiDeviceUpdateQueue updateQueue = new MsiDeviceUpdateQueue(UpdateTrigger, deviceType); IMsiRGBDevice motherboard = new MsiMainboardRGBDevice(new MsiRGBDeviceInfo(RGBDeviceType.Mainboard, deviceType, "Msi", "Motherboard")); - motherboard.Initialize(updateQueue); + motherboard.Initialize(updateQueue, ledCount); devices.Add(motherboard); } - - - if (deviceType.Equals("MSI_VGA")) + else if (deviceType.Equals("MSI_VGA")) { //Hex3l: Every led under MSI_VGA should be a different graphics card. Handling all the cards together seems a good way to avoid overlapping of leds //Hex3l: The led name is the name of the card (e.g. NVIDIA GeForce RTX 2080 Ti) we could provide it in device info. MsiDeviceUpdateQueue updateQueue = new MsiDeviceUpdateQueue(UpdateTrigger, deviceType); IMsiRGBDevice graphicscard = new MsiGraphicsCardRGBDevice(new MsiRGBDeviceInfo(RGBDeviceType.GraphicsCard, deviceType, "Msi", "GraphicsCard")); - graphicscard.Initialize(updateQueue); + graphicscard.Initialize(updateQueue, ledCount); devices.Add(graphicscard); } diff --git a/RGB.NET.Devices.Msi/RGB.NET.Devices.Msi.csproj.DotSettings b/RGB.NET.Devices.Msi/RGB.NET.Devices.Msi.csproj.DotSettings index 1071e1b..5db6073 100644 --- a/RGB.NET.Devices.Msi/RGB.NET.Devices.Msi.csproj.DotSettings +++ b/RGB.NET.Devices.Msi/RGB.NET.Devices.Msi.csproj.DotSettings @@ -1,4 +1,5 @@  True True + True True \ No newline at end of file From cabb9825be0df2c06f2dfbb533471f96ecf3dd34 Mon Sep 17 00:00:00 2001 From: Darth Affe Date: Mon, 24 Feb 2020 21:55:24 +0100 Subject: [PATCH 16/16] Enabled Msi-Package-Creation --- RGB.NET.Devices.Msi/RGB.NET.Devices.Msi.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RGB.NET.Devices.Msi/RGB.NET.Devices.Msi.csproj b/RGB.NET.Devices.Msi/RGB.NET.Devices.Msi.csproj index e84fca5..cb86295 100644 --- a/RGB.NET.Devices.Msi/RGB.NET.Devices.Msi.csproj +++ b/RGB.NET.Devices.Msi/RGB.NET.Devices.Msi.csproj @@ -21,7 +21,7 @@ https://raw.githubusercontent.com/DarthAffe/RGB.NET/master/LICENSE Github https://github.com/DarthAffe/RGB.NET - False + True