258 lines
7.7 KiB
Diff
258 lines
7.7 KiB
Diff
--- a/src/devices/k100airWU/k100airWU.go 2026-06-13 21:26:01.000000000 -0600
|
|
+++ b/src/devices/k100airWU/k100airWU.go 2026-06-18 13:03:58.116016558 -0600
|
|
@@ -13,6 +13,7 @@
|
|
"OpenLinkHub/src/keyboards"
|
|
"OpenLinkHub/src/logger"
|
|
"OpenLinkHub/src/macro"
|
|
+ "OpenLinkHub/src/openrgb"
|
|
"OpenLinkHub/src/rgb"
|
|
"OpenLinkHub/src/stats"
|
|
"OpenLinkHub/src/temperatures"
|
|
@@ -57,6 +58,7 @@
|
|
AutoBrightness int
|
|
Profiles []string
|
|
RGBCluster bool
|
|
+ OpenRGBIntegration bool
|
|
DisableAltTab bool
|
|
DisableAltF4 bool
|
|
DisableShiftTab bool
|
|
@@ -73,6 +75,7 @@
|
|
Product string `json:"product"`
|
|
Serial string `json:"serial"`
|
|
Firmware string `json:"firmware"`
|
|
+ Path string
|
|
activeRgb *rgb.ActiveRGB
|
|
UserProfiles map[string]*DeviceProfile `json:"userProfiles"`
|
|
Devices map[int]string `json:"devices"`
|
|
@@ -202,6 +205,7 @@
|
|
3: "100 %",
|
|
},
|
|
Product: "K100 AIR",
|
|
+ Path: path,
|
|
LEDChannels: 137,
|
|
Layouts: keyboards.GetLayouts(keyboardKey),
|
|
KeyAssignmentTypes: map[int]string{
|
|
@@ -256,6 +260,9 @@
|
|
d.setupClusterController() // RGB Cluster
|
|
d.setupPerformance() // Performance
|
|
d.setAutoBrightness() // Auto brightness
|
|
+ if d.DeviceProfile != nil && d.DeviceProfile.OpenRGBIntegration {
|
|
+ d.setupOpenRGBController() // OpenRGB Controller
|
|
+ }
|
|
d.createDevice() // Device register
|
|
logger.Log(logger.Fields{"serial": d.Serial, "product": d.Product}).Info("Device successfully initialized")
|
|
|
|
@@ -411,7 +418,16 @@
|
|
|
|
// getKeyData will return key data for given key hash
|
|
func (d *Device) getKeyData(keyHash string) *keyboards.Key {
|
|
- for _, value := range d.DeviceProfile.Keyboards[d.DeviceProfile.Profile].Row {
|
|
+ if d.DeviceProfile == nil {
|
|
+ return nil
|
|
+ }
|
|
+
|
|
+ keyboard := d.DeviceProfile.Keyboards[d.DeviceProfile.Profile]
|
|
+ if keyboard == nil {
|
|
+ return nil
|
|
+ }
|
|
+
|
|
+ for _, value := range keyboard.Row {
|
|
for _, key := range value.Keys {
|
|
for _, hash := range key.KeyHash {
|
|
if hash == keyHash {
|
|
@@ -776,6 +792,7 @@
|
|
deviceProfile.LCDMode = d.DeviceProfile.LCDMode
|
|
deviceProfile.LCDRotation = d.DeviceProfile.LCDRotation
|
|
deviceProfile.RGBCluster = d.DeviceProfile.RGBCluster
|
|
+ deviceProfile.OpenRGBIntegration = d.DeviceProfile.OpenRGBIntegration
|
|
deviceProfile.DisableAltTab = d.DeviceProfile.DisableAltTab
|
|
deviceProfile.DisableAltF4 = d.DeviceProfile.DisableAltF4
|
|
deviceProfile.DisableShiftTab = d.DeviceProfile.DisableShiftTab
|
|
@@ -1153,11 +1170,69 @@
|
|
cluster.Get().AddDeviceController(clusterController)
|
|
}
|
|
|
|
+// setupOpenRGBController will create RGBController object for OpenRGB Client Integration
|
|
+func (d *Device) setupOpenRGBController() {
|
|
+ openrgb.RemoveDeviceControllerBySerial(d.Serial)
|
|
+
|
|
+ controller := &common.OpenRGBController{
|
|
+ Name: d.Product,
|
|
+ Vendor: "Corsair",
|
|
+ Description: "OpenLinkHub Backend Device",
|
|
+ FwVersion: d.Firmware,
|
|
+ Serial: d.Serial,
|
|
+ Location: fmt.Sprintf("HID: %s", d.Path),
|
|
+ Zones: nil,
|
|
+ Colors: make([]byte, d.LEDChannels*3),
|
|
+ ActiveMode: 0,
|
|
+ WriteColorEx: d.writeColorEx,
|
|
+ DeviceType: common.DeviceTypeKeyboard,
|
|
+ ColorMode: common.ColorModePerLed,
|
|
+ }
|
|
+
|
|
+ controller.Zones = append(controller.Zones,
|
|
+ common.OpenRGBZone{
|
|
+ Name: "Keyboard",
|
|
+ NumLEDs: uint32(d.LEDChannels),
|
|
+ ZoneType: common.ZoneTypeLinear,
|
|
+ },
|
|
+ )
|
|
+ openrgb.AddDeviceController(controller)
|
|
+ openrgb.SendToOpenRGB()
|
|
+}
|
|
+
|
|
+// ProcessSetOpenRgbIntegration will update OpenRGB integration status
|
|
+func (d *Device) ProcessSetOpenRgbIntegration(enabled bool) uint8 {
|
|
+ if d.DeviceProfile == nil {
|
|
+ return 0
|
|
+ }
|
|
+ if d.DeviceProfile.RGBCluster {
|
|
+ return 2
|
|
+ }
|
|
+
|
|
+ d.DeviceProfile.OpenRGBIntegration = enabled
|
|
+ d.saveDeviceProfile()
|
|
+ if d.activeRgb != nil {
|
|
+ d.activeRgb.Exit <- true
|
|
+ d.activeRgb = nil
|
|
+ }
|
|
+ if enabled {
|
|
+ d.setupOpenRGBController()
|
|
+ } else {
|
|
+ openrgb.RemoveDeviceControllerBySerial(d.Serial)
|
|
+ openrgb.SendToOpenRGB()
|
|
+ }
|
|
+ d.setDeviceColor()
|
|
+ return 1
|
|
+}
|
|
+
|
|
// ProcessSetRgbCluster will update OpenRGB integration status
|
|
func (d *Device) ProcessSetRgbCluster(enabled bool) uint8 {
|
|
if d.DeviceProfile == nil {
|
|
return 0
|
|
}
|
|
+ if d.DeviceProfile.OpenRGBIntegration {
|
|
+ return 2
|
|
+ }
|
|
|
|
d.DeviceProfile.RGBCluster = enabled
|
|
d.saveDeviceProfile() // Save profile
|
|
@@ -1743,6 +1818,12 @@
|
|
return
|
|
}
|
|
|
|
+ // OpenRGB
|
|
+ if d.DeviceProfile.OpenRGBIntegration {
|
|
+ logger.Log(logger.Fields{}).Info("Exiting setDeviceColor() due to OpenRGB client")
|
|
+ return
|
|
+ }
|
|
+
|
|
// RGB Cluster
|
|
if d.DeviceProfile.RGBCluster {
|
|
logger.Log(logger.Fields{}).Info("Exiting setDeviceColor() due to RGB Cluster")
|
|
@@ -2071,6 +2152,85 @@
|
|
}
|
|
}
|
|
}
|
|
+
|
|
+ if d.DeviceProfile.Performance {
|
|
+ buf[6] = 255
|
|
+ buf[7] = 255
|
|
+ buf[8] = 255
|
|
+ buf[lockLedIndex] = 255
|
|
+ buf[lockLedIndex+1] = 0
|
|
+ buf[lockLedIndex+2] = 0
|
|
+ }
|
|
+
|
|
+ buffer := make([]byte, len(dataTypeSetColor)+len(buf)+headerWriteSize)
|
|
+ binary.LittleEndian.PutUint16(buffer[0:2], uint16(len(buf)))
|
|
+ copy(buffer[headerWriteSize:headerWriteSize+len(dataTypeSetColor)], dataTypeSetColor)
|
|
+ copy(buffer[headerWriteSize+len(dataTypeSetColor):], buf)
|
|
+
|
|
+ chunks := common.ProcessMultiChunkPacket(buffer, maxBufferSizePerRequest)
|
|
+ for i, chunk := range chunks {
|
|
+ if i == 0 {
|
|
+ _, err := d.transfer(cmdWriteColor, chunk)
|
|
+ if err != nil {
|
|
+ logger.Log(logger.Fields{"error": err, "serial": d.Serial}).Error("Unable to write to color endpoint")
|
|
+ }
|
|
+ } else {
|
|
+ _, err := d.transfer(dataTypeSubColor, chunk)
|
|
+ if err != nil {
|
|
+ logger.Log(logger.Fields{"error": err, "serial": d.Serial}).Error("Unable to write to color endpoint")
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+}
|
|
+
|
|
+// writeColorEx will write data to the device from OpenRGB client
|
|
+func (d *Device) writeColorEx(data []byte, _ int) {
|
|
+ if d.DeviceProfile == nil || !d.DeviceProfile.OpenRGBIntegration {
|
|
+ return
|
|
+ }
|
|
+
|
|
+ if d.Exit {
|
|
+ return
|
|
+ }
|
|
+
|
|
+ d.writeOpenRGBColors(data)
|
|
+}
|
|
+
|
|
+// writeOpenRGBColors maps sequential OpenRGB LED data onto the keyboard packet
|
|
+func (d *Device) writeOpenRGBColors(data []byte) {
|
|
+ d.deviceLock.Lock()
|
|
+ defer d.deviceLock.Unlock()
|
|
+
|
|
+ if d.DeviceProfile == nil {
|
|
+ return
|
|
+ }
|
|
+
|
|
+ keyboard := d.DeviceProfile.Keyboards[d.DeviceProfile.Profile]
|
|
+ if keyboard == nil {
|
|
+ return
|
|
+ }
|
|
+
|
|
+ var buf = make([]byte, colorPacketLength)
|
|
+ led := 0
|
|
+
|
|
+ for _, rows := range keyboard.Row {
|
|
+ for _, key := range rows.Keys {
|
|
+ if key.NoColor {
|
|
+ continue
|
|
+ }
|
|
+ for _, packetIndex := range key.PacketIndex {
|
|
+ base := led * 3
|
|
+ if base+2 >= len(data) {
|
|
+ led++
|
|
+ continue
|
|
+ }
|
|
+ buf[packetIndex] = data[base]
|
|
+ buf[packetIndex+1] = data[base+1]
|
|
+ buf[packetIndex+2] = data[base+2]
|
|
+ led++
|
|
+ }
|
|
+ }
|
|
+ }
|
|
|
|
if d.DeviceProfile.Performance {
|
|
buf[6] = 255
|
|
--- a/web/k100airW.html 2026-06-13 21:26:01.000000000 -0600
|
|
+++ b/web/k100airW.html 2026-06-18 13:03:58.116981931 -0600
|
|
@@ -148,6 +148,15 @@
|
|
<span class="toggle-track"></span>
|
|
</label>
|
|
</div>
|
|
+
|
|
+ <!-- OpenRGB -->
|
|
+ <div class="settings-row">
|
|
+ <span class="settings-label text-ellipsis">{{ .Lang "txtOpenRGB" }}</span>
|
|
+ <label class="system-toggle compact">
|
|
+ <input type="checkbox" class="toggleOpenRGB" {{ if $deviceProfile.OpenRGBIntegration }} checked {{ end }}>
|
|
+ <span class="toggle-track"></span>
|
|
+ </label>
|
|
+ </div>
|
|
{{ end }}
|
|
|
|
<!-- Auto Brightness -->
|