mirror of
https://github.com/DarthAffe/RGB.NET.git
synced 2025-12-12 17:48:31 +00:00
Streamlined usage of NativeLibrary; Changed all device providers to use function pointers when possible
This commit is contained in:
parent
4dc04286b7
commit
200631fbdb
@ -16,14 +16,14 @@ internal static class _CoolerMasterSDK
|
||||
{
|
||||
#region Libary Management
|
||||
|
||||
private static IntPtr _dllHandle = IntPtr.Zero;
|
||||
private static IntPtr _handle = IntPtr.Zero;
|
||||
|
||||
/// <summary>
|
||||
/// Reloads the SDK.
|
||||
/// </summary>
|
||||
internal static void Reload()
|
||||
{
|
||||
if (_dllHandle != IntPtr.Zero)
|
||||
if (_handle != IntPtr.Zero)
|
||||
{
|
||||
foreach (CoolerMasterDevicesIndexes index in Enum.GetValues(typeof(CoolerMasterDevicesIndexes)))
|
||||
EnableLedControl(false, index);
|
||||
@ -34,7 +34,7 @@ internal static class _CoolerMasterSDK
|
||||
|
||||
private static void LoadCMSDK()
|
||||
{
|
||||
if (_dllHandle != IntPtr.Zero) return;
|
||||
if (_handle != IntPtr.Zero) return;
|
||||
|
||||
// HACK: Load library at runtime to support both, x86 and x64 with one managed dll
|
||||
List<string> possiblePathList = (Environment.Is64BitProcess ? CoolerMasterDeviceProvider.PossibleX64NativePaths : CoolerMasterDeviceProvider.PossibleX86NativePaths)
|
||||
@ -43,22 +43,43 @@ internal static class _CoolerMasterSDK
|
||||
string? dllPath = possiblePathList.FirstOrDefault(File.Exists);
|
||||
if (dllPath == null) throw new RGBDeviceException($"Can't find the CoolerMaster-SDK at one of the expected locations:\r\n '{string.Join("\r\n", possiblePathList.Select(Path.GetFullPath))}'");
|
||||
|
||||
_dllHandle = LoadLibrary(dllPath);
|
||||
if (_dllHandle == IntPtr.Zero) throw new RGBDeviceException($"CoolerMaster LoadLibrary failed with error code {Marshal.GetLastWin32Error()}");
|
||||
_handle = LoadLibrary(dllPath);
|
||||
#if NET6_0
|
||||
if (_handle == IntPtr.Zero) throw new RGBDeviceException($"CoolerMaster LoadLibrary failed with error code {Marshal.GetLastPInvokeError()}");
|
||||
#else
|
||||
if (_handle == IntPtr.Zero) throw new RGBDeviceException($"CoolerMaster LoadLibrary failed with error code {Marshal.GetLastWin32Error()}");
|
||||
#endif
|
||||
|
||||
_getSDKVersionPointer = (GetSDKVersionPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "GetCM_SDK_DllVer"), typeof(GetSDKVersionPointer));
|
||||
_setControlDevicenPointer = (SetControlDevicePointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "SetControlDevice"), typeof(SetControlDevicePointer));
|
||||
_isDevicePlugPointer = (IsDevicePlugPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "IsDevicePlug"), typeof(IsDevicePlugPointer));
|
||||
_getDeviceLayoutPointer = (GetDeviceLayoutPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "GetDeviceLayout"), typeof(GetDeviceLayoutPointer));
|
||||
_enableLedControlPointer = (EnableLedControlPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "EnableLedControl"), typeof(EnableLedControlPointer));
|
||||
_refreshLedPointer = (RefreshLedPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "RefreshLed"), typeof(RefreshLedPointer));
|
||||
_setLedColorPointer = (SetLedColorPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "SetLedColor"), typeof(SetLedColorPointer));
|
||||
_setAllLedColorPointer = (SetAllLedColorPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "SetAllLedColor"), typeof(SetAllLedColorPointer));
|
||||
_getSDKVersionPointer = (GetSDKVersionPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_handle, "GetCM_SDK_DllVer"), typeof(GetSDKVersionPointer));
|
||||
_setControlDevicenPointer = (SetControlDevicePointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_handle, "SetControlDevice"), typeof(SetControlDevicePointer));
|
||||
_isDevicePlugPointer = (IsDevicePlugPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_handle, "IsDevicePlug"), typeof(IsDevicePlugPointer));
|
||||
_getDeviceLayoutPointer = (GetDeviceLayoutPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_handle, "GetDeviceLayout"), typeof(GetDeviceLayoutPointer));
|
||||
_enableLedControlPointer = (EnableLedControlPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_handle, "EnableLedControl"), typeof(EnableLedControlPointer));
|
||||
_refreshLedPointer = (RefreshLedPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_handle, "RefreshLed"), typeof(RefreshLedPointer));
|
||||
_setLedColorPointer = (SetLedColorPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_handle, "SetLedColor"), typeof(SetLedColorPointer));
|
||||
_setAllLedColorPointer = (SetAllLedColorPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_handle, "SetAllLedColor"), typeof(SetAllLedColorPointer));
|
||||
}
|
||||
|
||||
internal static void UnloadCMSDK()
|
||||
{
|
||||
if (_handle == IntPtr.Zero) return;
|
||||
|
||||
_getSDKVersionPointer = null;
|
||||
_setControlDevicenPointer = null;
|
||||
_isDevicePlugPointer = null;
|
||||
_getDeviceLayoutPointer = null;
|
||||
_enableLedControlPointer = null;
|
||||
_refreshLedPointer = null;
|
||||
_setLedColorPointer = null;
|
||||
_setAllLedColorPointer = null;
|
||||
|
||||
NativeLibrary.Free(_handle);
|
||||
_handle = IntPtr.Zero;
|
||||
}
|
||||
|
||||
[DllImport("kernel32.dll", CharSet = CharSet.Unicode)]
|
||||
private static extern IntPtr LoadLibrary(string dllToLoad);
|
||||
|
||||
|
||||
[DllImport("kernel32.dll", CharSet = CharSet.Ansi)]
|
||||
private static extern IntPtr GetProcAddress(IntPtr dllHandle, string name);
|
||||
|
||||
|
||||
@ -16,7 +16,7 @@ internal static class _CUESDK
|
||||
{
|
||||
#region Libary Management
|
||||
|
||||
private static IntPtr _dllHandle = IntPtr.Zero;
|
||||
private static IntPtr _handle = IntPtr.Zero;
|
||||
|
||||
/// <summary>
|
||||
/// Reloads the SDK.
|
||||
@ -29,113 +29,88 @@ internal static class _CUESDK
|
||||
|
||||
private static void LoadCUESDK()
|
||||
{
|
||||
if (_dllHandle != IntPtr.Zero) return;
|
||||
if (_handle != IntPtr.Zero) return;
|
||||
|
||||
List<string> possiblePathList = GetPossibleLibraryPaths().ToList();
|
||||
|
||||
// HACK: Load library at runtime to support both, x86 and x64 with one managed dll
|
||||
List<string> possiblePathList = (Environment.Is64BitProcess ? CorsairDeviceProvider.PossibleX64NativePaths : CorsairDeviceProvider.PossibleX86NativePaths)
|
||||
.Select(Environment.ExpandEnvironmentVariables)
|
||||
.ToList();
|
||||
string? dllPath = possiblePathList.FirstOrDefault(File.Exists);
|
||||
if (dllPath == null) throw new RGBDeviceException($"Can't find the CUE-SDK at one of the expected locations:\r\n '{string.Join("\r\n", possiblePathList.Select(Path.GetFullPath))}'");
|
||||
|
||||
_dllHandle = LoadLibrary(dllPath);
|
||||
if (_dllHandle == IntPtr.Zero) throw new RGBDeviceException($"Corsair LoadLibrary failed with error code {Marshal.GetLastWin32Error()}");
|
||||
if (!NativeLibrary.TryLoad(dllPath, out _handle))
|
||||
#if NET6_0
|
||||
throw new RGBDeviceException($"Corsair LoadLibrary failed with error code {Marshal.GetLastPInvokeError()}");
|
||||
#else
|
||||
throw new RGBDeviceException($"Corsair LoadLibrary failed with error code {Marshal.GetLastWin32Error()}");
|
||||
#endif
|
||||
|
||||
_corsairSetLedsColorsBufferByDeviceIndexPointer = (CorsairSetLedsColorsBufferByDeviceIndexPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "CorsairSetLedsColorsBufferByDeviceIndex"), typeof(CorsairSetLedsColorsBufferByDeviceIndexPointer));
|
||||
_corsairSetLedsColorsFlushBufferPointer = (CorsairSetLedsColorsFlushBufferPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "CorsairSetLedsColorsFlushBuffer"), typeof(CorsairSetLedsColorsFlushBufferPointer));
|
||||
_corsairGetLedsColorsByDeviceIndexPointer = (CorsairGetLedsColorsByDeviceIndexPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "CorsairGetLedsColorsByDeviceIndex"), typeof(CorsairGetLedsColorsByDeviceIndexPointer));
|
||||
_corsairSetLayerPriorityPointer = (CorsairSetLayerPriorityPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "CorsairSetLayerPriority"), typeof(CorsairSetLayerPriorityPointer));
|
||||
_corsairGetDeviceCountPointer = (CorsairGetDeviceCountPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "CorsairGetDeviceCount"), typeof(CorsairGetDeviceCountPointer));
|
||||
_corsairGetDeviceInfoPointer = (CorsairGetDeviceInfoPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "CorsairGetDeviceInfo"), typeof(CorsairGetDeviceInfoPointer));
|
||||
_corsairGetLedPositionsByDeviceIndexPointer = (CorsairGetLedPositionsByDeviceIndexPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "CorsairGetLedPositionsByDeviceIndex"), typeof(CorsairGetLedPositionsByDeviceIndexPointer));
|
||||
_corsairGetLedIdForKeyNamePointer = (CorsairGetLedIdForKeyNamePointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "CorsairGetLedIdForKeyName"), typeof(CorsairGetLedIdForKeyNamePointer));
|
||||
_corsairRequestControlPointer = (CorsairRequestControlPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "CorsairRequestControl"), typeof(CorsairRequestControlPointer));
|
||||
_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));
|
||||
if (!NativeLibrary.TryGetExport(_handle, "CorsairSetLedsColorsBufferByDeviceIndex", out _corsairSetLedsColorsBufferByDeviceIndexPointer)) throw new RGBDeviceException("Failed to load Corsair function 'CorsairSetLedsColorsBufferByDeviceIndex'");
|
||||
if (!NativeLibrary.TryGetExport(_handle, "CorsairSetLedsColorsFlushBuffer", out _corsairSetLedsColorsFlushBufferPointer)) throw new RGBDeviceException("Failed to load Corsair function 'CorsairSetLedsColorsFlushBuffer'");
|
||||
if (!NativeLibrary.TryGetExport(_handle, "CorsairGetLedsColorsByDeviceIndex", out _corsairGetLedsColorsByDeviceIndexPointer)) throw new RGBDeviceException("Failed to load Corsair function 'CorsairGetLedsColorsByDeviceIndex'");
|
||||
if (!NativeLibrary.TryGetExport(_handle, "CorsairSetLayerPriority", out _corsairSetLayerPriorityPointer)) throw new RGBDeviceException("Failed to load Corsair function 'CorsairSetLayerPriority'");
|
||||
if (!NativeLibrary.TryGetExport(_handle, "CorsairGetDeviceCount", out _corsairGetDeviceCountPointer)) throw new RGBDeviceException("Failed to load Corsair function 'CorsairGetDeviceCount'");
|
||||
if (!NativeLibrary.TryGetExport(_handle, "CorsairGetDeviceInfo", out _corsairGetDeviceInfoPointer)) throw new RGBDeviceException("Failed to load Corsair function 'CorsairGetDeviceInfo'");
|
||||
if (!NativeLibrary.TryGetExport(_handle, "CorsairGetLedIdForKeyName", out _corsairGetLedIdForKeyNamePointer)) throw new RGBDeviceException("Failed to load Corsair function 'CorsairGetLedIdForKeyName'");
|
||||
if (!NativeLibrary.TryGetExport(_handle, "CorsairGetLedPositionsByDeviceIndex", out _corsairGetLedPositionsByDeviceIndexPointer)) throw new RGBDeviceException("Failed to load Corsair function 'CorsairGetLedPositionsByDeviceIndex'");
|
||||
if (!NativeLibrary.TryGetExport(_handle, "CorsairRequestControl", out _corsairRequestControlPointer)) throw new RGBDeviceException("Failed to load Corsair function 'CorsairRequestControl'");
|
||||
if (!NativeLibrary.TryGetExport(_handle, "CorsairReleaseControl", out _corsairReleaseControlPointer)) throw new RGBDeviceException("Failed to load Corsair function 'CorsairReleaseControl'");
|
||||
if (!NativeLibrary.TryGetExport(_handle, "CorsairPerformProtocolHandshake", out _corsairPerformProtocolHandshakePointer)) throw new RGBDeviceException("Failed to load Corsair function 'CorsairPerformProtocolHandshake'");
|
||||
if (!NativeLibrary.TryGetExport(_handle, "CorsairGetLastError", out _corsairGetLastErrorPointer)) throw new RGBDeviceException("Failed to load Corsair function 'CorsairGetLastError'");
|
||||
}
|
||||
|
||||
private static IEnumerable<string> GetPossibleLibraryPaths()
|
||||
{
|
||||
IEnumerable<string> possibleLibraryPaths;
|
||||
|
||||
if (OperatingSystem.IsWindows())
|
||||
possibleLibraryPaths = Environment.Is64BitProcess ? CorsairDeviceProvider.PossibleX64NativePaths : CorsairDeviceProvider.PossibleX86NativePaths;
|
||||
else
|
||||
possibleLibraryPaths = Enumerable.Empty<string>();
|
||||
|
||||
return possibleLibraryPaths.Select(Environment.ExpandEnvironmentVariables);
|
||||
}
|
||||
|
||||
internal static void UnloadCUESDK()
|
||||
{
|
||||
if (_dllHandle == IntPtr.Zero) return;
|
||||
if (_handle == 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;
|
||||
_corsairSetLedsColorsBufferByDeviceIndexPointer = IntPtr.Zero;
|
||||
_corsairSetLedsColorsFlushBufferPointer = IntPtr.Zero;
|
||||
_corsairGetLedsColorsByDeviceIndexPointer = IntPtr.Zero;
|
||||
_corsairSetLayerPriorityPointer = IntPtr.Zero;
|
||||
_corsairGetDeviceCountPointer = IntPtr.Zero;
|
||||
_corsairGetDeviceInfoPointer = IntPtr.Zero;
|
||||
_corsairGetLedIdForKeyNamePointer = IntPtr.Zero;
|
||||
_corsairGetLedPositionsByDeviceIndexPointer = IntPtr.Zero;
|
||||
_corsairRequestControlPointer = IntPtr.Zero;
|
||||
_corsairReleaseControlPointer = IntPtr.Zero;
|
||||
_corsairPerformProtocolHandshakePointer = IntPtr.Zero;
|
||||
_corsairGetLastErrorPointer = IntPtr.Zero;
|
||||
|
||||
NativeLibrary.Free(_handle);
|
||||
_handle = IntPtr.Zero;
|
||||
}
|
||||
|
||||
[DllImport("kernel32.dll", CharSet = CharSet.Unicode)]
|
||||
private static extern IntPtr LoadLibrary(string dllToLoad);
|
||||
|
||||
[DllImport("kernel32.dll")]
|
||||
private static extern bool FreeLibrary(IntPtr dllHandle);
|
||||
|
||||
[DllImport("kernel32.dll", CharSet = CharSet.Ansi)]
|
||||
private static extern IntPtr GetProcAddress(IntPtr dllHandle, string name);
|
||||
|
||||
#endregion
|
||||
|
||||
#region SDK-METHODS
|
||||
|
||||
#region Pointers
|
||||
|
||||
private static CorsairSetLedsColorsBufferByDeviceIndexPointer? _corsairSetLedsColorsBufferByDeviceIndexPointer;
|
||||
private static CorsairSetLedsColorsFlushBufferPointer? _corsairSetLedsColorsFlushBufferPointer;
|
||||
private static CorsairGetLedsColorsByDeviceIndexPointer? _corsairGetLedsColorsByDeviceIndexPointer;
|
||||
private static CorsairSetLayerPriorityPointer? _corsairSetLayerPriorityPointer;
|
||||
private static CorsairGetDeviceCountPointer? _corsairGetDeviceCountPointer;
|
||||
private static CorsairGetDeviceInfoPointer? _corsairGetDeviceInfoPointer;
|
||||
private static CorsairGetLedIdForKeyNamePointer? _corsairGetLedIdForKeyNamePointer;
|
||||
private static CorsairGetLedPositionsByDeviceIndexPointer? _corsairGetLedPositionsByDeviceIndexPointer;
|
||||
private static CorsairRequestControlPointer? _corsairRequestControlPointer;
|
||||
private static CorsairReleaseControlPointer? _corsairReleaseControlPointer;
|
||||
private static CorsairPerformProtocolHandshakePointer? _corsairPerformProtocolHandshakePointer;
|
||||
private static CorsairGetLastErrorPointer? _corsairGetLastErrorPointer;
|
||||
private static IntPtr _corsairSetLedsColorsBufferByDeviceIndexPointer;
|
||||
private static IntPtr _corsairSetLedsColorsFlushBufferPointer;
|
||||
private static IntPtr _corsairGetLedsColorsByDeviceIndexPointer;
|
||||
private static IntPtr _corsairSetLayerPriorityPointer;
|
||||
private static IntPtr _corsairGetDeviceCountPointer;
|
||||
private static IntPtr _corsairGetDeviceInfoPointer;
|
||||
private static IntPtr _corsairGetLedIdForKeyNamePointer;
|
||||
private static IntPtr _corsairGetLedPositionsByDeviceIndexPointer;
|
||||
private static IntPtr _corsairRequestControlPointer;
|
||||
private static IntPtr _corsairReleaseControlPointer;
|
||||
private static IntPtr _corsairPerformProtocolHandshakePointer;
|
||||
private static IntPtr _corsairGetLastErrorPointer;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Delegates
|
||||
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
private delegate bool CorsairSetLedsColorsBufferByDeviceIndexPointer(int deviceIndex, int size, IntPtr ledsColors);
|
||||
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
private delegate bool CorsairSetLedsColorsFlushBufferPointer();
|
||||
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
private delegate bool CorsairGetLedsColorsByDeviceIndexPointer(int deviceIndex, int size, IntPtr ledsColors);
|
||||
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
private delegate bool CorsairSetLayerPriorityPointer(int priority);
|
||||
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
private delegate int CorsairGetDeviceCountPointer();
|
||||
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
private delegate IntPtr CorsairGetDeviceInfoPointer(int deviceIndex);
|
||||
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
private delegate IntPtr CorsairGetLedPositionsByDeviceIndexPointer(int deviceIndex);
|
||||
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
private delegate CorsairLedId CorsairGetLedIdForKeyNamePointer(char keyName);
|
||||
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
private delegate bool CorsairRequestControlPointer(CorsairAccessMode accessMode);
|
||||
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
private delegate bool CorsairReleaseControlPointer(CorsairAccessMode accessMode);
|
||||
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
private delegate _CorsairProtocolDetails CorsairPerformProtocolHandshakePointer();
|
||||
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
private delegate CorsairError CorsairGetLastErrorPointer();
|
||||
|
||||
#endregion
|
||||
|
||||
// ReSharper disable EventExceptionNotDocumented
|
||||
|
||||
/// <summary>
|
||||
/// CUE-SDK: set specified LEDs to some colors.
|
||||
/// This function set LEDs colors in the buffer which is written to the devices via CorsairSetLedsColorsFlushBuffer or CorsairSetLedsColorsFlushBufferAsync.
|
||||
@ -143,72 +118,76 @@ internal static class _CUESDK
|
||||
/// and follows after one or more calls of CorsairSetLedsColorsBufferByDeviceIndex to set the LEDs buffer.
|
||||
/// This function does not take logical layout into account.
|
||||
/// </summary>
|
||||
internal static bool CorsairSetLedsColorsBufferByDeviceIndex(int deviceIndex, int size, IntPtr ledsColors)
|
||||
=> (_corsairSetLedsColorsBufferByDeviceIndexPointer ?? throw new RGBDeviceException("The Corsair-SDK is not initialized.")).Invoke(deviceIndex, size, ledsColors);
|
||||
internal static unsafe bool CorsairSetLedsColorsBufferByDeviceIndex(int deviceIndex, int size, IntPtr ledsColors)
|
||||
=> ((delegate* unmanaged[Cdecl]<int, int, IntPtr, bool>)ThrowIfZero(_corsairSetLedsColorsBufferByDeviceIndexPointer))(deviceIndex, size, ledsColors);
|
||||
|
||||
/// <summary>
|
||||
/// CUE-SDK: writes to the devices LEDs colors buffer which is previously filled by the CorsairSetLedsColorsBufferByDeviceIndex function.
|
||||
/// This function executes synchronously, if you are concerned about delays consider using CorsairSetLedsColorsFlushBufferAsync
|
||||
/// </summary>
|
||||
internal static bool CorsairSetLedsColorsFlushBuffer() => (_corsairSetLedsColorsFlushBufferPointer ?? throw new RGBDeviceException("The Corsair-SDK is not initialized.")).Invoke();
|
||||
internal static unsafe bool CorsairSetLedsColorsFlushBuffer() => ((delegate* unmanaged[Cdecl]<bool>)ThrowIfZero(_corsairSetLedsColorsFlushBufferPointer))();
|
||||
|
||||
/// <summary>
|
||||
/// CUE-SDK: get current color for the list of requested LEDs.
|
||||
/// The color should represent the actual state of the hardware LED, which could be a combination of SDK and/or CUE input.
|
||||
/// This function works for keyboard, mouse, mousemat, headset, headset stand and DIY-devices.
|
||||
/// </summary>
|
||||
internal static bool CorsairGetLedsColorsByDeviceIndex(int deviceIndex, int size, IntPtr ledsColors)
|
||||
=> (_corsairGetLedsColorsByDeviceIndexPointer ?? throw new RGBDeviceException("The Corsair-SDK is not initialized.")).Invoke(deviceIndex, size, ledsColors);
|
||||
internal static unsafe bool CorsairGetLedsColorsByDeviceIndex(int deviceIndex, int size, IntPtr ledsColors)
|
||||
=> ((delegate* unmanaged[Cdecl]<int, int, IntPtr, bool>)ThrowIfZero(_corsairGetLedsColorsByDeviceIndexPointer))(deviceIndex, size, ledsColors);
|
||||
|
||||
/// <summary>
|
||||
/// CUE-SDK: set layer priority for this shared client.
|
||||
/// By default CUE has priority of 127 and all shared clients have priority of 128 if they don’t call this function.
|
||||
/// Layers with higher priority value are shown on top of layers with lower priority.
|
||||
/// </summary>
|
||||
internal static bool CorsairSetLayerPriority(int priority) => (_corsairSetLayerPriorityPointer ?? throw new RGBDeviceException("The Corsair-SDK is not initialized.")).Invoke(priority);
|
||||
internal static unsafe bool CorsairSetLayerPriority(int priority) => ((delegate* unmanaged[Cdecl]<int, bool>)ThrowIfZero(_corsairSetLayerPriorityPointer))(priority);
|
||||
|
||||
/// <summary>
|
||||
/// CUE-SDK: returns number of connected Corsair devices that support lighting control.
|
||||
/// </summary>
|
||||
internal static int CorsairGetDeviceCount() => (_corsairGetDeviceCountPointer ?? throw new RGBDeviceException("The Corsair-SDK is not initialized.")).Invoke();
|
||||
internal static unsafe int CorsairGetDeviceCount() => ((delegate* unmanaged[Cdecl]<int>)ThrowIfZero(_corsairGetDeviceCountPointer))();
|
||||
|
||||
/// <summary>
|
||||
/// CUE-SDK: returns information about device at provided index.
|
||||
/// </summary>
|
||||
internal static IntPtr CorsairGetDeviceInfo(int deviceIndex) => (_corsairGetDeviceInfoPointer ?? throw new RGBDeviceException("The Corsair-SDK is not initialized.")).Invoke(deviceIndex);
|
||||
internal static unsafe IntPtr CorsairGetDeviceInfo(int deviceIndex) => ((delegate* unmanaged[Cdecl]<int, IntPtr>)ThrowIfZero(_corsairGetDeviceInfoPointer))(deviceIndex);
|
||||
|
||||
/// <summary>
|
||||
/// CUE-SDK: provides list of keyboard or mousepad LEDs with their physical positions.
|
||||
/// </summary>
|
||||
internal static IntPtr CorsairGetLedPositionsByDeviceIndex(int deviceIndex) => (_corsairGetLedPositionsByDeviceIndexPointer ?? throw new RGBDeviceException("The Corsair-SDK is not initialized.")).Invoke(deviceIndex);
|
||||
internal static unsafe IntPtr CorsairGetLedPositionsByDeviceIndex(int deviceIndex) => ((delegate* unmanaged[Cdecl]<int, IntPtr>)ThrowIfZero(_corsairGetLedPositionsByDeviceIndexPointer))(deviceIndex);
|
||||
|
||||
/// <summary>
|
||||
/// CUE-SDK: retrieves led id for key name taking logical layout into account.
|
||||
/// </summary>
|
||||
internal static CorsairLedId CorsairGetLedIdForKeyName(char keyName) => (_corsairGetLedIdForKeyNamePointer ?? throw new RGBDeviceException("The Corsair-SDK is not initialized.")).Invoke(keyName);
|
||||
internal static unsafe CorsairLedId CorsairGetLedIdForKeyName(char keyName) => ((delegate* unmanaged[Cdecl]<char, CorsairLedId>)ThrowIfZero(_corsairGetLedIdForKeyNamePointer))(keyName);
|
||||
|
||||
/// <summary>
|
||||
/// CUE-SDK: 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.
|
||||
/// </summary>
|
||||
internal static bool CorsairRequestControl(CorsairAccessMode accessMode) => (_corsairRequestControlPointer ?? throw new RGBDeviceException("The Corsair-SDK is not initialized.")).Invoke(accessMode);
|
||||
internal static unsafe bool CorsairRequestControl(CorsairAccessMode accessMode) => ((delegate* unmanaged[Cdecl]<CorsairAccessMode, bool>)ThrowIfZero(_corsairRequestControlPointer))(accessMode);
|
||||
|
||||
/// <summary>
|
||||
/// CUE-SDK: releases previously requested control for specified access mode.
|
||||
/// </summary>
|
||||
internal static bool CorsairReleaseControl(CorsairAccessMode accessMode) => (_corsairReleaseControlPointer ?? throw new RGBDeviceException("The Corsair-SDK is not initialized.")).Invoke(accessMode);
|
||||
internal static unsafe bool CorsairReleaseControl(CorsairAccessMode accessMode) => ((delegate* unmanaged[Cdecl]<CorsairAccessMode, bool>)ThrowIfZero(_corsairReleaseControlPointer))(accessMode);
|
||||
|
||||
/// <summary>
|
||||
/// CUE-SDK: checks file and protocol version of CUE to understand which of SDK functions can be used with this version of CUE.
|
||||
/// </summary>
|
||||
internal static _CorsairProtocolDetails CorsairPerformProtocolHandshake() => (_corsairPerformProtocolHandshakePointer ?? throw new RGBDeviceException("The Corsair-SDK is not initialized.")).Invoke();
|
||||
internal static unsafe _CorsairProtocolDetails CorsairPerformProtocolHandshake() => ((delegate* unmanaged[Cdecl]<_CorsairProtocolDetails>)ThrowIfZero(_corsairPerformProtocolHandshakePointer))();
|
||||
|
||||
/// <summary>
|
||||
/// CUE-SDK: returns last error that occured while using any of Corsair* functions.
|
||||
/// </summary>
|
||||
internal static CorsairError CorsairGetLastError() => (_corsairGetLastErrorPointer ?? throw new RGBDeviceException("The Corsair-SDK is not initialized.")).Invoke();
|
||||
internal static unsafe CorsairError CorsairGetLastError() => ((delegate* unmanaged[Cdecl]<CorsairError>)ThrowIfZero(_corsairGetLastErrorPointer))();
|
||||
|
||||
// ReSharper restore EventExceptionNotDocumented
|
||||
private static IntPtr ThrowIfZero(IntPtr ptr)
|
||||
{
|
||||
if (ptr == IntPtr.Zero) throw new RGBDeviceException("The Corsair-SDK is not initialized.");
|
||||
return ptr;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
@ -36,6 +36,7 @@
|
||||
<IncludeSymbols>True</IncludeSymbols>
|
||||
<DebugType>portable</DebugType>
|
||||
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)'=='Debug'">
|
||||
|
||||
@ -13,11 +13,11 @@ using RGB.NET.Core;
|
||||
namespace RGB.NET.Devices.Logitech.Native;
|
||||
|
||||
// ReSharper disable once InconsistentNaming
|
||||
internal class _LogitechGSDK
|
||||
internal static class _LogitechGSDK
|
||||
{
|
||||
#region Libary Management
|
||||
|
||||
private static IntPtr _dllHandle = IntPtr.Zero;
|
||||
private static IntPtr _handle = IntPtr.Zero;
|
||||
|
||||
/// <summary>
|
||||
/// Reloads the SDK.
|
||||
@ -30,110 +30,90 @@ internal class _LogitechGSDK
|
||||
|
||||
private static void LoadLogitechGSDK()
|
||||
{
|
||||
if (_dllHandle != IntPtr.Zero) return;
|
||||
if (_handle != IntPtr.Zero) return;
|
||||
|
||||
List<string> possiblePathList = GetPossibleLibraryPaths().ToList();
|
||||
|
||||
// HACK: Load library at runtime to support both, x86 and x64 with one managed dll
|
||||
List<string> possiblePathList = (Environment.Is64BitProcess ? LogitechDeviceProvider.PossibleX64NativePaths : LogitechDeviceProvider.PossibleX86NativePaths)
|
||||
.Select(Environment.ExpandEnvironmentVariables)
|
||||
.ToList();
|
||||
string? dllPath = possiblePathList.FirstOrDefault(File.Exists);
|
||||
if (dllPath == null) throw new RGBDeviceException($"Can't find the Logitech-SDK at one of the expected locations:\r\n '{string.Join("\r\n", possiblePathList.Select(Path.GetFullPath))}'");
|
||||
|
||||
_dllHandle = LoadLibrary(dllPath);
|
||||
if (_dllHandle == IntPtr.Zero) throw new RGBDeviceException($"Logitech LoadLibrary failed with error code {Marshal.GetLastWin32Error()}");
|
||||
if (!NativeLibrary.TryLoad(dllPath, out _handle))
|
||||
#if NET6_0
|
||||
throw new RGBDeviceException($"Logitech LoadLibrary failed with error code {Marshal.GetLastPInvokeError()}");
|
||||
#else
|
||||
throw new RGBDeviceException($"Logitech LoadLibrary failed with error code {Marshal.GetLastWin32Error()}");
|
||||
#endif
|
||||
|
||||
_logiLedInitPointer = (LogiLedInitPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "LogiLedInit"), typeof(LogiLedInitPointer));
|
||||
_logiLedShutdownPointer = (LogiLedShutdownPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "LogiLedShutdown"), typeof(LogiLedShutdownPointer));
|
||||
_logiLedSetTargetDevicePointer = (LogiLedSetTargetDevicePointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "LogiLedSetTargetDevice"), typeof(LogiLedSetTargetDevicePointer));
|
||||
_logiLedGetSdkVersionPointer = (LogiLedGetSdkVersionPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "LogiLedGetSdkVersion"), typeof(LogiLedGetSdkVersionPointer));
|
||||
_lgiLedSaveCurrentLightingPointer = (LogiLedSaveCurrentLightingPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "LogiLedSaveCurrentLighting"), typeof(LogiLedSaveCurrentLightingPointer));
|
||||
_logiLedRestoreLightingPointer = (LogiLedRestoreLightingPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "LogiLedRestoreLighting"), typeof(LogiLedRestoreLightingPointer));
|
||||
_logiLedSetLightingPointer = (LogiLedSetLightingPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "LogiLedSetLighting"), typeof(LogiLedSetLightingPointer));
|
||||
_logiLedSetLightingForKeyWithKeyNamePointer = (LogiLedSetLightingForKeyWithKeyNamePointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "LogiLedSetLightingForKeyWithKeyName"), typeof(LogiLedSetLightingForKeyWithKeyNamePointer));
|
||||
_logiLedSetLightingFromBitmapPointer = (LogiLedSetLightingFromBitmapPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "LogiLedSetLightingFromBitmap"), typeof(LogiLedSetLightingFromBitmapPointer));
|
||||
_logiLedSetLightingForTargetZonePointer = (LogiLedSetLightingForTargetZonePointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "LogiLedSetLightingForTargetZone"), typeof(LogiLedSetLightingForTargetZonePointer));
|
||||
if (!NativeLibrary.TryGetExport(_handle, "LogiLedInit", out _logiLedInitPointer)) throw new RGBDeviceException("Failed to load Logitech function 'LogiLedInit'");
|
||||
if (!NativeLibrary.TryGetExport(_handle, "LogiLedShutdown", out _logiLedShutdownPointer)) throw new RGBDeviceException("Failed to load Logitech function 'LogiLedShutdown'");
|
||||
if (!NativeLibrary.TryGetExport(_handle, "LogiLedSetTargetDevice", out _logiLedSetTargetDevicePointer)) throw new RGBDeviceException("Failed to load Logitech function 'LogiLedSetTargetDevice'");
|
||||
if (!NativeLibrary.TryGetExport(_handle, "LogiLedGetSdkVersion", out _logiLedGetSdkVersionPointer)) throw new RGBDeviceException("Failed to load Logitech function 'LogiLedGetSdkVersion'");
|
||||
if (!NativeLibrary.TryGetExport(_handle, "LogiLedSaveCurrentLighting", out _lgiLedSaveCurrentLightingPointer)) throw new RGBDeviceException("Failed to load Logitech function 'LogiLedSaveCurrentLighting'");
|
||||
if (!NativeLibrary.TryGetExport(_handle, "LogiLedRestoreLighting", out _logiLedRestoreLightingPointer)) throw new RGBDeviceException("Failed to load Logitech function 'LogiLedRestoreLighting'");
|
||||
if (!NativeLibrary.TryGetExport(_handle, "LogiLedSetLighting", out _logiLedSetLightingPointer)) throw new RGBDeviceException("Failed to load Logitech function 'LogiLedSetLighting'");
|
||||
if (!NativeLibrary.TryGetExport(_handle, "LogiLedSetLightingForKeyWithKeyName", out _logiLedSetLightingForKeyWithKeyNamePointer)) throw new RGBDeviceException("Failed to load Logitech function 'LogiLedSetLightingForKeyWithKeyName'");
|
||||
if (!NativeLibrary.TryGetExport(_handle, "LogiLedSetLightingFromBitmap", out _logiLedSetLightingFromBitmapPointer)) throw new RGBDeviceException("Failed to load Logitech function 'LogiLedSetLightingFromBitmap'");
|
||||
if (!NativeLibrary.TryGetExport(_handle, "LogiLedSetLightingForTargetZone", out _logiLedSetLightingForTargetZonePointer)) throw new RGBDeviceException("Failed to load Logitech function 'LogiLedSetLightingForTargetZone'");
|
||||
}
|
||||
|
||||
private static IEnumerable<string> GetPossibleLibraryPaths()
|
||||
{
|
||||
IEnumerable<string> possibleLibraryPaths;
|
||||
|
||||
if (OperatingSystem.IsWindows())
|
||||
possibleLibraryPaths = Environment.Is64BitProcess ? LogitechDeviceProvider.PossibleX64NativePaths : LogitechDeviceProvider.PossibleX86NativePaths;
|
||||
else
|
||||
possibleLibraryPaths = Enumerable.Empty<string>();
|
||||
|
||||
return possibleLibraryPaths.Select(Environment.ExpandEnvironmentVariables);
|
||||
}
|
||||
|
||||
internal static void UnloadLogitechGSDK()
|
||||
{
|
||||
if (_dllHandle == IntPtr.Zero) return;
|
||||
if (_handle == IntPtr.Zero) return;
|
||||
|
||||
LogiLedShutdown();
|
||||
_logiLedInitPointer = IntPtr.Zero;
|
||||
_logiLedShutdownPointer = IntPtr.Zero;
|
||||
_logiLedSetTargetDevicePointer = IntPtr.Zero;
|
||||
_logiLedGetSdkVersionPointer = IntPtr.Zero;
|
||||
_lgiLedSaveCurrentLightingPointer = IntPtr.Zero;
|
||||
_logiLedRestoreLightingPointer = IntPtr.Zero;
|
||||
_logiLedSetLightingPointer = IntPtr.Zero;
|
||||
_logiLedSetLightingForKeyWithKeyNamePointer = IntPtr.Zero;
|
||||
_logiLedSetLightingFromBitmapPointer = IntPtr.Zero;
|
||||
_logiLedSetLightingForTargetZonePointer = IntPtr.Zero;
|
||||
|
||||
// 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;
|
||||
NativeLibrary.Free(_handle);
|
||||
_handle = IntPtr.Zero;
|
||||
}
|
||||
|
||||
[DllImport("kernel32.dll", CharSet = CharSet.Unicode)]
|
||||
private static extern IntPtr LoadLibrary(string dllToLoad);
|
||||
|
||||
[DllImport("kernel32.dll")]
|
||||
private static extern bool FreeLibrary(IntPtr dllHandle);
|
||||
|
||||
[DllImport("kernel32.dll", CharSet = CharSet.Ansi)]
|
||||
private static extern IntPtr GetProcAddress(IntPtr dllHandle, string name);
|
||||
|
||||
#endregion
|
||||
|
||||
#region SDK-METHODS
|
||||
|
||||
#region Pointers
|
||||
|
||||
private static LogiLedInitPointer? _logiLedInitPointer;
|
||||
private static LogiLedShutdownPointer? _logiLedShutdownPointer;
|
||||
private static LogiLedSetTargetDevicePointer? _logiLedSetTargetDevicePointer;
|
||||
private static LogiLedGetSdkVersionPointer? _logiLedGetSdkVersionPointer;
|
||||
private static LogiLedSaveCurrentLightingPointer? _lgiLedSaveCurrentLightingPointer;
|
||||
private static LogiLedRestoreLightingPointer? _logiLedRestoreLightingPointer;
|
||||
private static LogiLedSetLightingPointer? _logiLedSetLightingPointer;
|
||||
private static LogiLedSetLightingForKeyWithKeyNamePointer? _logiLedSetLightingForKeyWithKeyNamePointer;
|
||||
private static LogiLedSetLightingFromBitmapPointer? _logiLedSetLightingFromBitmapPointer;
|
||||
private static LogiLedSetLightingForTargetZonePointer? _logiLedSetLightingForTargetZonePointer;
|
||||
private static IntPtr _logiLedInitPointer;
|
||||
private static IntPtr _logiLedShutdownPointer;
|
||||
private static IntPtr _logiLedSetTargetDevicePointer;
|
||||
private static IntPtr _logiLedGetSdkVersionPointer;
|
||||
private static IntPtr _lgiLedSaveCurrentLightingPointer;
|
||||
private static IntPtr _logiLedRestoreLightingPointer;
|
||||
private static IntPtr _logiLedSetLightingPointer;
|
||||
private static IntPtr _logiLedSetLightingForKeyWithKeyNamePointer;
|
||||
private static IntPtr _logiLedSetLightingFromBitmapPointer;
|
||||
private static IntPtr _logiLedSetLightingForTargetZonePointer;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Delegates
|
||||
internal static unsafe bool LogiLedInit()
|
||||
=> ((delegate* unmanaged[Cdecl]<bool>)ThrowIfZero(_logiLedInitPointer))();
|
||||
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
private delegate bool LogiLedInitPointer();
|
||||
internal static unsafe void LogiLedShutdown()
|
||||
=> ((delegate* unmanaged[Cdecl]<void>)ThrowIfZero(_logiLedShutdownPointer))();
|
||||
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
private delegate void LogiLedShutdownPointer();
|
||||
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
private delegate bool LogiLedSetTargetDevicePointer(int targetDevice);
|
||||
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
private delegate bool LogiLedGetSdkVersionPointer(ref int majorNum, ref int minorNum, ref int buildNum);
|
||||
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
private delegate bool LogiLedSaveCurrentLightingPointer();
|
||||
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
private delegate bool LogiLedRestoreLightingPointer();
|
||||
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
private delegate bool LogiLedSetLightingPointer(int redPercentage, int greenPercentage, int bluePercentage);
|
||||
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
private delegate bool LogiLedSetLightingForKeyWithKeyNamePointer(int keyCode, int redPercentage, int greenPercentage, int bluePercentage);
|
||||
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
private delegate bool LogiLedSetLightingFromBitmapPointer(byte[] bitmap);
|
||||
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
private delegate bool LogiLedSetLightingForTargetZonePointer(LogitechDeviceType deviceType, int zone, int redPercentage, int greenPercentage, int bluePercentage);
|
||||
|
||||
#endregion
|
||||
|
||||
// ReSharper disable EventExceptionNotDocumented
|
||||
|
||||
internal static bool LogiLedInit() => (_logiLedInitPointer ?? throw new RGBDeviceException("The Logitech-GSDK is not initialized.")).Invoke();
|
||||
|
||||
internal static void LogiLedShutdown() => (_logiLedShutdownPointer ?? throw new RGBDeviceException("The Logitech-GSDK is not initialized.")).Invoke();
|
||||
|
||||
internal static bool LogiLedSetTargetDevice(LogitechDeviceCaps targetDevice) => (_logiLedSetTargetDevicePointer ?? throw new RGBDeviceException("The Logitech-GSDK is not initialized.")).Invoke((int)targetDevice);
|
||||
internal static unsafe bool LogiLedSetTargetDevice(LogitechDeviceCaps targetDevice)
|
||||
=> ((delegate* unmanaged[Cdecl]<int, bool>)ThrowIfZero(_logiLedSetTargetDevicePointer))((int)targetDevice);
|
||||
|
||||
internal static string LogiLedGetSdkVersion()
|
||||
{
|
||||
@ -145,25 +125,32 @@ internal class _LogitechGSDK
|
||||
return $"{major}.{minor}.{build}";
|
||||
}
|
||||
|
||||
internal static bool LogiLedGetSdkVersion(ref int majorNum, ref int minorNum, ref int buildNum) =>
|
||||
(_logiLedGetSdkVersionPointer ?? throw new RGBDeviceException("The Logitech-GSDK is not initialized.")).Invoke(ref majorNum, ref minorNum, ref buildNum);
|
||||
internal static unsafe bool LogiLedGetSdkVersion(ref int majorNum, ref int minorNum, ref int buildNum)
|
||||
=> ((delegate* unmanaged[Cdecl]<ref int, ref int, ref int, bool>)ThrowIfZero(_logiLedGetSdkVersionPointer))(ref majorNum, ref minorNum, ref buildNum);
|
||||
|
||||
internal static bool LogiLedSaveCurrentLighting() => (_lgiLedSaveCurrentLightingPointer ?? throw new RGBDeviceException("The Logitech-GSDK is not initialized.")).Invoke();
|
||||
internal static unsafe bool LogiLedSaveCurrentLighting()
|
||||
=> ((delegate* unmanaged[Cdecl]<bool>)ThrowIfZero(_lgiLedSaveCurrentLightingPointer))();
|
||||
|
||||
internal static bool LogiLedRestoreLighting() => (_logiLedRestoreLightingPointer ?? throw new RGBDeviceException("The Logitech-GSDK is not initialized.")).Invoke();
|
||||
internal static unsafe bool LogiLedRestoreLighting()
|
||||
=> ((delegate* unmanaged[Cdecl]<bool>)ThrowIfZero(_logiLedRestoreLightingPointer))();
|
||||
|
||||
internal static bool LogiLedSetLighting(int redPercentage, int greenPercentage, int bluePercentage) =>
|
||||
(_logiLedSetLightingPointer ?? throw new RGBDeviceException("The Logitech-GSDK is not initialized.")).Invoke(redPercentage, greenPercentage, bluePercentage);
|
||||
internal static unsafe bool LogiLedSetLighting(int redPercentage, int greenPercentage, int bluePercentage)
|
||||
=> ((delegate* unmanaged[Cdecl]<int, int, int, bool>)ThrowIfZero(_logiLedSetLightingPointer))(redPercentage, greenPercentage, bluePercentage);
|
||||
|
||||
internal static bool LogiLedSetLightingForKeyWithKeyName(int keyCode, int redPercentage, int greenPercentage, int bluePercentage)
|
||||
=> (_logiLedSetLightingForKeyWithKeyNamePointer ?? throw new RGBDeviceException("The Logitech-GSDK is not initialized.")).Invoke(keyCode, redPercentage, greenPercentage, bluePercentage);
|
||||
internal static unsafe bool LogiLedSetLightingForKeyWithKeyName(int keyCode, int redPercentage, int greenPercentage, int bluePercentage)
|
||||
=> ((delegate* unmanaged[Cdecl]<int, int, int, int, bool>)ThrowIfZero(_logiLedSetLightingForKeyWithKeyNamePointer))(keyCode, redPercentage, greenPercentage, bluePercentage);
|
||||
|
||||
internal static bool LogiLedSetLightingFromBitmap(byte[] bitmap) => (_logiLedSetLightingFromBitmapPointer ?? throw new RGBDeviceException("The Logitech-GSDK is not initialized.")).Invoke(bitmap);
|
||||
internal static unsafe bool LogiLedSetLightingFromBitmap(byte[] bitmap)
|
||||
=> ((delegate* unmanaged[Cdecl]<byte[], bool>)ThrowIfZero(_logiLedSetLightingFromBitmapPointer))(bitmap);
|
||||
|
||||
internal static bool LogiLedSetLightingForTargetZone(LogitechDeviceType deviceType, int zone, int redPercentage, int greenPercentage, int bluePercentage)
|
||||
=> (_logiLedSetLightingForTargetZonePointer ?? throw new RGBDeviceException("The Logitech-GSDK is not initialized.")).Invoke(deviceType, zone, redPercentage, greenPercentage, bluePercentage);
|
||||
internal static unsafe bool LogiLedSetLightingForTargetZone(LogitechDeviceType deviceType, int zone, int redPercentage, int greenPercentage, int bluePercentage)
|
||||
=> ((delegate* unmanaged[Cdecl]<LogitechDeviceType, int, int, int, int, bool>)ThrowIfZero(_logiLedSetLightingForTargetZonePointer))(deviceType, zone, redPercentage, greenPercentage, bluePercentage);
|
||||
|
||||
// ReSharper restore EventExceptionNotDocumented
|
||||
private static IntPtr ThrowIfZero(IntPtr ptr)
|
||||
{
|
||||
if (ptr == IntPtr.Zero) throw new RGBDeviceException("The Logitech-SDK is not initialized.");
|
||||
return ptr;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
@ -36,6 +36,7 @@
|
||||
<IncludeSymbols>True</IncludeSymbols>
|
||||
<DebugType>portable</DebugType>
|
||||
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)'=='Debug'">
|
||||
|
||||
@ -16,7 +16,7 @@ internal static class _MsiSDK
|
||||
{
|
||||
#region Libary Management
|
||||
|
||||
private static IntPtr _dllHandle = IntPtr.Zero;
|
||||
private static IntPtr _handle = IntPtr.Zero;
|
||||
|
||||
/// <summary>
|
||||
/// Reloads the SDK.
|
||||
@ -29,57 +29,76 @@ internal static class _MsiSDK
|
||||
|
||||
private static void LoadMsiSDK()
|
||||
{
|
||||
if (_dllHandle != IntPtr.Zero) return;
|
||||
if (_handle != IntPtr.Zero) return;
|
||||
|
||||
List<string> possiblePathList = GetPossibleLibraryPaths().ToList();
|
||||
|
||||
// HACK: Load library at runtime to support both, x86 and x64 with one managed dll
|
||||
List<string> possiblePathList = (Environment.Is64BitProcess ? MsiDeviceProvider.PossibleX64NativePaths : MsiDeviceProvider.PossibleX86NativePaths)
|
||||
.Select(Environment.ExpandEnvironmentVariables)
|
||||
.ToList();
|
||||
string? dllPath = possiblePathList.FirstOrDefault(File.Exists);
|
||||
if (dllPath == null) throw new RGBDeviceException($"Can't find the Msi-SDK at one of the expected locations:\r\n '{string.Join("\r\n", possiblePathList.Select(Path.GetFullPath))}'");
|
||||
|
||||
if (dllPath == null) throw new RGBDeviceException($"Can't find the CUE-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);
|
||||
if (_dllHandle == IntPtr.Zero) throw new RGBDeviceException($"MSI LoadLibrary failed with error code {Marshal.GetLastWin32Error()}");
|
||||
if (!NativeLibrary.TryLoad(dllPath, out _handle))
|
||||
#if NET6_0
|
||||
throw new RGBDeviceException($"MSI LoadLibrary failed with error code {Marshal.GetLastPInvokeError()}");
|
||||
#else
|
||||
throw new RGBDeviceException($"MSI LoadLibrary failed with error code {Marshal.GetLastWin32Error()}");
|
||||
#endif
|
||||
|
||||
_initializePointer = (InitializePointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "MLAPI_Initialize"), typeof(InitializePointer));
|
||||
_getDeviceInfoPointer = (GetDeviceInfoPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "MLAPI_GetDeviceInfo"), typeof(GetDeviceInfoPointer));
|
||||
_getLedInfoPointer = (GetLedInfoPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "MLAPI_GetLedInfo"), typeof(GetLedInfoPointer));
|
||||
_getLedColorPointer = (GetLedColorPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "MLAPI_GetLedColor"), typeof(GetLedColorPointer));
|
||||
_getLedStylePointer = (GetLedStylePointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "MLAPI_GetLedStyle"), typeof(GetLedStylePointer));
|
||||
_getLedMaxBrightPointer = (GetLedMaxBrightPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "MLAPI_GetLedMaxBright"), typeof(GetLedMaxBrightPointer));
|
||||
_getLedBrightPointer = (GetLedBrightPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "MLAPI_GetLedBright"), typeof(GetLedBrightPointer));
|
||||
_getLedMaxSpeedPointer = (GetLedMaxSpeedPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "MLAPI_GetLedMaxSpeed"), typeof(GetLedMaxSpeedPointer));
|
||||
_getLedSpeedPointer = (GetLedSpeedPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "MLAPI_GetLedSpeed"), typeof(GetLedSpeedPointer));
|
||||
_setLedColorPointer = (SetLedColorPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "MLAPI_SetLedColor"), typeof(SetLedColorPointer));
|
||||
_setLedStylePointer = (SetLedStylePointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "MLAPI_SetLedStyle"), typeof(SetLedStylePointer));
|
||||
_setLedBrightPointer = (SetLedBrightPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "MLAPI_SetLedBright"), typeof(SetLedBrightPointer));
|
||||
_setLedSpeedPointer = (SetLedSpeedPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "MLAPI_SetLedSpeed"), typeof(SetLedSpeedPointer));
|
||||
_getErrorMessagePointer = (GetErrorMessagePointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "MLAPI_GetErrorMessage"), typeof(GetErrorMessagePointer));
|
||||
_initializePointer = (InitializePointer)Marshal.GetDelegateForFunctionPointer(NativeLibrary.GetExport(_handle, "MLAPI_Initialize"), typeof(InitializePointer));
|
||||
_getDeviceInfoPointer = (GetDeviceInfoPointer)Marshal.GetDelegateForFunctionPointer(NativeLibrary.GetExport(_handle, "MLAPI_GetDeviceInfo"), typeof(GetDeviceInfoPointer));
|
||||
_getLedInfoPointer = (GetLedInfoPointer)Marshal.GetDelegateForFunctionPointer(NativeLibrary.GetExport(_handle, "MLAPI_GetLedInfo"), typeof(GetLedInfoPointer));
|
||||
_getLedColorPointer = (GetLedColorPointer)Marshal.GetDelegateForFunctionPointer(NativeLibrary.GetExport(_handle, "MLAPI_GetLedColor"), typeof(GetLedColorPointer));
|
||||
_getLedStylePointer = (GetLedStylePointer)Marshal.GetDelegateForFunctionPointer(NativeLibrary.GetExport(_handle, "MLAPI_GetLedStyle"), typeof(GetLedStylePointer));
|
||||
_getLedMaxBrightPointer = (GetLedMaxBrightPointer)Marshal.GetDelegateForFunctionPointer(NativeLibrary.GetExport(_handle, "MLAPI_GetLedMaxBright"), typeof(GetLedMaxBrightPointer));
|
||||
_getLedBrightPointer = (GetLedBrightPointer)Marshal.GetDelegateForFunctionPointer(NativeLibrary.GetExport(_handle, "MLAPI_GetLedBright"), typeof(GetLedBrightPointer));
|
||||
_getLedMaxSpeedPointer = (GetLedMaxSpeedPointer)Marshal.GetDelegateForFunctionPointer(NativeLibrary.GetExport(_handle, "MLAPI_GetLedMaxSpeed"), typeof(GetLedMaxSpeedPointer));
|
||||
_getLedSpeedPointer = (GetLedSpeedPointer)Marshal.GetDelegateForFunctionPointer(NativeLibrary.GetExport(_handle, "MLAPI_GetLedSpeed"), typeof(GetLedSpeedPointer));
|
||||
_setLedColorPointer = (SetLedColorPointer)Marshal.GetDelegateForFunctionPointer(NativeLibrary.GetExport(_handle, "MLAPI_SetLedColor"), typeof(SetLedColorPointer));
|
||||
_setLedStylePointer = (SetLedStylePointer)Marshal.GetDelegateForFunctionPointer(NativeLibrary.GetExport(_handle, "MLAPI_SetLedStyle"), typeof(SetLedStylePointer));
|
||||
_setLedBrightPointer = (SetLedBrightPointer)Marshal.GetDelegateForFunctionPointer(NativeLibrary.GetExport(_handle, "MLAPI_SetLedBright"), typeof(SetLedBrightPointer));
|
||||
_setLedSpeedPointer = (SetLedSpeedPointer)Marshal.GetDelegateForFunctionPointer(NativeLibrary.GetExport(_handle, "MLAPI_SetLedSpeed"), typeof(SetLedSpeedPointer));
|
||||
_getErrorMessagePointer = (GetErrorMessagePointer)Marshal.GetDelegateForFunctionPointer(NativeLibrary.GetExport(_handle, "MLAPI_GetErrorMessage"), typeof(GetErrorMessagePointer));
|
||||
}
|
||||
|
||||
private static IEnumerable<string> GetPossibleLibraryPaths()
|
||||
{
|
||||
IEnumerable<string> possibleLibraryPaths;
|
||||
|
||||
if (OperatingSystem.IsWindows())
|
||||
possibleLibraryPaths = Environment.Is64BitProcess ? MsiDeviceProvider.PossibleX64NativePaths : MsiDeviceProvider.PossibleX86NativePaths;
|
||||
else
|
||||
possibleLibraryPaths = Enumerable.Empty<string>();
|
||||
|
||||
return possibleLibraryPaths.Select(Environment.ExpandEnvironmentVariables);
|
||||
}
|
||||
|
||||
internal static void UnloadMsiSDK()
|
||||
{
|
||||
if (_dllHandle == IntPtr.Zero) return;
|
||||
if (_handle == IntPtr.Zero) return;
|
||||
|
||||
// ReSharper disable once EmptyEmbeddedStatement - DarthAffe 07.10.2017: We might need to reduce the internal reference counter more than once to set the library free
|
||||
while (FreeLibrary(_dllHandle)) ;
|
||||
_dllHandle = IntPtr.Zero;
|
||||
_initializePointer = null;
|
||||
_getDeviceInfoPointer = null;
|
||||
_getLedColorPointer = null;
|
||||
_getLedColorPointer = null;
|
||||
_getLedStylePointer = null;
|
||||
_getLedMaxBrightPointer = null;
|
||||
_getLedBrightPointer = null;
|
||||
_getLedMaxSpeedPointer = null;
|
||||
_getLedSpeedPointer = null;
|
||||
_setLedColorPointer = null;
|
||||
_setLedStylePointer = null;
|
||||
_setLedBrightPointer = null;
|
||||
_setLedSpeedPointer = null;
|
||||
_getErrorMessagePointer = null;
|
||||
|
||||
NativeLibrary.Free(_handle);
|
||||
_handle = IntPtr.Zero;
|
||||
}
|
||||
|
||||
[DllImport("kernel32.dll", CharSet = CharSet.Unicode)]
|
||||
private static extern bool SetDllDirectory(string lpPathName);
|
||||
|
||||
[DllImport("kernel32.dll", CharSet = CharSet.Unicode)]
|
||||
private static extern IntPtr LoadLibrary(string dllToLoad);
|
||||
|
||||
[DllImport("kernel32.dll")]
|
||||
private static extern bool FreeLibrary(IntPtr dllHandle);
|
||||
|
||||
[DllImport("kernel32.dll", CharSet = CharSet.Ansi)]
|
||||
private static extern IntPtr GetProcAddress(IntPtr dllHandle, string name);
|
||||
|
||||
#endregion
|
||||
|
||||
#region SDK-METHODS
|
||||
|
||||
@ -16,7 +16,7 @@ internal static class _RazerSDK
|
||||
{
|
||||
#region Libary Management
|
||||
|
||||
private static IntPtr _dllHandle = IntPtr.Zero;
|
||||
private static IntPtr _handle = IntPtr.Zero;
|
||||
|
||||
/// <summary>
|
||||
/// Reloads the SDK.
|
||||
@ -29,132 +29,108 @@ internal static class _RazerSDK
|
||||
|
||||
private static void LoadRazerSDK()
|
||||
{
|
||||
if (_dllHandle != IntPtr.Zero) return;
|
||||
if (_handle != IntPtr.Zero) return;
|
||||
|
||||
List<string> possiblePathList = GetPossibleLibraryPaths().ToList();
|
||||
|
||||
// HACK: Load library at runtime to support both, x86 and x64 with one managed dll
|
||||
List<string> possiblePathList = (Environment.Is64BitProcess ? RazerDeviceProvider.PossibleX64NativePaths : RazerDeviceProvider.PossibleX86NativePaths)
|
||||
.Select(Environment.ExpandEnvironmentVariables)
|
||||
.ToList();
|
||||
string? dllPath = possiblePathList.FirstOrDefault(File.Exists);
|
||||
if (dllPath == null) throw new RGBDeviceException($"Can't find the Razer-SDK at one of the expected locations:\r\n '{string.Join("\r\n", possiblePathList.Select(Path.GetFullPath))}'");
|
||||
|
||||
_dllHandle = LoadLibrary(dllPath);
|
||||
if (_dllHandle == IntPtr.Zero) throw new RGBDeviceException($"Razer LoadLibrary failed with error code {Marshal.GetLastWin32Error()}");
|
||||
if (!NativeLibrary.TryLoad(dllPath, out _handle))
|
||||
#if NET6_0
|
||||
throw new RGBDeviceException($"Razer LoadLibrary failed with error code {Marshal.GetLastPInvokeError()}");
|
||||
#else
|
||||
throw new RGBDeviceException($"Razer LoadLibrary failed with error code {Marshal.GetLastWin32Error()}");
|
||||
#endif
|
||||
|
||||
_initPointer = (InitPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "Init"), typeof(InitPointer));
|
||||
_unInitPointer = (UnInitPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "UnInit"), typeof(UnInitPointer));
|
||||
_queryDevicePointer = (QueryDevicePointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "QueryDevice"), typeof(QueryDevicePointer));
|
||||
_createEffectPointer = (CreateEffectPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "CreateEffect"), typeof(CreateEffectPointer));
|
||||
_createHeadsetEffectPointer = (CreateHeadsetEffectPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "CreateHeadsetEffect"), typeof(CreateHeadsetEffectPointer));
|
||||
_createChromaLinkEffectPointer = (CreateChromaLinkEffectPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "CreateChromaLinkEffect"), typeof(CreateChromaLinkEffectPointer));
|
||||
_createKeyboardEffectPointer = (CreateKeyboardEffectPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "CreateKeyboardEffect"), typeof(CreateKeyboardEffectPointer));
|
||||
_createKeypadEffectPointer = (CreateKeypadEffectPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "CreateKeypadEffect"), typeof(CreateKeypadEffectPointer));
|
||||
_createMouseEffectPointer = (CreateMouseEffectPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "CreateMouseEffect"), typeof(CreateMouseEffectPointer));
|
||||
_createMousepadEffectPointer = (CreateMousepadEffectPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "CreateMousepadEffect"), typeof(CreateMousepadEffectPointer));
|
||||
_setEffectPointer = (SetEffectPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "SetEffect"), typeof(SetEffectPointer));
|
||||
_deleteEffectPointer = (DeleteEffectPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "DeleteEffect"), typeof(DeleteEffectPointer));
|
||||
if (!NativeLibrary.TryGetExport(_handle, "Init", out _initPointer)) throw new RGBDeviceException("Failed to load Razer function 'Init'");
|
||||
if (!NativeLibrary.TryGetExport(_handle, "UnInit", out _unInitPointer)) throw new RGBDeviceException("Failed to load Razer function 'UnInit'");
|
||||
if (!NativeLibrary.TryGetExport(_handle, "QueryDevice", out _queryDevicePointer)) throw new RGBDeviceException("Failed to load Razer function 'QueryDevice'");
|
||||
if (!NativeLibrary.TryGetExport(_handle, "CreateEffect", out _createEffectPointer)) throw new RGBDeviceException("Failed to load Razer function 'CreateEffect'");
|
||||
if (!NativeLibrary.TryGetExport(_handle, "CreateHeadsetEffect", out _createHeadsetEffectPointer)) throw new RGBDeviceException("Failed to load Razer function 'CreateHeadsetEffect'");
|
||||
if (!NativeLibrary.TryGetExport(_handle, "CreateChromaLinkEffect", out _createChromaLinkEffectPointer)) throw new RGBDeviceException("Failed to load Razer function 'CreateChromaLinkEffect'");
|
||||
if (!NativeLibrary.TryGetExport(_handle, "CreateKeyboardEffect", out _createKeyboardEffectPointer)) throw new RGBDeviceException("Failed to load Razer function 'CreateKeyboardEffect'");
|
||||
if (!NativeLibrary.TryGetExport(_handle, "CreateKeypadEffect", out _createKeypadEffectPointer)) throw new RGBDeviceException("Failed to load Razer function 'CreateKeypadEffect'");
|
||||
if (!NativeLibrary.TryGetExport(_handle, "CreateMouseEffect", out _createMouseEffectPointer)) throw new RGBDeviceException("Failed to load Razer function 'CreateMouseEffect'");
|
||||
if (!NativeLibrary.TryGetExport(_handle, "CreateMousepadEffect", out _createMousepadEffectPointer)) throw new RGBDeviceException("Failed to load Razer function 'CreateMousepadEffect'");
|
||||
if (!NativeLibrary.TryGetExport(_handle, "SetEffect", out _setEffectPointer)) throw new RGBDeviceException("Failed to load Razer function 'SetEffect'");
|
||||
if (!NativeLibrary.TryGetExport(_handle, "DeleteEffect", out _deleteEffectPointer)) throw new RGBDeviceException("Failed to load Razer function 'DeleteEffect'");
|
||||
}
|
||||
|
||||
private static IEnumerable<string> GetPossibleLibraryPaths()
|
||||
{
|
||||
IEnumerable<string> possibleLibraryPaths;
|
||||
|
||||
if (OperatingSystem.IsWindows())
|
||||
possibleLibraryPaths = Environment.Is64BitProcess ? RazerDeviceProvider.PossibleX64NativePaths : RazerDeviceProvider.PossibleX86NativePaths;
|
||||
else
|
||||
possibleLibraryPaths = Enumerable.Empty<string>();
|
||||
|
||||
return possibleLibraryPaths.Select(Environment.ExpandEnvironmentVariables);
|
||||
}
|
||||
|
||||
internal static void UnloadRazerSDK()
|
||||
{
|
||||
if (_dllHandle == IntPtr.Zero) return;
|
||||
if (_handle == IntPtr.Zero) return;
|
||||
|
||||
// ReSharper disable once EmptyEmbeddedStatement - DarthAffe 09.11.2017: We might need to reduce the internal reference counter more than once to set the library free
|
||||
while (FreeLibrary(_dllHandle)) ;
|
||||
_dllHandle = IntPtr.Zero;
|
||||
_initPointer = IntPtr.Zero;
|
||||
_unInitPointer = IntPtr.Zero;
|
||||
_queryDevicePointer = IntPtr.Zero;
|
||||
_createEffectPointer = IntPtr.Zero;
|
||||
_createHeadsetEffectPointer = IntPtr.Zero;
|
||||
_createChromaLinkEffectPointer = IntPtr.Zero;
|
||||
_createKeyboardEffectPointer = IntPtr.Zero;
|
||||
_createKeypadEffectPointer = IntPtr.Zero;
|
||||
_createMouseEffectPointer = IntPtr.Zero;
|
||||
_createMousepadEffectPointer = IntPtr.Zero;
|
||||
_setEffectPointer = IntPtr.Zero;
|
||||
_deleteEffectPointer = IntPtr.Zero;
|
||||
|
||||
NativeLibrary.Free(_handle);
|
||||
_handle = IntPtr.Zero;
|
||||
}
|
||||
|
||||
[DllImport("kernel32.dll", CharSet = CharSet.Unicode)]
|
||||
private static extern IntPtr LoadLibrary(string dllToLoad);
|
||||
|
||||
[DllImport("kernel32.dll")]
|
||||
private static extern bool FreeLibrary(IntPtr dllHandle);
|
||||
|
||||
[DllImport("kernel32.dll", CharSet = CharSet.Ansi)]
|
||||
private static extern IntPtr GetProcAddress(IntPtr dllHandle, string name);
|
||||
|
||||
#endregion
|
||||
|
||||
#region SDK-METHODS
|
||||
|
||||
#region Pointers
|
||||
|
||||
private static InitPointer? _initPointer;
|
||||
private static UnInitPointer? _unInitPointer;
|
||||
private static QueryDevicePointer? _queryDevicePointer;
|
||||
private static CreateEffectPointer? _createEffectPointer;
|
||||
private static CreateHeadsetEffectPointer? _createHeadsetEffectPointer;
|
||||
private static CreateChromaLinkEffectPointer? _createChromaLinkEffectPointer;
|
||||
private static CreateKeyboardEffectPointer? _createKeyboardEffectPointer;
|
||||
private static CreateKeypadEffectPointer? _createKeypadEffectPointer;
|
||||
private static CreateMouseEffectPointer? _createMouseEffectPointer;
|
||||
private static CreateMousepadEffectPointer? _createMousepadEffectPointer;
|
||||
private static SetEffectPointer? _setEffectPointer;
|
||||
private static DeleteEffectPointer? _deleteEffectPointer;
|
||||
private static IntPtr _initPointer;
|
||||
private static IntPtr _unInitPointer;
|
||||
private static IntPtr _queryDevicePointer;
|
||||
private static IntPtr _createEffectPointer;
|
||||
private static IntPtr _createHeadsetEffectPointer;
|
||||
private static IntPtr _createChromaLinkEffectPointer;
|
||||
private static IntPtr _createKeyboardEffectPointer;
|
||||
private static IntPtr _createKeypadEffectPointer;
|
||||
private static IntPtr _createMouseEffectPointer;
|
||||
private static IntPtr _createMousepadEffectPointer;
|
||||
private static IntPtr _setEffectPointer;
|
||||
private static IntPtr _deleteEffectPointer;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Delegates
|
||||
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
private delegate RazerError InitPointer();
|
||||
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
private delegate RazerError UnInitPointer();
|
||||
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
private delegate RazerError QueryDevicePointer(Guid deviceId, IntPtr deviceInfo);
|
||||
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
private delegate RazerError CreateEffectPointer(Guid deviceId, int effectType, IntPtr param, ref Guid effectId);
|
||||
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
private delegate RazerError CreateHeadsetEffectPointer(int effectType, IntPtr param, ref Guid effectId);
|
||||
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
private delegate RazerError CreateChromaLinkEffectPointer(int effectType, IntPtr param, ref Guid effectId);
|
||||
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
private delegate RazerError CreateKeyboardEffectPointer(int effectType, IntPtr param, ref Guid effectId);
|
||||
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
private delegate RazerError CreateKeypadEffectPointer(int effectType, IntPtr param, ref Guid effectId);
|
||||
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
private delegate RazerError CreateMouseEffectPointer(int effectType, IntPtr param, ref Guid effectId);
|
||||
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
private delegate RazerError CreateMousepadEffectPointer(int effectType, IntPtr param, ref Guid effectId);
|
||||
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
private delegate RazerError SetEffectPointer(Guid effectId);
|
||||
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
private delegate RazerError DeleteEffectPointer(Guid effectId);
|
||||
|
||||
#endregion
|
||||
|
||||
// ReSharper disable EventExceptionNotDocumented
|
||||
|
||||
/// <summary>
|
||||
/// Razer-SDK: Initialize Chroma SDK.
|
||||
/// </summary>
|
||||
internal static RazerError Init() => (_initPointer ?? throw new RGBDeviceException("The Razer-SDK is not initialized.")).Invoke();
|
||||
internal static unsafe RazerError Init() => ((delegate* unmanaged[Cdecl]<RazerError>)ThrowIfZero(_initPointer))();
|
||||
|
||||
/// <summary>
|
||||
/// Razer-SDK: UnInitialize Chroma SDK.
|
||||
/// </summary>
|
||||
internal static RazerError UnInit() => (_unInitPointer ?? throw new RGBDeviceException("The Razer-SDK is not initialized.")).Invoke();
|
||||
internal static unsafe RazerError UnInit()
|
||||
=> ((delegate* unmanaged[Cdecl]<RazerError>)ThrowIfZero(_unInitPointer))();
|
||||
|
||||
/// <summary>
|
||||
/// Razer-SDK: Query for device information.
|
||||
/// </summary>
|
||||
internal static RazerError QueryDevice(Guid deviceId, out _DeviceInfo deviceInfo)
|
||||
internal static unsafe RazerError QueryDevice(Guid deviceId, out _DeviceInfo deviceInfo)
|
||||
{
|
||||
int structSize = Marshal.SizeOf(typeof(_DeviceInfo));
|
||||
IntPtr deviceInfoPtr = Marshal.AllocHGlobal(structSize);
|
||||
|
||||
RazerError error = (_queryDevicePointer ?? throw new RGBDeviceException("The Razer-SDK is not initialized.")).Invoke(deviceId, deviceInfoPtr);
|
||||
RazerError error = ((delegate* unmanaged[Cdecl]<Guid, IntPtr, RazerError>)ThrowIfZero(_queryDevicePointer))(deviceId, deviceInfoPtr);
|
||||
|
||||
deviceInfo = (_DeviceInfo)Marshal.PtrToStructure(deviceInfoPtr, typeof(_DeviceInfo))!;
|
||||
Marshal.FreeHGlobal(deviceInfoPtr);
|
||||
@ -162,25 +138,38 @@ internal static class _RazerSDK
|
||||
return error;
|
||||
}
|
||||
|
||||
internal static RazerError CreateEffect(Guid deviceId, int effectType, IntPtr param, ref Guid effectId) => (_createEffectPointer ?? throw new RGBDeviceException("The Razer-SDK is not initialized.")).Invoke(deviceId, effectType, param, ref effectId);
|
||||
internal static unsafe RazerError CreateEffect(Guid deviceId, int effectType, IntPtr param, ref Guid effectId)
|
||||
=> ((delegate* unmanaged[Cdecl]<Guid, int, IntPtr, ref Guid, RazerError>)ThrowIfZero(_createEffectPointer))(deviceId, effectType, param, ref effectId);
|
||||
|
||||
internal static RazerError CreateHeadsetEffect(int effectType, IntPtr param, ref Guid effectId) => (_createHeadsetEffectPointer ?? throw new RGBDeviceException("The Razer-SDK is not initialized.")).Invoke(effectType, param, ref effectId);
|
||||
internal static unsafe RazerError CreateHeadsetEffect(int effectType, IntPtr param, ref Guid effectId)
|
||||
=> ((delegate* unmanaged[Cdecl]<int, IntPtr, ref Guid, RazerError>)ThrowIfZero(_createHeadsetEffectPointer))(effectType, param, ref effectId);
|
||||
|
||||
internal static RazerError CreateChromaLinkEffect(int effectType, IntPtr param, ref Guid effectId) => (_createChromaLinkEffectPointer ?? throw new RGBDeviceException("The Razer-SDK is not initialized.")).Invoke(effectType, param, ref effectId);
|
||||
internal static unsafe RazerError CreateChromaLinkEffect(int effectType, IntPtr param, ref Guid effectId)
|
||||
=> ((delegate* unmanaged[Cdecl]<int, IntPtr, ref Guid, RazerError>)ThrowIfZero(_createChromaLinkEffectPointer))(effectType, param, ref effectId);
|
||||
|
||||
internal static RazerError CreateKeyboardEffect(int effectType, IntPtr param, ref Guid effectId) => (_createKeyboardEffectPointer ?? throw new RGBDeviceException("The Razer-SDK is not initialized.")).Invoke(effectType, param, ref effectId);
|
||||
internal static unsafe RazerError CreateKeyboardEffect(int effectType, IntPtr param, ref Guid effectId)
|
||||
=> ((delegate* unmanaged[Cdecl]<int, IntPtr, ref Guid, RazerError>)ThrowIfZero(_createKeyboardEffectPointer))(effectType, param, ref effectId);
|
||||
|
||||
internal static RazerError CreateKeypadEffect(int effectType, IntPtr param, ref Guid effectId) => (_createKeypadEffectPointer ?? throw new RGBDeviceException("The Razer-SDK is not initialized.")).Invoke(effectType, param, ref effectId);
|
||||
internal static unsafe RazerError CreateKeypadEffect(int effectType, IntPtr param, ref Guid effectId)
|
||||
=> ((delegate* unmanaged[Cdecl]<int, IntPtr, ref Guid, RazerError>)ThrowIfZero(_createKeypadEffectPointer))(effectType, param, ref effectId);
|
||||
|
||||
internal static RazerError CreateMouseEffect(int effectType, IntPtr param, ref Guid effectId) => (_createMouseEffectPointer ?? throw new RGBDeviceException("The Razer-SDK is not initialized.")).Invoke(effectType, param, ref effectId);
|
||||
internal static unsafe RazerError CreateMouseEffect(int effectType, IntPtr param, ref Guid effectId)
|
||||
=> ((delegate* unmanaged[Cdecl]<int, IntPtr, ref Guid, RazerError>)ThrowIfZero(_createMouseEffectPointer))(effectType, param, ref effectId);
|
||||
|
||||
internal static RazerError CreateMousepadEffect(int effectType, IntPtr param, ref Guid effectId) => (_createMousepadEffectPointer ?? throw new RGBDeviceException("The Razer-SDK is not initialized.")).Invoke(effectType, param, ref effectId);
|
||||
internal static unsafe RazerError CreateMousepadEffect(int effectType, IntPtr param, ref Guid effectId)
|
||||
=> ((delegate* unmanaged[Cdecl]<int, IntPtr, ref Guid, RazerError>)ThrowIfZero(_createMousepadEffectPointer))(effectType, param, ref effectId);
|
||||
|
||||
internal static RazerError SetEffect(Guid effectId) => (_setEffectPointer ?? throw new RGBDeviceException("The Razer-SDK is not initialized.")).Invoke(effectId);
|
||||
internal static unsafe RazerError SetEffect(Guid effectId)
|
||||
=> ((delegate* unmanaged[Cdecl]<Guid, RazerError>)ThrowIfZero(_setEffectPointer))(effectId);
|
||||
|
||||
internal static RazerError DeleteEffect(Guid effectId) => (_deleteEffectPointer ?? throw new RGBDeviceException("The Razer-SDK is not initialized.")).Invoke(effectId);
|
||||
internal static unsafe RazerError DeleteEffect(Guid effectId)
|
||||
=> ((delegate* unmanaged[Cdecl]<Guid, RazerError>)ThrowIfZero(_deleteEffectPointer))(effectId);
|
||||
|
||||
// ReSharper restore EventExceptionNotDocumented
|
||||
private static IntPtr ThrowIfZero(IntPtr ptr)
|
||||
{
|
||||
if (ptr == IntPtr.Zero) throw new RGBDeviceException("The Razer-SDK is not initialized.");
|
||||
return ptr;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
@ -36,6 +36,7 @@
|
||||
<IncludeSymbols>True</IncludeSymbols>
|
||||
<DebugType>portable</DebugType>
|
||||
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)'=='Debug'">
|
||||
|
||||
@ -36,7 +36,12 @@ internal static class _WootingSDK
|
||||
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))}'");
|
||||
|
||||
if (!NativeLibrary.TryLoad(dllPath, out _handle)) throw new RGBDeviceException($"Wooting LoadLibrary failed with error code {Marshal.GetLastWin32Error()}");
|
||||
if (!NativeLibrary.TryLoad(dllPath, out _handle))
|
||||
#if NET6_0
|
||||
throw new RGBDeviceException($"Wooting LoadLibrary failed with error code {Marshal.GetLastPInvokeError()}");
|
||||
#else
|
||||
throw new RGBDeviceException($"Wooting LoadLibrary failed with error code {Marshal.GetLastWin32Error()}");
|
||||
#endif
|
||||
|
||||
if (!NativeLibrary.TryGetExport(_handle, "wooting_rgb_device_info", out _getDeviceInfoPointer)) throw new RGBDeviceException("Failed to load wooting function 'wooting_rgb_device_info'");
|
||||
if (!NativeLibrary.TryGetExport(_handle, "wooting_rgb_kbd_connected", out _keyboardConnectedPointer)) throw new RGBDeviceException("Failed to load wooting function 'wooting_rgb_kbd_connected'");
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user