diff --git a/RGB.NET.Core/Devices/RGBDeviceLighting.cs b/RGB.NET.Core/Devices/RGBDeviceLighting.cs
index b362dc9..70a0607 100644
--- a/RGB.NET.Core/Devices/RGBDeviceLighting.cs
+++ b/RGB.NET.Core/Devices/RGBDeviceLighting.cs
@@ -18,8 +18,8 @@ namespace RGB.NET.Core
Key = 1,
///
- /// The supports per-keyboard-lightning.
+ /// The supports per-device-lightning.
///
- Keyboard = 2,
+ Device = 2,
}
}
diff --git a/RGB.NET.Devices.Logitech/Enum/LogitechLedIds.cs b/RGB.NET.Devices.Logitech/Enum/LogitechLedIds.cs
index f3edfd0..b3f871b 100644
--- a/RGB.NET.Devices.Logitech/Enum/LogitechLedIds.cs
+++ b/RGB.NET.Devices.Logitech/Enum/LogitechLedIds.cs
@@ -132,5 +132,7 @@ namespace RGB.NET.Devices.Logitech
G_9 = 0xFFF9,
G_LOGO = 0xFFFF1,
G_BADGE = 0xFFFF2,
+
+ DEVICE = 0xFFFFFFF
}
}
diff --git a/RGB.NET.Devices.Logitech/Generic/LogitechRGBDevice.cs b/RGB.NET.Devices.Logitech/Generic/LogitechRGBDevice.cs
index 6f51937..b1e435c 100644
--- a/RGB.NET.Devices.Logitech/Generic/LogitechRGBDevice.cs
+++ b/RGB.NET.Devices.Logitech/Generic/LogitechRGBDevice.cs
@@ -1,10 +1,8 @@
using System;
-using System.Collections.Generic;
using System.IO;
using System.Linq;
using RGB.NET.Core;
using RGB.NET.Core.Layout;
-using RGB.NET.Devices.Logitech.Native;
namespace RGB.NET.Devices.Logitech
{
@@ -56,7 +54,14 @@ namespace RGB.NET.Devices.Logitech
///
/// Initializes the and of the device.
///
- protected abstract void InitializeLayout();
+ protected virtual void InitializeLayout()
+ {
+ if (!(DeviceInfo is LogitechRGBDeviceInfo info)) return;
+ string basePath = info.ImageBasePath;
+ string layout = info.ImageLayout;
+ string layoutPath = info.LayoutPath;
+ ApplyLayoutFromFile(PathHelper.GetAbsolutePath($@"Layouts\Logitech\{basePath}\{layoutPath}.xml"), layout, PathHelper.GetAbsolutePath($@"Images\Logitech\{basePath}"));
+ }
///
/// Applies the given layout.
@@ -99,35 +104,6 @@ namespace RGB.NET.Devices.Logitech
}
}
- ///
- protected override void UpdateLeds(IEnumerable ledsToUpdate)
- {
- _LogitechGSDK.LogiLedSetTargetDevice(LogitechDeviceCaps.PerKeyRGB);
-
- List leds = ledsToUpdate.Where(x => x.Color.A > 0).ToList();
-
- byte[] bitmap = null;
- foreach (Led led in leds)
- {
- //TODO DarthAffe 26.03.2017: This is only needed since update by name doesn't work as expected for all keys ...
- if (BitmapMapping.BitmapOffset.TryGetValue(((LogitechLedId)led.Id).LedId, out int bitmapOffset))
- {
- if (bitmap == null)
- bitmap = BitmapMapping.CreateBitmap();
-
- BitmapMapping.SetColor(ref bitmap, bitmapOffset, led.Color);
- }
- else
- _LogitechGSDK.LogiLedSetLightingForKeyWithKeyName((int)((LogitechLedId)led.Id).LedId,
- (int)Math.Round(led.Color.RPercent * 100),
- (int)Math.Round(led.Color.GPercent * 100),
- (int)Math.Round(led.Color.BPercent * 100));
- }
-
- if (bitmap != null)
- _LogitechGSDK.LogiLedSetLightingFromBitmap(bitmap);
- }
-
#endregion
}
}
diff --git a/RGB.NET.Devices.Logitech/Generic/LogitechRGBDeviceInfo.cs b/RGB.NET.Devices.Logitech/Generic/LogitechRGBDeviceInfo.cs
index a9e98bc..262967c 100644
--- a/RGB.NET.Devices.Logitech/Generic/LogitechRGBDeviceInfo.cs
+++ b/RGB.NET.Devices.Logitech/Generic/LogitechRGBDeviceInfo.cs
@@ -32,7 +32,7 @@ namespace RGB.NET.Devices.Logitech
return RGBDeviceLighting.Key;
if (DeviceCaps.HasFlag(LogitechDeviceCaps.DeviceRGB))
- return RGBDeviceLighting.Keyboard;
+ return RGBDeviceLighting.Device;
return RGBDeviceLighting.None;
}
@@ -43,6 +43,21 @@ namespace RGB.NET.Devices.Logitech
///
public LogitechDeviceCaps DeviceCaps { get; }
+ ///
+ /// Gets the base of the image path used to load device-images.
+ ///
+ internal string ImageBasePath { get; }
+
+ ///
+ /// Gets the layout used to decide which images to load.
+ ///
+ internal string ImageLayout { get; }
+
+ ///
+ /// Gets the path/name of the layout-file.
+ ///
+ internal string LayoutPath { get; }
+
#endregion
#region Constructors
@@ -53,11 +68,20 @@ namespace RGB.NET.Devices.Logitech
/// The type of the .
/// The represented device model.
/// The lighting-capabilities of the device.
- internal LogitechRGBDeviceInfo(RGBDeviceType deviceType, string model, LogitechDeviceCaps deviceCaps)
+ /// The base of the image path used to load device-images.
+ /// The layout used to decide which images to load.
+ /// The path/name of the layout-file.
+ internal LogitechRGBDeviceInfo(RGBDeviceType deviceType, string model, LogitechDeviceCaps deviceCaps,
+ string imageBasePath, string imageLayout, string layoutPath)
{
this.DeviceType = deviceType;
this.Model = model;
this.DeviceCaps = deviceCaps;
+ this.ImageBasePath = imageBasePath;
+ this.ImageLayout = imageLayout;
+ this.LayoutPath = layoutPath;
+
+ Image = new Uri(PathHelper.GetAbsolutePath($@"Images\Logitech\{LayoutPath}.png"), UriKind.Absolute);
}
#endregion
diff --git a/RGB.NET.Devices.Logitech/HID/DeviceChecker.cs b/RGB.NET.Devices.Logitech/HID/DeviceChecker.cs
index 8ff6f09..0204e45 100644
--- a/RGB.NET.Devices.Logitech/HID/DeviceChecker.cs
+++ b/RGB.NET.Devices.Logitech/HID/DeviceChecker.cs
@@ -1,5 +1,7 @@
using System.Collections.Generic;
+using System.Linq;
using HidSharp;
+using RGB.NET.Core;
namespace RGB.NET.Devices.Logitech.HID
{
@@ -8,31 +10,31 @@ namespace RGB.NET.Devices.Logitech.HID
{
#region Constants
- //TODO DarthAffe 04.02.2017: Add IDs
private const int VENDOR_ID = 0x046D;
- private const int G910_ID = 0xC32B;
- private const int G810_ID = 0x0;
- private const int G610_ID = 0xC333;
+
+ //TODO DarthAffe 14.11.2017: Add devices
+ private static readonly List<(string model, RGBDeviceType deviceType, int id, string imageBasePath, string imageLayout, string layoutPath)> PER_KEY_DEVICES
+ = new List<(string model, RGBDeviceType deviceType, int id, string imageBasePath, string imageLayout, string layoutPath)>
+ {
+ ("G910", RGBDeviceType.Keyboard, 0xC32B, "", "", ""),
+ ("G910", RGBDeviceType.Keyboard, 0xC333, "", "", ""),
+ };
+
+ private static readonly List<(string model, RGBDeviceType deviceType, int id, string imageBasePath, string imageLayout, string layoutPath)> PER_DEVICE_DEVICES
+ = new List<(string model, RGBDeviceType deviceType, int id, string imageBasePath, string imageLayout, string layoutPath)>
+ {
+ ("G403", RGBDeviceType.Mouse, 0xC083, "", "", ""),
+ };
#endregion
#region Properties & Fields
- public static string ConnectedDeviceModel
- {
- get
- {
- if (IsG910Connected) return "G910";
- if (IsG810Connected) return "G810";
- if (IsG610Connected) return "G610";
- return null;
- }
- }
+ public static bool IsPerKeyDeviceConnected { get; private set; }
+ public static (string model, RGBDeviceType deviceType, int id, string imageBasePath, string imageLayout, string layoutPath) PerKeyDeviceData { get; private set; }
- public static bool IsDeviceConnected => IsG910Connected || IsG810Connected || IsG610Connected;
- public static bool IsG910Connected { get; private set; }
- public static bool IsG810Connected { get; private set; }
- public static bool IsG610Connected { get; private set; }
+ public static bool IsPerDeviceDeviceConnected { get; private set; }
+ public static (string model, RGBDeviceType deviceType, int id, string imageBasePath, string imageLayout, string layoutPath) PerDeviceDeviceData { get; private set; }
#endregion
@@ -40,21 +42,23 @@ namespace RGB.NET.Devices.Logitech.HID
internal static void LoadDeviceList()
{
- IsG910Connected = false;
- IsG810Connected = false;
- IsG610Connected = false;
-
HidDeviceLoader loader = new HidDeviceLoader();
- IEnumerable devices = loader.GetDevices();
- foreach (HidDevice hidDevice in devices)
- if (hidDevice.VendorID == VENDOR_ID)
+ List ids = loader.GetDevices(VENDOR_ID).Select(x => x.ProductID).Distinct().ToList();
+
+ foreach ((string model, RGBDeviceType deviceType, int id, string imageBasePath, string imageLayout, string layoutPath) deviceData in PER_KEY_DEVICES)
+ if (ids.Contains(deviceData.id))
{
- if (hidDevice.ProductID == G910_ID)
- IsG910Connected = true;
- else if (hidDevice.ProductID == G810_ID)
- IsG810Connected = true;
- else if (hidDevice.ProductID == G610_ID)
- IsG610Connected = true;
+ IsPerKeyDeviceConnected = true;
+ PerKeyDeviceData = deviceData;
+ break;
+ }
+
+ foreach ((string model, RGBDeviceType deviceType, int id, string imageBasePath, string imageLayout, string layoutPath) deviceData in PER_DEVICE_DEVICES)
+ if (ids.Contains(deviceData.id))
+ {
+ IsPerDeviceDeviceConnected = true;
+ PerDeviceDeviceData = deviceData;
+ break;
}
}
diff --git a/RGB.NET.Devices.Logitech/Helper/BitmapMapping.cs b/RGB.NET.Devices.Logitech/Helper/BitmapMapping.cs
index f0ac3f5..dba979c 100644
--- a/RGB.NET.Devices.Logitech/Helper/BitmapMapping.cs
+++ b/RGB.NET.Devices.Logitech/Helper/BitmapMapping.cs
@@ -153,10 +153,7 @@ namespace RGB.NET.Devices.Logitech
#region Methods
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- internal static byte[] CreateBitmap()
- {
- return new byte[BITMAP_SIZE];
- }
+ internal static byte[] CreateBitmap() => new byte[BITMAP_SIZE];
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static void SetColor(ref byte[] bitmap, int offset, Color color)
diff --git a/RGB.NET.Devices.Logitech/Keyboard/LogitechKeyboardRGBDevice.cs b/RGB.NET.Devices.Logitech/Keyboard/LogitechKeyboardRGBDevice.cs
deleted file mode 100644
index adb8882..0000000
--- a/RGB.NET.Devices.Logitech/Keyboard/LogitechKeyboardRGBDevice.cs
+++ /dev/null
@@ -1,51 +0,0 @@
-// ReSharper disable MemberCanBePrivate.Global
-// ReSharper disable UnusedMember.Global
-
-using RGB.NET.Core;
-
-namespace RGB.NET.Devices.Logitech
-{
- ///
- ///
- /// Represents a logitech keyboard.
- ///
- public class LogitechKeyboardRGBDevice : LogitechRGBDevice
- {
- #region Properties & Fields
-
- ///
- /// Gets information about the .
- ///
- public LogitechKeyboardRGBDeviceInfo KeyboardDeviceInfo { get; }
-
- #endregion
-
- #region Constructors
-
- ///
- ///
- /// Initializes a new instance of the class.
- ///
- /// The specific information provided by logitech for the keyboard
- internal LogitechKeyboardRGBDevice(LogitechKeyboardRGBDeviceInfo info)
- : base(info)
- {
- this.KeyboardDeviceInfo = info;
- }
-
- #endregion
-
- #region Methods
-
- ///
- protected override void InitializeLayout()
- {
- string model = KeyboardDeviceInfo.Model.Replace(" ", string.Empty).ToUpper();
- ApplyLayoutFromFile(PathHelper.GetAbsolutePath(
- $@"Layouts\Logitech\Keyboards\{model}\{KeyboardDeviceInfo.PhysicalLayout.ToString().ToUpper()}.xml"),
- KeyboardDeviceInfo.LogicalLayout.ToString(), PathHelper.GetAbsolutePath(@"Images\Logitech\Keyboards"));
- }
-
- #endregion
- }
-}
diff --git a/RGB.NET.Devices.Logitech/Keyboard/LogitechKeyboardRGBDeviceInfo.cs b/RGB.NET.Devices.Logitech/Keyboard/LogitechKeyboardRGBDeviceInfo.cs
deleted file mode 100644
index 00d3811..0000000
--- a/RGB.NET.Devices.Logitech/Keyboard/LogitechKeyboardRGBDeviceInfo.cs
+++ /dev/null
@@ -1,65 +0,0 @@
-// ReSharper disable MemberCanBePrivate.Global
-// ReSharper disable UnusedMember.Global
-
-using System;
-using System.Globalization;
-using RGB.NET.Core;
-
-namespace RGB.NET.Devices.Logitech
-{
- ///
- ///
- /// Represents a generic information for a .
- ///
- public class LogitechKeyboardRGBDeviceInfo : LogitechRGBDeviceInfo
- {
- #region Properties & Fields
-
- ///
- /// Gets the physical layout of the keyboard.
- ///
- public LogitechPhysicalKeyboardLayout PhysicalLayout { get; private set; }
-
- ///
- /// Gets the logical layout of the keyboard.
- ///
- public LogitechLogicalKeyboardLayout LogicalLayout { get; private set; }
-
- #endregion
-
- #region Constructors
-
- ///
- ///
- /// Internal constructor of managed .
- ///
- /// The represented device model.
- /// The lighting-capabilities of the device.
- /// The of the layout this keyboard is using
- internal LogitechKeyboardRGBDeviceInfo(string model, LogitechDeviceCaps deviceCaps, CultureInfo culture)
- : base(RGBDeviceType.Keyboard, model, deviceCaps)
- {
- SetLayouts(culture.KeyboardLayoutId);
-
- Image = new Uri(PathHelper.GetAbsolutePath($@"Images\Logitech\Keyboards\{Model.Replace(" ", string.Empty).ToUpper()}.png"), UriKind.Absolute);
- }
-
- #endregion
-
- #region Methods
-
- private void SetLayouts(int keyboardLayoutId)
- {
- switch (keyboardLayoutId)
- {
- //TODO DarthAffe 04.02.2017: Check all available keyboards and there layout-ids
- default:
- PhysicalLayout = LogitechPhysicalKeyboardLayout.UK;
- LogicalLayout = LogitechLogicalKeyboardLayout.DE;
- break;
- }
- }
-
- #endregion
- }
-}
diff --git a/RGB.NET.Devices.Logitech/LogitechDeviceProvider.cs b/RGB.NET.Devices.Logitech/LogitechDeviceProvider.cs
index 37d31f9..128bf52 100644
--- a/RGB.NET.Devices.Logitech/LogitechDeviceProvider.cs
+++ b/RGB.NET.Devices.Logitech/LogitechDeviceProvider.cs
@@ -8,6 +8,7 @@ using System.Globalization;
using RGB.NET.Core;
using RGB.NET.Devices.Logitech.HID;
using RGB.NET.Devices.Logitech.Native;
+using RGB.NET.Devices.Logitech.PerKey;
namespace RGB.NET.Devices.Logitech
{
@@ -66,7 +67,7 @@ namespace RGB.NET.Devices.Logitech
/// Thrown if this constructor is called even if there is already an instance of this class.
public LogitechDeviceProvider()
{
- if (_instance != null) throw new InvalidOperationException($"There can be only one instanc of type {nameof(LogitechDeviceProvider)}");
+ if (_instance != null) throw new InvalidOperationException($"There can be only one instance of type {nameof(LogitechDeviceProvider)}");
_instance = this;
}
@@ -95,25 +96,22 @@ namespace RGB.NET.Devices.Logitech
_LogitechGSDK.LogiLedSaveCurrentLighting();
IList devices = new List();
-
DeviceChecker.LoadDeviceList();
- if (DeviceChecker.IsDeviceConnected)
- {
- LogitechRGBDevice device = new LogitechKeyboardRGBDevice(new LogitechKeyboardRGBDeviceInfo(
- DeviceChecker.ConnectedDeviceModel, LogitechDeviceCaps.PerKeyRGB, GetCulture()));
- devices.Add(device);
- try
- {
- device.Initialize();
- }
- catch
- {
- if (throwExceptions)
- throw;
- return false;
- }
+ if (DeviceChecker.IsPerKeyDeviceConnected)
+ {
+ (string model, RGBDeviceType deviceType, int _, string imageBasePath, string imageLayout, string layoutPath) = DeviceChecker.PerKeyDeviceData;
+ LogitechRGBDevice device = new LogitechPerKeyRGBDevice(new LogitechRGBDeviceInfo(deviceType, model, LogitechDeviceCaps.PerKeyRGB, imageBasePath, imageLayout, layoutPath));
+ devices.Add(device);
}
+
+ if (DeviceChecker.IsPerDeviceDeviceConnected)
+ {
+ (string model, RGBDeviceType deviceType, int _, string imageBasePath, string imageLayout, string layoutPath) = DeviceChecker.PerDeviceDeviceData;
+ LogitechRGBDevice device = new LogitechPerKeyRGBDevice(new LogitechRGBDeviceInfo(deviceType, model, LogitechDeviceCaps.DeviceRGB, imageBasePath, imageLayout, layoutPath));
+ devices.Add(device);
+ }
+
Devices = new ReadOnlyCollection(devices);
}
catch
diff --git a/RGB.NET.Devices.Logitech/Native/_LogitechGSDK.cs b/RGB.NET.Devices.Logitech/Native/_LogitechGSDK.cs
index b1b1bb0..ce5e678 100644
--- a/RGB.NET.Devices.Logitech/Native/_LogitechGSDK.cs
+++ b/RGB.NET.Devices.Logitech/Native/_LogitechGSDK.cs
@@ -49,6 +49,7 @@ namespace RGB.NET.Devices.Logitech.Native
_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));
}
@@ -85,6 +86,7 @@ namespace RGB.NET.Devices.Logitech.Native
private static LogiLedGetSdkVersionPointer _logiLedGetSdkVersionPointer;
private static LogiLedSaveCurrentLightingPointer _lgiLedSaveCurrentLightingPointer;
private static LogiLedRestoreLightingPointer _logiLedRestoreLightingPointer;
+ private static LogiLedSetLightingPointer _logiLedSetLightingPointer;
private static LogiLedSetLightingForKeyWithKeyNamePointer _logiLedSetLightingForKeyWithKeyNamePointer;
private static LogiLedSetLightingFromBitmapPointer _logiLedSetLightingFromBitmapPointer;
@@ -110,6 +112,9 @@ namespace RGB.NET.Devices.Logitech.Native
[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);
@@ -160,6 +165,11 @@ namespace RGB.NET.Devices.Logitech.Native
return _logiLedRestoreLightingPointer();
}
+ internal static bool LogiLedSetLighting(int redPercentage, int greenPercentage, int bluePercentage)
+ {
+ return _logiLedSetLightingPointer(redPercentage, greenPercentage, bluePercentage);
+ }
+
internal static bool LogiLedSetLightingForKeyWithKeyName(int keyCode,
int redPercentage, int greenPercentage, int bluePercentage)
{
diff --git a/RGB.NET.Devices.Logitech/PerDevice/LogitechPerDeviceRGBDevice.cs b/RGB.NET.Devices.Logitech/PerDevice/LogitechPerDeviceRGBDevice.cs
new file mode 100644
index 0000000..5dc4b36
--- /dev/null
+++ b/RGB.NET.Devices.Logitech/PerDevice/LogitechPerDeviceRGBDevice.cs
@@ -0,0 +1,64 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using RGB.NET.Core;
+using RGB.NET.Devices.Logitech.Native;
+
+namespace RGB.NET.Devices.Logitech.PerDevice
+{
+ ///
+ ///
+ /// Represents a logitech per-device-lightable device.
+ ///
+ public class LogitechPerDeviceRGBDevice : LogitechRGBDevice
+ {
+ #region Properties & Fields
+
+ ///
+ /// Gets information about the .
+ ///
+ public LogitechRGBDeviceInfo PerDeviceDeviceInfo { get; }
+
+ #endregion
+
+ #region Constructors
+
+ ///
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The specific information provided by logitech for the per-device-lightable device
+ internal LogitechPerDeviceRGBDevice(LogitechRGBDeviceInfo info)
+ : base(info)
+ {
+ this.PerDeviceDeviceInfo = info;
+ }
+
+ #endregion
+
+ #region Methods
+
+ ///
+ protected override void InitializeLayout()
+ {
+ base.InitializeLayout();
+
+ if (LedMapping.Count == 0)
+ InitializeLed(new LogitechLedId(this, LogitechLedIds.DEVICE), new Rectangle(0, 0, 1, 1));
+ }
+
+ ///
+ protected override void UpdateLeds(IEnumerable ledsToUpdate)
+ {
+ Led led = ledsToUpdate.FirstOrDefault(x => x.Color.A > 0);
+ if (led == null) return;
+
+ _LogitechGSDK.LogiLedSetTargetDevice(LogitechDeviceCaps.DeviceRGB);
+ _LogitechGSDK.LogiLedSetLighting((int)Math.Round(led.Color.RPercent * 100),
+ (int)Math.Round(led.Color.GPercent * 100),
+ (int)Math.Round(led.Color.BPercent * 100));
+ }
+
+ #endregion
+ }
+}
diff --git a/RGB.NET.Devices.Logitech/PerKey/LogitechPerKeyRGBDevice.cs b/RGB.NET.Devices.Logitech/PerKey/LogitechPerKeyRGBDevice.cs
new file mode 100644
index 0000000..d9c17c1
--- /dev/null
+++ b/RGB.NET.Devices.Logitech/PerKey/LogitechPerKeyRGBDevice.cs
@@ -0,0 +1,73 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using RGB.NET.Core;
+using RGB.NET.Devices.Logitech.Native;
+
+namespace RGB.NET.Devices.Logitech.PerKey
+{
+ ///
+ ///
+ /// Represents a logitech per-key-lightable device.
+ ///
+ public class LogitechPerKeyRGBDevice : LogitechRGBDevice
+ {
+ #region Properties & Fields
+
+ ///
+ /// Gets information about the .
+ ///
+ public LogitechRGBDeviceInfo PerKeyDeviceInfo { get; }
+
+ #endregion
+
+ #region Constructors
+
+ ///
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The specific information provided by logitech for the per-key-lightable device
+ internal LogitechPerKeyRGBDevice(LogitechRGBDeviceInfo info)
+ : base(info)
+ {
+ this.PerKeyDeviceInfo = info;
+ }
+
+ #endregion
+
+ #region Methods
+
+ ///
+ protected override void UpdateLeds(IEnumerable ledsToUpdate)
+ {
+ List leds = ledsToUpdate.Where(x => x.Color.A > 0).ToList();
+ if (leds.Count <= 0) return;
+
+ _LogitechGSDK.LogiLedSetTargetDevice(LogitechDeviceCaps.PerKeyRGB);
+
+ byte[] bitmap = null;
+ foreach (Led led in leds)
+ {
+ // DarthAffe 26.03.2017: This is only needed since update by name doesn't work as expected for all keys ...
+ if (BitmapMapping.BitmapOffset.TryGetValue(((LogitechLedId)led.Id).LedId, out int bitmapOffset))
+ {
+ if (bitmap == null)
+ bitmap = BitmapMapping.CreateBitmap();
+
+ BitmapMapping.SetColor(ref bitmap, bitmapOffset, led.Color);
+ }
+ else
+ _LogitechGSDK.LogiLedSetLightingForKeyWithKeyName((int)((LogitechLedId)led.Id).LedId,
+ (int)Math.Round(led.Color.RPercent * 100),
+ (int)Math.Round(led.Color.GPercent * 100),
+ (int)Math.Round(led.Color.BPercent * 100));
+ }
+
+ if (bitmap != null)
+ _LogitechGSDK.LogiLedSetLightingFromBitmap(bitmap);
+ }
+
+ #endregion
+ }
+}
diff --git a/RGB.NET.Devices.Logitech/RGB.NET.Devices.Logitech.csproj b/RGB.NET.Devices.Logitech/RGB.NET.Devices.Logitech.csproj
index b2ca124..aeeca58 100644
--- a/RGB.NET.Devices.Logitech/RGB.NET.Devices.Logitech.csproj
+++ b/RGB.NET.Devices.Logitech/RGB.NET.Devices.Logitech.csproj
@@ -58,10 +58,10 @@
-
-
+
+
@@ -200,6 +200,7 @@
+