diff --git a/CUE.NET.csproj b/CUE.NET.csproj index 72493ca..ff1ef4c 100644 --- a/CUE.NET.csproj +++ b/CUE.NET.csproj @@ -59,6 +59,7 @@ + @@ -67,7 +68,12 @@ + + + + + @@ -76,6 +82,7 @@ + diff --git a/CueSDK.cs b/CueSDK.cs index fbb3b5b..205a401 100644 --- a/CueSDK.cs +++ b/CueSDK.cs @@ -1,6 +1,7 @@ // ReSharper disable MemberCanBePrivate.Global // ReSharper disable UnusedMember.Global +using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Runtime.InteropServices; @@ -8,9 +9,11 @@ using CUE.NET.Devices; using CUE.NET.Devices.Generic; using CUE.NET.Devices.Generic.Enums; using CUE.NET.Devices.Headset; +using CUE.NET.Devices.HeadsetStand; using CUE.NET.Devices.Keyboard; using CUE.NET.Devices.Mouse; using CUE.NET.Devices.Mousemat; +using CUE.NET.EventArgs; using CUE.NET.Exceptions; using CUE.NET.Native; @@ -86,13 +89,33 @@ namespace CUE.NET public static CorsairHeadset HeadsetSDK { get; private set; } /// - /// Gets the managed representation of a moustmat managed by the CUE-SDK. + /// Gets the managed representation of a mousemat managed by the CUE-SDK. /// Note that currently only one connected mousemat is supported. /// public static CorsairMousemat MousematSDK { get; private set; } + /// + /// Gets the managed representation of a headset stand managed by the CUE-SDK. + /// Note that currently only one connected headset stand is supported. + /// + public static CorsairHeadsetStand HeadsetStandSDK { get; private set; } + // ReSharper restore UnusedAutoPropertyAccessor.Global + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + private delegate void OnKeyPressedDelegate(IntPtr context, CorsairKeyId keyId, [MarshalAs(UnmanagedType.I1)] bool pressed); + private static readonly OnKeyPressedDelegate _onKeyPressedDelegate = OnKeyPressed; + + #endregion + + #region Events + + /// + /// Occurs when the SDK reports that a key is pressed. + /// Notice that right now only G- (keyboard) and M- (mouse) keys are supported. + /// + public static event EventHandler KeyPressed; + #endregion #region Methods @@ -120,6 +143,8 @@ namespace CUE.NET return HeadsetSDK != null; case CorsairDeviceType.Mousemat: return MousematSDK != null; + case CorsairDeviceType.HeadsetStand: + return HeadsetStandSDK != null; default: return true; } @@ -205,6 +230,9 @@ namespace CUE.NET case CorsairDeviceType.Mousemat: device = MousematSDK = new CorsairMousemat(new CorsairMousematDeviceInfo(nativeDeviceInfo)); break; + case CorsairDeviceType.HeadsetStand: + device = HeadsetStandSDK = new CorsairHeadsetStand(new CorsairHeadsetStandDeviceInfo(nativeDeviceInfo)); + break; // ReSharper disable once RedundantCaseLabel case CorsairDeviceType.Unknown: default: @@ -219,11 +247,25 @@ namespace CUE.NET Throw(error, true); } + _CUESDK.CorsairRegisterKeypressCallback(Marshal.GetFunctionPointerForDelegate(_onKeyPressedDelegate), IntPtr.Zero); + error = LastError; + if (error != CorsairError.Success) + Throw(error, false); + InitializedDevices = new ReadOnlyCollection(devices); IsInitialized = true; } + /// + /// Resets the colors of all devices back to the last saved color-data. (If there wasn't a manual save, that's the data from the time the SDK was initialized.) + /// + public static void Reset() + { + foreach (ICueDevice device in InitializedDevices) + device.RestoreColors(); + } + /// /// Reinitialize the CUE-SDK and temporarily hand back full control to CUE. /// @@ -245,6 +287,7 @@ namespace CUE.NET MouseSDK?.ResetLeds(); HeadsetSDK?.ResetLeds(); MousematSDK?.ResetLeds(); + HeadsetStandSDK?.ResetLeds(); _CUESDK.Reload(); @@ -295,6 +338,15 @@ namespace CUE.NET if (!reloadedDevices.ContainsKey(CorsairDeviceType.Mousemat) || MousematSDK.MousematDeviceInfo.Model != reloadedDevices[CorsairDeviceType.Mousemat].Model) throw new WrapperException("The previously loaded Mousemat got disconnected."); + if (HeadsetStandSDK != null) + if (!reloadedDevices.ContainsKey(CorsairDeviceType.HeadsetStand) + || HeadsetStandSDK.HeadsetStandDeviceInfo.Model != reloadedDevices[CorsairDeviceType.HeadsetStand].Model) + throw new WrapperException("The previously loaded Headset Stand got disconnected."); + + _CUESDK.CorsairRegisterKeypressCallback(Marshal.GetFunctionPointerForDelegate(_onKeyPressedDelegate), IntPtr.Zero); + error = LastError; + if (error != CorsairError.Success) + Throw(error, false); IsInitialized = true; } @@ -309,12 +361,16 @@ namespace CUE.NET MouseSDK = null; HeadsetSDK = null; MousematSDK = null; + HeadsetStandSDK = null; IsInitialized = false; } throw new CUEException(error); } + private static void OnKeyPressed(IntPtr context, CorsairKeyId keyId, bool pressed) + => KeyPressed?.Invoke(null, new KeyPressedEventArgs(keyId, pressed)); + #endregion } } diff --git a/Devices/Generic/AbstractCueDevice.cs b/Devices/Generic/AbstractCueDevice.cs index 7a253c3..5eb0346 100644 --- a/Devices/Generic/AbstractCueDevice.cs +++ b/Devices/Generic/AbstractCueDevice.cs @@ -29,6 +29,8 @@ namespace CUE.NET.Devices.Generic private static DateTime _lastUpdate = DateTime.Now; + private Dictionary _colorDataSave; + /// /// Gets generic information provided by CUE for the device. /// @@ -56,6 +58,7 @@ namespace CUE.NET.Devices.Generic /// /// Gets or sets the background brush of the keyboard. + /// If this is null the last saved color-data is used as background. /// public IBrush Brush { get; set; } @@ -153,6 +156,7 @@ namespace CUE.NET.Devices.Generic public virtual void Initialize() { DeviceRectangle = RectangleHelper.CreateRectangleFromRectangles((this).Select(x => x.LedRectangle)); + SaveColors(); } /// @@ -187,19 +191,26 @@ namespace CUE.NET.Devices.Generic /// Performs an update for all dirty keys, or all keys if flushLeds is set to true. /// /// Specifies whether all keys (including clean ones) should be updated. - public void Update(bool flushLeds = false) + /// Only updates the hardware-leds skippin effects and the render-pass. Only use this if you know what that means! + public void Update(bool flushLeds = false, bool noRender = false) { OnUpdating(); - // Update effects - foreach (ILedGroup ledGroup in LedGroups) - ledGroup.UpdateEffects(); + if (!noRender) + { + // Update effects + foreach (ILedGroup ledGroup in LedGroups) + ledGroup.UpdateEffects(); - // Render brushes - Render(this); - foreach (ILedGroup ledGroup in LedGroups.OrderBy(x => x.ZIndex)) - Render(ledGroup); + // Render brushes + if (Brush != null) + Render(this); + else + ApplyColorData(_colorDataSave); + foreach (ILedGroup ledGroup in LedGroups.OrderBy(x => x.ZIndex)) + Render(ledGroup); + } // Device-specific updates DeviceUpdate(); @@ -293,6 +304,63 @@ namespace CUE.NET.Devices.Generic OnLedsUpdated(updateRequests); } + /// + public void SyncColors() + { + Dictionary colorData = GetColors(); + ApplyColorData(colorData); + Update(true, true); + } + + /// + public void SaveColors() + { + _colorDataSave = GetColors(); + } + + /// + public void RestoreColors() + { + ApplyColorData(_colorDataSave); + Update(true, true); + } + + private void ApplyColorData(Dictionary colorData) + { + if (colorData == null) return; + + foreach (KeyValuePair corsairColor in _colorDataSave) + LedMapping[corsairColor.Key].Color = corsairColor.Value; + } + + private Dictionary GetColors() + { + int structSize = Marshal.SizeOf(typeof(_CorsairLedColor)); + IntPtr ptr = Marshal.AllocHGlobal(structSize * LedMapping.Count); + IntPtr addPtr = new IntPtr(ptr.ToInt64()); + foreach (KeyValuePair led in LedMapping) + { + _CorsairLedColor color = new _CorsairLedColor { ledId = (int)led.Value.Id }; + Marshal.StructureToPtr(color, addPtr, false); + addPtr = new IntPtr(addPtr.ToInt64() + structSize); + } + _CUESDK.CorsairGetLedsColors(LedMapping.Count, ptr); + + IntPtr readPtr = ptr; + Dictionary colorData = new Dictionary(); + for (int i = 0; i < LedMapping.Count; i++) + { + _CorsairLedColor ledColor = (_CorsairLedColor)Marshal.PtrToStructure(readPtr, typeof(_CorsairLedColor)); + colorData.Add((CorsairLedId)ledColor.ledId, new CorsairColor((byte)ledColor.r, (byte)ledColor.g, (byte)ledColor.b)); + + readPtr = new IntPtr(readPtr.ToInt64() + structSize); + } + + Marshal.FreeHGlobal(ptr); + + return colorData; + } + #endregion #region LedGroup diff --git a/Devices/Generic/Enums/CorsairDeviceType.cs b/Devices/Generic/Enums/CorsairDeviceType.cs index adcac29..71ec6b7 100644 --- a/Devices/Generic/Enums/CorsairDeviceType.cs +++ b/Devices/Generic/Enums/CorsairDeviceType.cs @@ -15,6 +15,7 @@ namespace CUE.NET.Devices.Generic.Enums Mouse = 1, Keyboard = 2, Headset = 3, - Mousemat = 4 + Mousemat = 4, + HeadsetStand = 5 }; } diff --git a/Devices/Generic/Enums/CorsairKeyId.cs b/Devices/Generic/Enums/CorsairKeyId.cs new file mode 100644 index 0000000..693c471 --- /dev/null +++ b/Devices/Generic/Enums/CorsairKeyId.cs @@ -0,0 +1,46 @@ +// ReSharper disable InconsistentNaming + +#pragma warning disable 1591 // Missing XML comment for publicly visible type or member + +namespace CUE.NET.Devices.Generic.Enums +{ + /// + /// Contains list of all KeyIds available for all corsair devices. + /// + public enum CorsairKeyId + { + Invalid = 0, + + G1 = 1, + G2 = 2, + G3 = 3, + G4 = 4, + G5 = 5, + G6 = 6, + G7 = 7, + G8 = 8, + G9 = 9, + G10 = 10, + G11 = 11, + G12 = 12, + G13 = 13, + G14 = 14, + G15 = 15, + G16 = 16, + G17 = 17, + G18 = 18, + + M1 = 19, + M2 = 20, + M3 = 21, + M4 = 22, + M5 = 23, + M6 = 24, + M7 = 25, + M8 = 26, + M9 = 27, + M10 = 28, + M11 = 29, + M12 = 30, + } +} diff --git a/Devices/Generic/Enums/CorsairLedId.cs b/Devices/Generic/Enums/CorsairLedId.cs index c22c63a..6f74351 100644 --- a/Devices/Generic/Enums/CorsairLedId.cs +++ b/Devices/Generic/Enums/CorsairLedId.cs @@ -205,5 +205,15 @@ namespace CUE.NET.Devices.Generic.Enums Lightbar17 = 186, Lightbar18 = 187, Lightbar19 = 188, + + HeadsetStandZone1 = 191, + HeadsetStandZone2 = 192, + HeadsetStandZone3 = 193, + HeadsetStandZone4 = 194, + HeadsetStandZone5 = 195, + HeadsetStandZone6 = 196, + HeadsetStandZone7 = 197, + HeadsetStandZone8 = 198, + HeadsetStandZone9 = 199, } } diff --git a/Devices/HeadsetStand/CorsairHeadsetStand.cs b/Devices/HeadsetStand/CorsairHeadsetStand.cs new file mode 100644 index 0000000..f34d1ef --- /dev/null +++ b/Devices/HeadsetStand/CorsairHeadsetStand.cs @@ -0,0 +1,91 @@ +// ReSharper disable UnusedAutoPropertyAccessor.Global +// ReSharper disable MemberCanBePrivate.Global +// ReSharper disable UnusedMember.Global + +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Linq; +using System.Runtime.InteropServices; +using CUE.NET.Devices.Generic; +using CUE.NET.Devices.Generic.Enums; +using CUE.NET.Exceptions; +using CUE.NET.Native; + +namespace CUE.NET.Devices.HeadsetStand +{ + /// + /// Represents the SDK for a corsair headset stand. + /// + public class CorsairHeadsetStand : AbstractCueDevice + { + #region Properties & Fields + + /// + /// Gets specific information provided by CUE for the headset stand. + /// + public CorsairHeadsetStandDeviceInfo HeadsetStandDeviceInfo { get; } + + #endregion + + #region Constructors + + /// + /// Initializes a new instance of the class. + /// + /// The specific information provided by CUE for the headset stand + internal CorsairHeadsetStand(CorsairHeadsetStandDeviceInfo info) + : base(info) + { + this.HeadsetStandDeviceInfo = info; + } + + #endregion + + #region Methods + + /// + /// Initializes the headset stand. + /// + public override void Initialize() + { + int deviceCount = _CUESDK.CorsairGetDeviceCount(); + + // Get headset stand device index + int headsetStandIndex = -1; + for (int i = 0; i < deviceCount; i++) + { + _CorsairDeviceInfo nativeDeviceInfo = (_CorsairDeviceInfo)Marshal.PtrToStructure(_CUESDK.CorsairGetDeviceInfo(i), typeof(_CorsairDeviceInfo)); + GenericDeviceInfo info = new GenericDeviceInfo(nativeDeviceInfo); + if (info.Type != CorsairDeviceType.HeadsetStand) + continue; + + headsetStandIndex = i; + break; + } + if (headsetStandIndex < 0) + throw new WrapperException("Can't determine headset stand device index"); + + _CorsairLedPositions nativeLedPositions = (_CorsairLedPositions)Marshal.PtrToStructure(_CUESDK.CorsairGetLedPositionsByDeviceIndex(headsetStandIndex), typeof(_CorsairLedPositions)); + int structSize = Marshal.SizeOf(typeof(_CorsairLedPosition)); + IntPtr ptr = nativeLedPositions.pLedPosition; + + // Put the positions in an array for sorting later on + List<_CorsairLedPosition> positions = new List<_CorsairLedPosition>(); + for (int i = 0; i < nativeLedPositions.numberOfLed; i++) + { + _CorsairLedPosition ledPosition = (_CorsairLedPosition)Marshal.PtrToStructure(ptr, typeof(_CorsairLedPosition)); + ptr = new IntPtr(ptr.ToInt64() + structSize); + positions.Add(ledPosition); + } + + // Sort for easy iteration by clients + foreach (_CorsairLedPosition ledPosition in positions.OrderBy(p => p.ledId)) + InitializeLed(ledPosition.ledId, new RectangleF((float)ledPosition.left, (float)ledPosition.top, (float)ledPosition.width, (float)ledPosition.height)); + + base.Initialize(); + } + + #endregion + } +} diff --git a/Devices/HeadsetStand/CorsairHeadsetStandDeviceInfo.cs b/Devices/HeadsetStand/CorsairHeadsetStandDeviceInfo.cs new file mode 100644 index 0000000..46bfe1c --- /dev/null +++ b/Devices/HeadsetStand/CorsairHeadsetStandDeviceInfo.cs @@ -0,0 +1,26 @@ +// ReSharper disable MemberCanBePrivate.Global +// ReSharper disable UnusedAutoPropertyAccessor.Global + +using CUE.NET.Devices.Generic; +using CUE.NET.Native; + +namespace CUE.NET.Devices.HeadsetStand +{ + /// + /// Represents specific information for a CUE headset stand. + /// + public class CorsairHeadsetStandDeviceInfo : GenericDeviceInfo + { + #region Constructors + + /// + /// Internal constructor of managed . + /// + /// The native -struct + internal CorsairHeadsetStandDeviceInfo(_CorsairDeviceInfo nativeInfo) + : base(nativeInfo) + { } + + #endregion + } +} \ No newline at end of file diff --git a/Devices/HeadsetStand/Enums/CorsairHeadsetStandLedId.cs b/Devices/HeadsetStand/Enums/CorsairHeadsetStandLedId.cs new file mode 100644 index 0000000..6ae1a2e --- /dev/null +++ b/Devices/HeadsetStand/Enums/CorsairHeadsetStandLedId.cs @@ -0,0 +1,26 @@ +// ReSharper disable UnusedMember.Global +// ReSharper disable InconsistentNaming + +#pragma warning disable 1591 // Missing XML comment for publicly visible type or member + +using CUE.NET.Devices.Generic.Enums; + +namespace CUE.NET.Devices.HeadsetStand.Enums +{ + /// + /// Contains list of all LEDs available for corsair headset stands. + /// + public static class CorsairHeadsetStandLedId + { + public const CorsairLedId Invalid = CorsairLedId.Invalid; + public const CorsairLedId HeadsetStandZone1 = CorsairLedId.HeadsetStandZone1; + public const CorsairLedId HeadsetStandZone2 = CorsairLedId.HeadsetStandZone2; + public const CorsairLedId HeadsetStandZone3 = CorsairLedId.HeadsetStandZone3; + public const CorsairLedId HeadsetStandZone4 = CorsairLedId.HeadsetStandZone4; + public const CorsairLedId HeadsetStandZone5 = CorsairLedId.HeadsetStandZone5; + public const CorsairLedId HeadsetStandZone6 = CorsairLedId.HeadsetStandZone6; + public const CorsairLedId HeadsetStandZone7 = CorsairLedId.HeadsetStandZone7; + public const CorsairLedId HeadsetStandZone8 = CorsairLedId.HeadsetStandZone8; + public const CorsairLedId HeadsetStandZone9 = CorsairLedId.HeadsetStandZone9; + } +} \ No newline at end of file diff --git a/Devices/ICueDevice.cs b/Devices/ICueDevice.cs index 3b2226a..2d95d18 100644 --- a/Devices/ICueDevice.cs +++ b/Devices/ICueDevice.cs @@ -140,10 +140,26 @@ namespace CUE.NET.Devices void Initialize(); /// - /// Perform an update for all dirty keys, or all keys if flushLeds is set to true. + /// Performs an update for all dirty keys, or all keys if flushLeds is set to true. /// /// Specifies whether all keys (including clean ones) should be updated. - void Update(bool flushLeds = false); + /// Only updates the hardware-leds skippin effects and the render-pass. Only use this if you know what that means! + void Update(bool flushLeds = false, bool noRender = false); + + /// + /// Reads the currently active colors from the device and sync them with the internal state. + /// + void SyncColors(); + + /// + /// Saves the currently active colors from the device. + /// + void SaveColors(); + + /// + /// Restores the last saved colors. + /// + void RestoreColors(); /// /// Attaches the given ledgroup. diff --git a/Devices/Keyboard/Enums/CorsairKeyboardKeyId.cs b/Devices/Keyboard/Enums/CorsairKeyboardKeyId.cs new file mode 100644 index 0000000..9c2ce3c --- /dev/null +++ b/Devices/Keyboard/Enums/CorsairKeyboardKeyId.cs @@ -0,0 +1,36 @@ +// ReSharper disable UnusedMember.Global +// ReSharper disable InconsistentNaming + +#pragma warning disable 1591 // Missing XML comment for publicly visible type or member + +using CUE.NET.Devices.Generic.Enums; + +namespace CUE.NET.Devices.Keyboard.Enums +{ + /// + /// Contains list of all LEDs available for corsair keyboards. + /// + public static class CorsairKeyboardKeyId + { + public const CorsairKeyId Invalid = CorsairKeyId.Invalid; + + public const CorsairKeyId G1 = CorsairKeyId.G1; + public const CorsairKeyId G2 = CorsairKeyId.G2; + public const CorsairKeyId G3 = CorsairKeyId.G3; + public const CorsairKeyId G4 = CorsairKeyId.G4; + public const CorsairKeyId G5 = CorsairKeyId.G5; + public const CorsairKeyId G6 = CorsairKeyId.G6; + public const CorsairKeyId G7 = CorsairKeyId.G7; + public const CorsairKeyId G8 = CorsairKeyId.G8; + public const CorsairKeyId G9 = CorsairKeyId.G9; + public const CorsairKeyId G10 = CorsairKeyId.G10; + public const CorsairKeyId G11 = CorsairKeyId.G11; + public const CorsairKeyId G12 = CorsairKeyId.G12; + public const CorsairKeyId G13 = CorsairKeyId.G13; + public const CorsairKeyId G14 = CorsairKeyId.G14; + public const CorsairKeyId G15 = CorsairKeyId.G15; + public const CorsairKeyId G16 = CorsairKeyId.G16; + public const CorsairKeyId G17 = CorsairKeyId.G17; + public const CorsairKeyId G18 = CorsairKeyId.G18; + } +} diff --git a/Devices/Mouse/CorsairMouse.cs b/Devices/Mouse/CorsairMouse.cs index 864ac94..3dbedba 100644 --- a/Devices/Mouse/CorsairMouse.cs +++ b/Devices/Mouse/CorsairMouse.cs @@ -2,10 +2,16 @@ // ReSharper disable UnusedAutoPropertyAccessor.Global // ReSharper disable UnusedMember.Global +using System; +using System.Collections.Generic; using System.Drawing; +using System.Linq; +using System.Runtime.InteropServices; using CUE.NET.Devices.Generic; +using CUE.NET.Devices.Generic.Enums; using CUE.NET.Devices.Mouse.Enums; using CUE.NET.Exceptions; +using CUE.NET.Native; namespace CUE.NET.Devices.Mouse { @@ -44,6 +50,14 @@ namespace CUE.NET.Devices.Mouse /// public override void Initialize() { + // Glaive is a special flake that doesn't follow the default layout + if (MouseDeviceInfo.Model == "GLAIVE RGB") + { + InitializeLed(CorsairMouseLedId.B1, new RectangleF(0, 0, 1, 1)); // Logo + InitializeLed(CorsairMouseLedId.B2, new RectangleF(2, 0, 1, 1)); // Front + InitializeLed(CorsairMouseLedId.B5, new RectangleF(3, 0, 1, 1)); // Sides + return; + } switch (MouseDeviceInfo.PhysicalLayout) { case CorsairPhysicalMouseLayout.Zones1: diff --git a/Devices/Mouse/Enums/CorsairMouseKeyId.cs b/Devices/Mouse/Enums/CorsairMouseKeyId.cs new file mode 100644 index 0000000..751f0a8 --- /dev/null +++ b/Devices/Mouse/Enums/CorsairMouseKeyId.cs @@ -0,0 +1,30 @@ +// ReSharper disable UnusedMember.Global +// ReSharper disable InconsistentNaming + +#pragma warning disable 1591 // Missing XML comment for publicly visible type or member + +using CUE.NET.Devices.Generic.Enums; + +namespace CUE.NET.Devices.Mouse.Enums +{ + /// + /// Contains list of all LEDs available for corsair mice. + /// + public static class CorsairMouseKeyId + { + public const CorsairKeyId Invalid = CorsairKeyId.Invalid; + + public const CorsairKeyId M1 = CorsairKeyId.M1; + public const CorsairKeyId M2 = CorsairKeyId.M2; + public const CorsairKeyId M3 = CorsairKeyId.M3; + public const CorsairKeyId M4 = CorsairKeyId.M4; + public const CorsairKeyId M5 = CorsairKeyId.M5; + public const CorsairKeyId M6 = CorsairKeyId.M6; + public const CorsairKeyId M7 = CorsairKeyId.M7; + public const CorsairKeyId M8 = CorsairKeyId.M8; + public const CorsairKeyId M9 = CorsairKeyId.M9; + public const CorsairKeyId M10 = CorsairKeyId.M10; + public const CorsairKeyId M11 = CorsairKeyId.M11; + public const CorsairKeyId M12 = CorsairKeyId.M12; + } +} diff --git a/EventArgs/KeyPressedEventArgs.cs b/EventArgs/KeyPressedEventArgs.cs new file mode 100644 index 0000000..5741055 --- /dev/null +++ b/EventArgs/KeyPressedEventArgs.cs @@ -0,0 +1,41 @@ +// ReSharper disable MemberCanBePrivate.Global + +using CUE.NET.Devices.Generic.Enums; + +namespace CUE.NET.EventArgs +{ + /// + /// Represents the data provided by the -event. + /// + public class KeyPressedEventArgs : System.EventArgs + { + #region Properties & Fields + + /// + /// Gets the id of the key. + /// + public CorsairKeyId KeyId { get; } + + /// + /// Gets the current status of the key (true = pressed, flase = released). + /// + public bool IsPressed { get; } + + #endregion + + #region Constructors + + /// + /// Initializes a new instance of the class. + /// + /// The id of the key. + /// The current status of the key (true = pressed, flase = released). + public KeyPressedEventArgs(CorsairKeyId keyId, bool isPressed) + { + this.KeyId = keyId; + this.IsPressed = isPressed; + } + + #endregion + } +} diff --git a/Examples/SimpleDevTest/Program.cs b/Examples/SimpleDevTest/Program.cs index 7b52a33..8780c87 100644 --- a/Examples/SimpleDevTest/Program.cs +++ b/Examples/SimpleDevTest/Program.cs @@ -39,7 +39,9 @@ namespace SimpleDevTest CueSDK.Initialize(); Console.WriteLine("Initialized with " + CueSDK.LoadedArchitecture + "-SDK"); - CueSDK.KeyboardSDK.Brush = (SolidColorBrush)Color.Black; + CueSDK.KeyPressed += (sender, eventArgs) => Console.WriteLine($"Key {eventArgs.KeyId} {(eventArgs.IsPressed ? "pressed" : "released")}"); + + //CueSDK.KeyboardSDK.Brush = (SolidColorBrush)Color.Black; //CueSDK.KeyboardSDK[CorsairLedId.Z].Color = Color.Red; //CueSDK.KeyboardSDK[CorsairLedId.Z].IsLocked = true; @@ -51,12 +53,15 @@ namespace SimpleDevTest //CueSDK.KeyboardSDK.Brush = new LinearGradientBrush(new LinearGradient(true, new GradientStop(0, Color.Blue), new GradientStop(0.5f, Color.Red))); left.Brush = new ConicalGradientBrush(new PointF(0.6f, 0.7f), new RainbowGradient(360, 0)); left.Brush.AddEffect(new MoveGradientEffect()); + left.Brush.AddEffect(new FlashEffect { Attack = 2, Sustain = 1f, Release = 2, Interval = 1f }); mid.Brush = new ConicalGradientBrush(new PointF(0.5f, 0.3f), new RainbowGradient()); mid.Brush.AddEffect(new MoveGradientEffect()); + mid.Brush.AddEffect(new FlashEffect { Attack = 2, Sustain = 1f, Release = 2, Interval = 1f }); right.Brush = new ConicalGradientBrush(new PointF(0.4f, 0.7f), new RainbowGradient(360, 0)); right.Brush.AddEffect(new MoveGradientEffect()); + right.Brush.AddEffect(new FlashEffect { Attack = 2, Sustain = 1f, Release = 2, Interval = 1f }); //float halfKeyboardWidth = CueSDK.KeyboardSDK.DeviceRectangle.Width / 2f; //ILedGroup left = new RectangleLedGroup(CueSDK.KeyboardSDK, new RectangleF(CueSDK.KeyboardSDK.DeviceRectangle.X, CueSDK.KeyboardSDK.DeviceRectangle.Y, halfKeyboardWidth, CueSDK.KeyboardSDK.DeviceRectangle.Height)); diff --git a/Native/_CUESDK.cs b/Native/_CUESDK.cs index c6a18de..9f8b939 100644 --- a/Native/_CUESDK.cs +++ b/Native/_CUESDK.cs @@ -53,6 +53,7 @@ namespace CUE.NET.Native _dllHandle = LoadLibrary(dllPath); _corsairSetLedsColorsPointer = (CorsairSetLedsColorsPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "CorsairSetLedsColors"), typeof(CorsairSetLedsColorsPointer)); + _corsairGetLedsColorsPointer = (CorsairGetLedsColorsPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "CorsairGetLedsColors"), typeof(CorsairGetLedsColorsPointer)); _corsairGetDeviceCountPointer = (CorsairGetDeviceCountPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "CorsairGetDeviceCount"), typeof(CorsairGetDeviceCountPointer)); _corsairGetDeviceInfoPointer = (CorsairGetDeviceInfoPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "CorsairGetDeviceInfo"), typeof(CorsairGetDeviceInfoPointer)); _corsairGetLedPositionsPointer = (CorsairGetLedPositionsPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "CorsairGetLedPositions"), typeof(CorsairGetLedPositionsPointer)); @@ -62,6 +63,7 @@ namespace CUE.NET.Native _corsairReleaseControlPointer = (CorsairReleaseControlPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "CorsairReleaseControl"), typeof(CorsairReleaseControlPointer)); _corsairPerformProtocolHandshakePointer = (CorsairPerformProtocolHandshakePointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "CorsairPerformProtocolHandshake"), typeof(CorsairPerformProtocolHandshakePointer)); _corsairGetLastErrorPointer = (CorsairGetLastErrorPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "CorsairGetLastError"), typeof(CorsairGetLastErrorPointer)); + _corsairRegisterKeypressCallbackPointer = (CorsairRegisterKeypressCallbackPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "CorsairRegisterKeypressCallback"), typeof(CorsairRegisterKeypressCallbackPointer)); } private static void UnloadCUESDK() @@ -89,6 +91,7 @@ namespace CUE.NET.Native #region Pointers private static CorsairSetLedsColorsPointer _corsairSetLedsColorsPointer; + private static CorsairGetLedsColorsPointer _corsairGetLedsColorsPointer; private static CorsairGetDeviceCountPointer _corsairGetDeviceCountPointer; private static CorsairGetDeviceInfoPointer _corsairGetDeviceInfoPointer; private static CorsairGetLedPositionsPointer _corsairGetLedPositionsPointer; @@ -98,6 +101,7 @@ namespace CUE.NET.Native private static CorsairReleaseControlPointer _corsairReleaseControlPointer; private static CorsairPerformProtocolHandshakePointer _corsairPerformProtocolHandshakePointer; private static CorsairGetLastErrorPointer _corsairGetLastErrorPointer; + private static CorsairRegisterKeypressCallbackPointer _corsairRegisterKeypressCallbackPointer; #endregion @@ -106,6 +110,9 @@ namespace CUE.NET.Native [UnmanagedFunctionPointer(CallingConvention.Cdecl)] private delegate bool CorsairSetLedsColorsPointer(int size, IntPtr ledsColors); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + private delegate bool CorsairGetLedsColorsPointer(int size, IntPtr ledsColors); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] private delegate int CorsairGetDeviceCountPointer(); @@ -133,6 +140,9 @@ namespace CUE.NET.Native [UnmanagedFunctionPointer(CallingConvention.Cdecl)] private delegate CorsairError CorsairGetLastErrorPointer(); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + private delegate bool CorsairRegisterKeypressCallbackPointer(IntPtr callback, IntPtr context); + #endregion // ReSharper disable EventExceptionNotDocumented @@ -145,6 +155,14 @@ namespace CUE.NET.Native return _corsairSetLedsColorsPointer(size, ledsColors); } + /// + /// CUE-SDK: get current color for the list of requested LEDs. + /// + internal static bool CorsairGetLedsColors(int size, IntPtr ledsColors) + { + return _corsairGetLedsColorsPointer(size, ledsColors); + } + /// /// CUE-SDK: returns number of connected Corsair devices that support lighting control. /// @@ -218,6 +236,11 @@ namespace CUE.NET.Native return _corsairGetLastErrorPointer(); } + internal static bool CorsairRegisterKeypressCallback(IntPtr callback, IntPtr context) + { + return _corsairRegisterKeypressCallbackPointer(callback, context); + } + // ReSharper restore EventExceptionNotDocumented #endregion diff --git a/libs/x64/CUESDK_2015.dll b/libs/x64/CUESDK_2015.dll index 6e5da8c..139ba27 100644 Binary files a/libs/x64/CUESDK_2015.dll and b/libs/x64/CUESDK_2015.dll differ diff --git a/libs/x86/CUESDK_2015.dll b/libs/x86/CUESDK_2015.dll index 70d678f..b0e6996 100644 Binary files a/libs/x86/CUESDK_2015.dll and b/libs/x86/CUESDK_2015.dll differ