diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000..1ff0c42
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,63 @@
+###############################################################################
+# Set default behavior to automatically normalize line endings.
+###############################################################################
+* text=auto
+
+###############################################################################
+# Set default behavior for command prompt diff.
+#
+# This is need for earlier builds of msysgit that does not have it on by
+# default for csharp files.
+# Note: This is only used by command line
+###############################################################################
+#*.cs diff=csharp
+
+###############################################################################
+# Set the merge driver for project and solution files
+#
+# Merging from the command prompt will add diff markers to the files if there
+# are conflicts (Merging from VS is not affected by the settings below, in VS
+# the diff markers are never inserted). Diff markers may cause the following
+# file extensions to fail to load in VS. An alternative would be to treat
+# these files as binary and thus will always conflict and require user
+# intervention with every merge. To do so, just uncomment the entries below
+###############################################################################
+#*.sln merge=binary
+#*.csproj merge=binary
+#*.vbproj merge=binary
+#*.vcxproj merge=binary
+#*.vcproj merge=binary
+#*.dbproj merge=binary
+#*.fsproj merge=binary
+#*.lsproj merge=binary
+#*.wixproj merge=binary
+#*.modelproj merge=binary
+#*.sqlproj merge=binary
+#*.wwaproj merge=binary
+
+###############################################################################
+# behavior for image files
+#
+# image files are treated as binary by default.
+###############################################################################
+#*.jpg binary
+#*.png binary
+#*.gif binary
+
+###############################################################################
+# diff behavior for common document formats
+#
+# Convert binary document formats to text before diffing them. This feature
+# is only available from the command line. Turn it on by uncommenting the
+# entries below.
+###############################################################################
+#*.doc diff=astextplain
+#*.DOC diff=astextplain
+#*.docx diff=astextplain
+#*.DOCX diff=astextplain
+#*.dot diff=astextplain
+#*.DOT diff=astextplain
+#*.pdf diff=astextplain
+#*.PDF diff=astextplain
+#*.rtf diff=astextplain
+#*.RTF diff=astextplain
diff --git a/CUE.NET.csproj b/CUE.NET.csproj
new file mode 100644
index 0000000..7e8561c
--- /dev/null
+++ b/CUE.NET.csproj
@@ -0,0 +1,106 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {70A266B5-E9D4-4EAA-A91A-947C0039FFB6}
+ Library
+ Properties
+ CUE.NET
+ CUE.NET
+ v4.6
+ 512
+
+
+ true
+ bin\x64\
+ TRACE;DEBUG;WIN64
+ full
+ x64
+ prompt
+ MinimumRecommendedRules.ruleset
+
+
+ bin\x64\
+ TRACE;WIN64
+ true
+ pdbonly
+ x64
+ prompt
+ MinimumRecommendedRules.ruleset
+
+
+ true
+ bin\x86\
+ TRACE;DEBUG;WIN32
+ full
+ x86
+ prompt
+ MinimumRecommendedRules.ruleset
+
+
+ bin\x86\
+ TRACE;WIN32
+ true
+ pdbonly
+ x86
+ prompt
+ MinimumRecommendedRules.ruleset
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ if $(PlatformName) == x86 copy "$(ProjectDir)libs\CUESDK_2013.dll" "$(TargetDir)CUESDK_2013.dll"
+if $(PlatformName) == x64 copy "$(ProjectDir)libs\CUESDK.x64_2013.dll" "$(TargetDir)CUESDK.x64_2013.dll"
+
+
+
\ No newline at end of file
diff --git a/CUE.NET.csproj.DotSettings b/CUE.NET.csproj.DotSettings
new file mode 100644
index 0000000..b35dc7e
--- /dev/null
+++ b/CUE.NET.csproj.DotSettings
@@ -0,0 +1,2 @@
+
+ True
\ No newline at end of file
diff --git a/CUE.NET.sln b/CUE.NET.sln
new file mode 100644
index 0000000..c041fd8
--- /dev/null
+++ b/CUE.NET.sln
@@ -0,0 +1,28 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 14
+VisualStudioVersion = 14.0.23107.0
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CUE.NET", "CUE.NET.csproj", "{70A266B5-E9D4-4EAA-A91A-947C0039FFB6}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|x64 = Debug|x64
+ Debug|x86 = Debug|x86
+ Release|x64 = Release|x64
+ Release|x86 = Release|x86
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {70A266B5-E9D4-4EAA-A91A-947C0039FFB6}.Debug|x64.ActiveCfg = Release|x64
+ {70A266B5-E9D4-4EAA-A91A-947C0039FFB6}.Debug|x64.Build.0 = Release|x64
+ {70A266B5-E9D4-4EAA-A91A-947C0039FFB6}.Debug|x86.ActiveCfg = Release|x86
+ {70A266B5-E9D4-4EAA-A91A-947C0039FFB6}.Debug|x86.Build.0 = Release|x86
+ {70A266B5-E9D4-4EAA-A91A-947C0039FFB6}.Release|x64.ActiveCfg = Release|x64
+ {70A266B5-E9D4-4EAA-A91A-947C0039FFB6}.Release|x64.Build.0 = Release|x64
+ {70A266B5-E9D4-4EAA-A91A-947C0039FFB6}.Release|x86.ActiveCfg = Release|x86
+ {70A266B5-E9D4-4EAA-A91A-947C0039FFB6}.Release|x86.Build.0 = Release|x86
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/Enums/CorsairAccessMode.cs b/Enums/CorsairAccessMode.cs
new file mode 100644
index 0000000..dc569f5
--- /dev/null
+++ b/Enums/CorsairAccessMode.cs
@@ -0,0 +1,13 @@
+// ReSharper disable InconsistentNaming
+// ReSharper disable UnusedMember.Global
+
+namespace CUE.NET.Enums
+{
+ ///
+ /// Contains list of available SDK access modes.
+ ///
+ public enum CorsairAccessMode
+ {
+ CAM_ExclusiveLightingControl = 0
+ };
+}
diff --git a/Enums/CorsairDeviceCaps.cs b/Enums/CorsairDeviceCaps.cs
new file mode 100644
index 0000000..4033771
--- /dev/null
+++ b/Enums/CorsairDeviceCaps.cs
@@ -0,0 +1,21 @@
+// ReSharper disable InconsistentNaming
+// ReSharper disable UnusedMember.Global
+
+namespace CUE.NET.Enums
+{
+ ///
+ /// Contains list of device capabilities
+ ///
+ public enum CorsairDeviceCaps
+ {
+ ///
+ /// For devices that do not support any SDK functions
+ ///
+ CDC_None = 0,
+
+ ///
+ /// For devices that has controlled lighting
+ ///
+ CDC_Lighting = 1
+ };
+}
diff --git a/Enums/CorsairDeviceType.cs b/Enums/CorsairDeviceType.cs
new file mode 100644
index 0000000..e0f415d
--- /dev/null
+++ b/Enums/CorsairDeviceType.cs
@@ -0,0 +1,16 @@
+// ReSharper disable InconsistentNaming
+// ReSharper disable UnusedMember.Global
+
+namespace CUE.NET.Enums
+{
+ ///
+ /// Contains list of available device types.
+ ///
+ public enum CorsairDeviceType
+ {
+ CDT_Unknown = 0,
+ CDT_Mouse = 1,
+ CDT_Keyboard = 2,
+ CDT_Headset = 3
+ };
+}
diff --git a/Enums/CorsairError.cs b/Enums/CorsairError.cs
new file mode 100644
index 0000000..5938f06
--- /dev/null
+++ b/Enums/CorsairError.cs
@@ -0,0 +1,42 @@
+// ReSharper disable InconsistentNaming
+// ReSharper disable UnusedMember.Global
+
+namespace CUE.NET.Enums
+{
+ ///
+ /// Shared list of all errors which could happen during calling of Corsair* functions.
+ ///
+ public enum CorsairError
+ {
+ ///
+ /// If previously called function completed successfully.
+ ///
+ CE_Success,
+
+ ///
+ /// CUE is not running or was shut down or third-party control is disabled in CUE settings. (runtime error)
+ ///
+ CE_ServerNotFound,
+
+ ///
+ /// If some other client has or took over exclusive control. (runtime error)
+ ///
+ CE_NoControl,
+
+ ///
+ /// If developer did not perform protocol handshake. (developer error)
+ ///
+ CE_ProtocolHandshakeMissing,
+
+ ///
+ /// If developer is calling the function that is not supported by the server (either because protocol has broken by server or client or because the function is new and server is too old.
+ /// Check CorsairProtocolDetails for details). (developer error)
+ ///
+ CE_IncompatibleProtocol,
+
+ ///
+ /// If developer supplied invalid arguments to the function (for specifics look at function descriptions). (developer error)
+ ///
+ CE_InvalidArguments
+ };
+}
diff --git a/Enums/CorsairLedId.cs b/Enums/CorsairLedId.cs
new file mode 100644
index 0000000..4b8909c
--- /dev/null
+++ b/Enums/CorsairLedId.cs
@@ -0,0 +1,166 @@
+// ReSharper disable UnusedMember.Global
+// ReSharper disable InconsistentNaming
+
+namespace CUE.NET.Enums
+{
+ public enum CorsairLedId
+ {
+ CLI_Invalid = 0,
+ CLK_Escape = 1,
+ CLK_F1 = 2,
+ CLK_F2 = 3,
+ CLK_F3 = 4,
+ CLK_F4 = 5,
+ CLK_F5 = 6,
+ CLK_F6 = 7,
+ CLK_F7 = 8,
+ CLK_F8 = 9,
+ CLK_F9 = 10,
+ CLK_F10 = 11,
+ CLK_F11 = 12,
+ CLK_GraveAccentAndTilde = 13,
+ CLK_1 = 14,
+ CLK_2 = 15,
+ CLK_3 = 16,
+ CLK_4 = 17,
+ CLK_5 = 18,
+ CLK_6 = 19,
+ CLK_7 = 20,
+ CLK_8 = 21,
+ CLK_9 = 22,
+ CLK_0 = 23,
+ CLK_MinusAndUnderscore = 24,
+ CLK_Tab = 25,
+ CLK_Q = 26,
+ CLK_W = 27,
+ CLK_E = 28,
+ CLK_R = 29,
+ CLK_T = 30,
+ CLK_Y = 31,
+ CLK_U = 32,
+ CLK_I = 33,
+ CLK_O = 34,
+ CLK_P = 35,
+ CLK_BracketLeft = 36,
+ CLK_CapsLock = 37,
+ CLK_A = 38,
+ CLK_S = 39,
+ CLK_D = 40,
+ CLK_F = 41,
+ CLK_G = 42,
+ CLK_H = 43,
+ CLK_J = 44,
+ CLK_K = 45,
+ CLK_L = 46,
+ CLK_SemicolonAndColon = 47,
+ CLK_ApostropheAndDoubleQuote = 48,
+ CLK_LeftShift = 49,
+ CLK_NonUsBackslash = 50,
+ CLK_Z = 51,
+ CLK_X = 52,
+ CLK_C = 53,
+ CLK_V = 54,
+ CLK_B = 55,
+ CLK_N = 56,
+ CLK_M = 57,
+ CLK_CommaAndLessThan = 58,
+ CLK_PeriodAndBiggerThan = 59,
+ CLK_SlashAndQuestionMark = 60,
+ CLK_LeftCtrl = 61,
+ CLK_LeftGui = 62,
+ CLK_LeftAlt = 63,
+ CLK_Lang2 = 64,
+ CLK_Space = 65,
+ CLK_Lang1 = 66,
+ CLK_International2 = 67,
+ CLK_RightAlt = 68,
+ CLK_RightGui = 69,
+ CLK_Application = 70,
+ CLK_LedProgramming = 71,
+ CLK_Brightness = 72,
+ CLK_F12 = 73,
+ CLK_PrintScreen = 74,
+ CLK_ScrollLock = 75,
+ CLK_PauseBreak = 76,
+ CLK_Insert = 77,
+ CLK_Home = 78,
+ CLK_PageUp = 79,
+ CLK_BracketRight = 80,
+ CLK_Backslash = 81,
+ CLK_NonUsTilde = 82,
+ CLK_Enter = 83,
+ CLK_International1 = 84,
+ CLK_EqualsAndPlus = 85,
+ CLK_International3 = 86,
+ CLK_Backspace = 87,
+ CLK_Delete = 88,
+ CLK_End = 89,
+ CLK_PageDown = 90,
+ CLK_RightShift = 91,
+ CLK_RightCtrl = 92,
+ CLK_UpArrow = 93,
+ CLK_LeftArrow = 94,
+ CLK_DownArrow = 95,
+ CLK_RightArrow = 96,
+ CLK_WinLock = 97,
+ CLK_Mute = 98,
+ CLK_Stop = 99,
+ CLK_ScanPreviousTrack = 100,
+ CLK_PlayPause = 101,
+ CLK_ScanNextTrack = 102,
+ CLK_NumLock = 103,
+ CLK_KeypadSlash = 104,
+ CLK_KeypadAsterisk = 105,
+ CLK_KeypadMinus = 106,
+ CLK_KeypadPlus = 107,
+ CLK_KeypadEnter = 108,
+ CLK_Keypad7 = 109,
+ CLK_Keypad8 = 110,
+ CLK_Keypad9 = 111,
+ CLK_KeypadComma = 112,
+ CLK_Keypad4 = 113,
+ CLK_Keypad5 = 114,
+ CLK_Keypad6 = 115,
+ CLK_Keypad1 = 116,
+ CLK_Keypad2 = 117,
+ CLK_Keypad3 = 118,
+ CLK_Keypad0 = 119,
+ CLK_KeypadPeriodAndDelete = 120,
+ CLK_G1 = 121,
+ CLK_G2 = 122,
+ CLK_G3 = 123,
+ CLK_G4 = 124,
+ CLK_G5 = 125,
+ CLK_G6 = 126,
+ CLK_G7 = 127,
+ CLK_G8 = 128,
+ CLK_G9 = 129,
+ CLK_G10 = 130,
+ CLK_VolumeUp = 131,
+ CLK_VolumeDown = 132,
+ CLK_MR = 133,
+ CLK_M1 = 134,
+ CLK_M2 = 135,
+ CLK_M3 = 136,
+ CLK_G11 = 137,
+ CLK_G12 = 138,
+ CLK_G13 = 139,
+ CLK_G14 = 140,
+ CLK_G15 = 141,
+ CLK_G16 = 142,
+ CLK_G17 = 143,
+ CLK_G18 = 144,
+ CLK_International5 = 145,
+ CLK_International4 = 146,
+ CLK_Fn = 147,
+ CLM_1 = 148,
+ CLM_2 = 149,
+ CLM_3 = 150,
+ CLM_4 = 151,
+ CLH_LeftLogo = 152,
+ CLH_RightLogo = 153,
+ CLK_Logo = 154,
+
+ CLI_Last = CLK_Logo
+ };
+}
diff --git a/Enums/CorsairLogicalLayout.cs b/Enums/CorsairLogicalLayout.cs
new file mode 100644
index 0000000..96d491e
--- /dev/null
+++ b/Enums/CorsairLogicalLayout.cs
@@ -0,0 +1,35 @@
+// ReSharper disable InconsistentNaming
+// ReSharper disable UnusedMember.Global
+
+namespace CUE.NET.Enums
+{
+ ///
+ /// Contains list of available logical layouts for keyboards.
+ ///
+ public enum CorsairLogicalLayout
+ {
+ ///
+ /// Dummy value
+ ///
+ CLL_Invalid = 0,
+
+ CLL_US_Int = 1,
+ CLL_NA = 2,
+ CLL_EU = 3,
+ CLL_UK = 4,
+ CLL_BE = 5,
+ CLL_BR = 6,
+ CLL_CH = 7,
+ CLL_CN = 8,
+ CLL_DE = 9,
+ CLL_ES = 10,
+ CLL_FR = 11,
+ CLL_IT = 12,
+ CLL_ND = 13,
+ CLL_RU = 14,
+ CLL_JP = 15,
+ CLL_KR = 16,
+ CLL_TW = 17,
+ CLL_MEX = 18
+ };
+}
diff --git a/Enums/CorsairPhysicalLayout.cs b/Enums/CorsairPhysicalLayout.cs
new file mode 100644
index 0000000..131eff8
--- /dev/null
+++ b/Enums/CorsairPhysicalLayout.cs
@@ -0,0 +1,61 @@
+// ReSharper disable InconsistentNaming
+// ReSharper disable UnusedMember.Global
+
+namespace CUE.NET.Enums
+{
+ ///
+ /// Contains list of available physical layouts for keyboards.
+ ///
+ public enum CorsairPhysicalLayout
+ {
+ ///
+ /// Dummy value
+ ///
+ CPL_Invalid = 0,
+
+ ///
+ /// US-Keyboard
+ ///
+ CPL_US = 1,
+
+ ///
+ /// UK-Keyboard
+ ///
+ CPL_UK = 2,
+
+ ///
+ /// BR-Keyboard
+ ///
+ CPL_BR = 3,
+
+ ///
+ /// JP-Keyboard
+ ///
+ CPL_JP = 4,
+
+ ///
+ /// KR-Keyboard
+ ///
+ CPL_KR = 5,
+
+ ///
+ /// Zone1-Mouse
+ ///
+ CPL_Zones1 = 6,
+
+ ///
+ /// Zone1-Mouse
+ ///
+ CPL_Zones2 = 7,
+
+ ///
+ /// Zone1-Mouse
+ ///
+ CPL_Zones3 = 8,
+
+ ///
+ /// Zone1-Mouse
+ ///
+ CPL_Zones4 = 9
+ };
+}
diff --git a/Exceptions/CUEException.cs b/Exceptions/CUEException.cs
new file mode 100644
index 0000000..5e1612c
--- /dev/null
+++ b/Exceptions/CUEException.cs
@@ -0,0 +1,26 @@
+// ReSharper disable UnusedAutoPropertyAccessor.Global
+// ReSharper disable MemberCanBePrivate.Global
+
+using System;
+using CUE.NET.Enums;
+
+namespace CUE.NET.Exceptions
+{
+ public class CUEException : ApplicationException
+ {
+ #region Properties & Fields
+
+ public CorsairError Error { get; }
+
+ #endregion
+
+ #region Constructors
+
+ public CUEException(CorsairError error)
+ {
+ this.Error = error;
+ }
+
+ #endregion
+ }
+}
diff --git a/Exceptions/WrapperException.cs b/Exceptions/WrapperException.cs
new file mode 100644
index 0000000..5fca300
--- /dev/null
+++ b/Exceptions/WrapperException.cs
@@ -0,0 +1,15 @@
+using System;
+
+namespace CUE.NET.Exceptions
+{
+ public class WrapperException : ApplicationException
+ {
+ #region Constructors
+
+ public WrapperException(string message, Exception innerException = null)
+ : base(message, innerException)
+ { }
+
+ #endregion
+ }
+}
diff --git a/Native/CUESDK.cs b/Native/CUESDK.cs
new file mode 100644
index 0000000..654871c
--- /dev/null
+++ b/Native/CUESDK.cs
@@ -0,0 +1,45 @@
+using System;
+using System.Runtime.InteropServices;
+using CUE.NET.Enums;
+
+namespace CUE.NET.Native
+{
+ // ReSharper disable once InconsistentNaming
+ internal static class CUESDK
+ {
+ // set specified leds to some colors. The color is retained until changed by successive calls. This function does not take logical layout into account
+ [DllImport("CUESDK.x64_2013.dll")]
+ public static extern bool CorsairSetLedsColors(int size, IntPtr ledsColors);
+
+ //[DllImport("CUESDK.x64_2013.dll")]
+ //public static extern bool CorsairSetLedsColorsAsync(int size, CorsairLedColor* ledsColors, void(*CallbackType)(void*, bool, CorsairError), void* context);
+
+ // returns number of connected Corsair devices that support lighting control.
+ [DllImport("CUESDK.x64_2013.dll")]
+ public static extern int CorsairGetDeviceCount();
+
+ // returns information about device at provided index
+ [DllImport("CUESDK.x64_2013.dll")]
+ public static extern IntPtr CorsairGetDeviceInfo(int deviceIndex);
+
+ // provides list of keyboard LEDs with their physical positions.
+ [DllImport("CUESDK.x64_2013.dll")]
+ public static extern IntPtr CorsairGetLedPositions();
+
+ // retrieves led id for key name taking logical layout into account.
+ [DllImport("CUESDK.x64_2013.dll")]
+ public static extern CorsairLedId CorsairGetLedIdForKeyName(char keyName);
+
+ // requestes control using specified access mode. By default client has shared control over lighting so there is no need to call CorsairRequestControl unless client requires exclusive control
+ [DllImport("CUESDK.x64_2013.dll")]
+ public static extern bool CorsairRequestControl(CorsairAccessMode accessMode);
+
+ // checks file and protocol version of CUE to understand which of SDK functions can be used with this version of CUE
+ [DllImport("CUESDK.x64_2013.dll")]
+ public static extern _CorsairProtocolDetails CorsairPerformProtocolHandshake();
+
+ // returns last error that occured while using any of Corsair* functions
+ [DllImport("CUESDK.x64_2013.dll")]
+ public static extern CorsairError CorsairGetLastError();
+ }
+}
diff --git a/Native/_CorsairDeviceInfo.cs b/Native/_CorsairDeviceInfo.cs
new file mode 100644
index 0000000..310bfb0
--- /dev/null
+++ b/Native/_CorsairDeviceInfo.cs
@@ -0,0 +1,21 @@
+#pragma warning disable 169 // Field 'x' is never used
+#pragma warning disable 414 // Field 'x' is assigned but its value never used
+#pragma warning disable 649 // Field 'x' is never assigned
+
+using System;
+using System.Runtime.InteropServices;
+using CUE.NET.Enums;
+
+namespace CUE.NET.Native
+{
+ // ReSharper disable once InconsistentNaming
+ [StructLayout(LayoutKind.Sequential)]
+ public class _CorsairDeviceInfo // contains information about device
+ {
+ internal CorsairDeviceType type; // enum describing device type
+ internal IntPtr model; // null - terminated device model(like “K95RGB”)
+ internal CorsairPhysicalLayout physicalLayout; // enum describing physical layout of the keyboard or mouse
+ internal CorsairLogicalLayout logicalLayout; // enum describing logical layout of the keyboard as set in CUE settings
+ internal int capsMask; // mask that describes device capabilities, formed as logical “or” of CorsairDeviceCaps enum values
+ }
+}
diff --git a/Native/_CorsairLedColor.cs b/Native/_CorsairLedColor.cs
new file mode 100644
index 0000000..4539ac3
--- /dev/null
+++ b/Native/_CorsairLedColor.cs
@@ -0,0 +1,20 @@
+#pragma warning disable 169 // Field 'x' is never used
+#pragma warning disable 414 // Field 'x' is assigned but its value never used
+#pragma warning disable 649 // Field 'x' is never assigned
+
+using System.Runtime.InteropServices;
+using CUE.NET.Enums;
+
+namespace CUE.NET.Native
+{
+ // ReSharper disable once InconsistentNaming
+ [StructLayout(LayoutKind.Sequential)]
+ public class _CorsairLedColor // contains information about led and its color
+ {
+
+ internal CorsairLedId ledId; // identifier of LED to set
+ internal int r; // red brightness[0..255]
+ internal int g; // green brightness[0..255]
+ internal int b; // blue brightness[0..255]
+ };
+}
diff --git a/Native/_CorsairLedPosition.cs b/Native/_CorsairLedPosition.cs
new file mode 100644
index 0000000..c57521e
--- /dev/null
+++ b/Native/_CorsairLedPosition.cs
@@ -0,0 +1,20 @@
+#pragma warning disable 169 // Field 'x' is never used
+#pragma warning disable 414 // Field 'x' is assigned but its value never used
+#pragma warning disable 649 // Field 'x' is never assigned
+
+using System.Runtime.InteropServices;
+using CUE.NET.Enums;
+
+namespace CUE.NET.Native
+{
+ // ReSharper disable once InconsistentNaming
+ [StructLayout(LayoutKind.Sequential)]
+ public class _CorsairLedPosition // contains led id and position of led rectangle.Most of the keys are rectangular. In case if key is not rectangular(like Enter in ISO / UK layout) it returns the smallest rectangle that fully contains the key
+ {
+ internal CorsairLedId ledId; // identifier of led
+ internal double top;
+ internal double left;
+ internal double height;
+ internal double width; // values in mm
+ }
+}
diff --git a/Native/_CorsairLedPositions.cs b/Native/_CorsairLedPositions.cs
new file mode 100644
index 0000000..d299e25
--- /dev/null
+++ b/Native/_CorsairLedPositions.cs
@@ -0,0 +1,17 @@
+#pragma warning disable 169 // Field 'x' is never used
+#pragma warning disable 414 // Field 'x' is assigned but its value never used
+#pragma warning disable 649 // Field 'x' is never assigned
+
+using System;
+using System.Runtime.InteropServices;
+
+namespace CUE.NET.Native
+{
+ // ReSharper disable once InconsistentNaming
+ [StructLayout(LayoutKind.Sequential)]
+ public class _CorsairLedPositions // contains number of leds and arrays with their positions
+ {
+ internal int numberOfLed; // integer value.Number of elements in following array
+ internal IntPtr pLedPosition; // array of led positions
+ }
+}
diff --git a/Native/_CorsairProtocolDetails.cs b/Native/_CorsairProtocolDetails.cs
new file mode 100644
index 0000000..92fa888
--- /dev/null
+++ b/Native/_CorsairProtocolDetails.cs
@@ -0,0 +1,20 @@
+#pragma warning disable 169 // Field 'x' is never used
+#pragma warning disable 414 // Field 'x' is assigned but its value never used
+#pragma warning disable 649 // Field 'x' is never assigned
+
+using System;
+using System.Runtime.InteropServices;
+
+namespace CUE.NET.Native
+{
+ // ReSharper disable once InconsistentNaming
+ [StructLayout(LayoutKind.Sequential)]
+ internal struct _CorsairProtocolDetails // contains information about SDK and CUE versions
+ {
+ internal IntPtr sdkVersion; // null - terminated string containing version of SDK(like “1.0.0.1”). Always contains valid value even if there was no CUE found
+ internal IntPtr serverVersion; // null - terminated string containing version of CUE(like “1.0.0.1”) or NULL if CUE was not found.
+ internal int sdkProtocolVersion; // integer number that specifies version of protocol that is implemented by current SDK. Numbering starts from 1. Always contains valid value even if there was no CUE found
+ internal int serverProtocolVersion; // integer number that specifies version of protocol that is implemented by CUE. Numbering starts from 1. If CUE was not found then this value will be 0
+ internal byte breakingChanges; // boolean value that specifies if there were breaking changes between version of protocol implemented by server and client
+ };
+}
diff --git a/Properties/AssemblyInfo.cs b/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..bdc9790
--- /dev/null
+++ b/Properties/AssemblyInfo.cs
@@ -0,0 +1,35 @@
+using System.Reflection;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("CUE.NET")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Wyrez")]
+[assembly: AssemblyProduct("CUE.NET")]
+[assembly: AssemblyCopyright("Copyright © Wyrez 2015")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("70a266b5-e9d4-4eaa-a91a-947c0039ffb6")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/Wrapper/AbstractCueDevice.cs b/Wrapper/AbstractCueDevice.cs
new file mode 100644
index 0000000..d6e42ec
--- /dev/null
+++ b/Wrapper/AbstractCueDevice.cs
@@ -0,0 +1,24 @@
+namespace CUE.NET.Wrapper
+{
+ public abstract class AbstractCueDevice : ICueDevice
+ {
+ #region Properties & Fields
+
+ public CorsairDeviceInfo DeviceInfo { get; }
+
+ #endregion
+
+ #region Constructors
+
+ protected AbstractCueDevice(CorsairDeviceInfo info)
+ {
+ this.DeviceInfo = info;
+ }
+
+ #endregion
+
+ #region Methods
+
+ #endregion
+ }
+}
diff --git a/Wrapper/CorsairDeviceInfo.cs b/Wrapper/CorsairDeviceInfo.cs
new file mode 100644
index 0000000..574175e
--- /dev/null
+++ b/Wrapper/CorsairDeviceInfo.cs
@@ -0,0 +1,57 @@
+// ReSharper disable MemberCanBePrivate.Global
+// ReSharper disable UnusedAutoPropertyAccessor.Global
+
+using System;
+using System.Runtime.InteropServices;
+using CUE.NET.Enums;
+using CUE.NET.Native;
+
+namespace CUE.NET.Wrapper
+{
+ public class CorsairDeviceInfo
+ {
+ #region Properties & Fields
+
+ ///
+ /// Device type.
+ ///
+ public CorsairDeviceType Type { get; private set; }
+
+ //TODO DarthAffe 17.09.2015: This could be an Enum
+ ///
+ /// Device model (like “K95RGB”).
+ ///
+ public string Model { get; private set; }
+
+ ///
+ /// Physical layout of the keyboard or mouse.
+ ///
+ public CorsairPhysicalLayout PhysicalLayout { get; private set; }
+
+ //TODO DarthAffe 17.09.2015: Would device-specific infos be useful?
+ ///
+ /// Logical layout of the keyboard as set in CUE settings.
+ ///
+ public CorsairLogicalLayout LogicalLayout { get; private set; }
+
+ ///
+ /// Mask that describes device capabilities, formed as logical "or" of CorsairDeviceCaps enum values
+ ///
+ public int CapsMask { get; private set; }
+
+ #endregion
+
+ #region Constructors
+
+ public CorsairDeviceInfo(_CorsairDeviceInfo nativeInfo)
+ {
+ this.Type = nativeInfo.type;
+ this.Model = nativeInfo.model == IntPtr.Zero ? null : Marshal.PtrToStringAuto(nativeInfo.model);
+ this.PhysicalLayout = nativeInfo.physicalLayout;
+ this.LogicalLayout = nativeInfo.logicalLayout;
+ this.CapsMask = nativeInfo.capsMask;
+ }
+
+ #endregion
+ }
+}
diff --git a/Wrapper/CorsairProtocolDetails.cs b/Wrapper/CorsairProtocolDetails.cs
new file mode 100644
index 0000000..ea31c73
--- /dev/null
+++ b/Wrapper/CorsairProtocolDetails.cs
@@ -0,0 +1,66 @@
+// ReSharper disable MemberCanBePrivate.Global
+// ReSharper disable UnusedAutoPropertyAccessor.Global
+
+using System;
+using System.Runtime.InteropServices;
+using CUE.NET.Native;
+
+namespace CUE.NET.Wrapper
+{
+ ///
+ /// Managed wrapper for CorsairProtocolDetails.
+ ///
+ public class CorsairProtocolDetails
+ {
+ #region Properties & Fields
+
+ ///
+ /// String containing version of SDK(like “1.0.0.1”).
+ /// Always contains valid value even if there was no CUE found.
+ ///
+ public string SdkVersion { get; }
+
+ ///
+ /// String containing version of CUE(like “1.0.0.1”) or NULL if CUE was not found.
+ ///
+ public string ServerVersion { get; }
+
+ ///
+ /// Integer that specifies version of protocol that is implemented by current SDK.
+ /// Numbering starts from 1.
+ /// Always contains valid value even if there was no CUE found.
+ ///
+ public int SdkProtocolVersion { get; }
+
+ ///
+ /// Integer that specifies version of protocol that is implemented by CUE.
+ /// Numbering starts from 1.
+ /// If CUE was not found then this value will be 0.
+ ///
+ public int ServerProtocolVersion { get; }
+
+ ///
+ /// Boolean that specifies if there were breaking changes between version of protocol implemented by server and client.
+ ///
+ public byte BreakingChanges { get; }
+
+ #endregion
+
+ #region Constructors
+
+ ///
+ /// Internal constructor of managed CorsairProtocolDetails.
+ ///
+ /// The native CorsairProtocolDetails-struct
+ internal CorsairProtocolDetails(_CorsairProtocolDetails nativeDetails)
+ {
+ this.SdkVersion = nativeDetails.sdkVersion == IntPtr.Zero ? null : Marshal.PtrToStringAuto(nativeDetails.sdkVersion);
+ this.ServerVersion = nativeDetails.serverVersion == IntPtr.Zero ? null : Marshal.PtrToStringAuto(nativeDetails.serverVersion);
+ this.SdkProtocolVersion = nativeDetails.sdkProtocolVersion;
+ this.ServerProtocolVersion = nativeDetails.serverProtocolVersion;
+ this.BreakingChanges = nativeDetails.breakingChanges;
+ }
+
+ #endregion
+ }
+}
diff --git a/Wrapper/CueHeadset.cs b/Wrapper/CueHeadset.cs
new file mode 100644
index 0000000..e0651a5
--- /dev/null
+++ b/Wrapper/CueHeadset.cs
@@ -0,0 +1,22 @@
+namespace CUE.NET.Wrapper
+{
+ //TODO DarthAffe 18.09.2015: Implement
+ public class CueHeadset : AbstractCueDevice
+ {
+ #region Properties & Fields
+
+ #endregion
+
+ #region Constructors
+
+ public CueHeadset(CorsairDeviceInfo info)
+ : base(info)
+ { }
+
+ #endregion
+
+ #region Methods
+
+ #endregion
+ }
+}
diff --git a/Wrapper/CueKeyboard.cs b/Wrapper/CueKeyboard.cs
new file mode 100644
index 0000000..721e6a7
--- /dev/null
+++ b/Wrapper/CueKeyboard.cs
@@ -0,0 +1,38 @@
+using System;
+using System.Drawing;
+using System.Runtime.InteropServices;
+using CUE.NET.Enums;
+using CUE.NET.Native;
+
+namespace CUE.NET.Wrapper
+{
+ public class CueKeyboard : AbstractCueDevice
+ {
+ #region Properties & Fields
+
+ #endregion
+
+ #region Constructors
+
+ public CueKeyboard(CorsairDeviceInfo info)
+ : base(info)
+ { }
+
+ #endregion
+
+ #region Methods
+
+ public void SetKeyColor(char key, Color color)
+ {
+ CorsairLedId id = CUESDK.CorsairGetLedIdForKeyName(key);
+ _CorsairLedColor ledColor = new _CorsairLedColor { ledId = id, r = color.R, g = color.G, b = color.B };
+
+ //TODO DarthAffe 18.09.2015: Generalize and move to base class
+ IntPtr ptr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(_CorsairLedColor)));
+ Marshal.StructureToPtr(ledColor, ptr, true);
+ CUESDK.CorsairSetLedsColors(1, ptr);
+ }
+
+ #endregion
+ }
+}
diff --git a/Wrapper/CueMouse.cs b/Wrapper/CueMouse.cs
new file mode 100644
index 0000000..ebe440c
--- /dev/null
+++ b/Wrapper/CueMouse.cs
@@ -0,0 +1,22 @@
+namespace CUE.NET.Wrapper
+{
+ //TODO DarthAffe 18.09.2015: Implement
+ public class CueMouse : AbstractCueDevice
+ {
+ #region Properties & Fields
+
+ #endregion
+
+ #region Constructors
+
+ public CueMouse(CorsairDeviceInfo info)
+ : base(info)
+ { }
+
+ #endregion
+
+ #region Methods
+
+ #endregion
+ }
+}
diff --git a/Wrapper/CueSDK.cs b/Wrapper/CueSDK.cs
new file mode 100644
index 0000000..6ffed46
--- /dev/null
+++ b/Wrapper/CueSDK.cs
@@ -0,0 +1,90 @@
+// ReSharper disable MemberCanBePrivate.Global
+
+using System.Runtime.InteropServices;
+using CUE.NET.Enums;
+using CUE.NET.Exceptions;
+using CUE.NET.Native;
+
+namespace CUE.NET.Wrapper
+{
+ public static class CueSDK
+ {
+ #region Properties & Fields
+
+ // ReSharper disable UnusedAutoPropertyAccessor.Global
+
+ public static CorsairProtocolDetails ProtocolDetails { get; private set; }
+ public static bool HasExclusiveAccess { get; private set; }
+ public static CorsairError LastError => CUESDK.CorsairGetLastError();
+
+ public static CueKeyboard KeyboardSDK { get; private set; }
+ public static CueMouse MouseSDK { get; private set; }
+ public static CueHeadset HeadsetSDK { get; private set; }
+
+ // ReSharper restore UnusedAutoPropertyAccessor.Global
+
+ #endregion
+
+ #region Methods
+
+ public static void Initialize(bool exclusiveAccess = false)
+ {
+ if (ProtocolDetails != null)
+ throw new WrapperException("CueSDK is already initialized.");
+
+ ProtocolDetails = new CorsairProtocolDetails(CUESDK.CorsairPerformProtocolHandshake());
+
+ CorsairError error = LastError;
+ if (error != CorsairError.CE_Success)
+ Throw(error);
+
+ if (exclusiveAccess)
+ {
+ if (!CUESDK.CorsairRequestControl(CorsairAccessMode.CAM_ExclusiveLightingControl))
+ Throw(error);
+
+ HasExclusiveAccess = true;
+ }
+
+ int deviceCount = CUESDK.CorsairGetDeviceCount();
+ for (int i = 0; i < deviceCount; i++)
+ {
+ CorsairDeviceInfo info = new CorsairDeviceInfo((_CorsairDeviceInfo)Marshal.PtrToStructure(CUESDK.CorsairGetDeviceInfo(i), typeof(_CorsairDeviceInfo)));
+ switch (info.Type)
+ {
+ case CorsairDeviceType.CDT_Keyboard:
+ KeyboardSDK = new CueKeyboard(info);
+ break;
+ case CorsairDeviceType.CDT_Mouse:
+ MouseSDK = new CueMouse(info);
+ break;
+ case CorsairDeviceType.CDT_Headset:
+ HeadsetSDK = new CueHeadset(info);
+ break;
+
+ // ReSharper disable once RedundantCaseLabel
+ case CorsairDeviceType.CDT_Unknown:
+ default:
+ throw new WrapperException("Unknown Device-Type");
+ }
+
+ error = LastError;
+ if (error != CorsairError.CE_Success)
+ Throw(error);
+ }
+ }
+
+ private static void Throw(CorsairError error)
+ {
+ ProtocolDetails = null;
+ HasExclusiveAccess = false;
+ KeyboardSDK = null;
+ MouseSDK = null;
+ HeadsetSDK = null;
+
+ throw new CUEException(error);
+ }
+
+ #endregion
+ }
+}
diff --git a/Wrapper/ICueDevice.cs b/Wrapper/ICueDevice.cs
new file mode 100644
index 0000000..dc36911
--- /dev/null
+++ b/Wrapper/ICueDevice.cs
@@ -0,0 +1,7 @@
+namespace CUE.NET.Wrapper
+{
+ public interface ICueDevice
+ {
+ CorsairDeviceInfo DeviceInfo { get; }
+ }
+}
diff --git a/libs/CUESDK.x64_2013.dll b/libs/CUESDK.x64_2013.dll
new file mode 100644
index 0000000..64fbe92
Binary files /dev/null and b/libs/CUESDK.x64_2013.dll differ
diff --git a/libs/CUESDK_2013.dll b/libs/CUESDK_2013.dll
new file mode 100644
index 0000000..c2dbf62
Binary files /dev/null and b/libs/CUESDK_2013.dll differ