--- a/src/devices/k100airWU/k100airWU.go +++ b/src/devices/k100airWU/k100airWU.go @@ -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{ @@ -253,6 +257,7 @@ d.setDeviceColor() // Device color d.setBrightnessLevel() // Brightness d.backendListener() // Control listener + d.setupOpenRGBController() // OpenRGB Controller d.setupClusterController() // RGB Cluster d.setupPerformance() // Performance d.setAutoBrightness() // Auto brightness @@ -411,7 +416,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 +790,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 +1168,65 @@ cluster.Get().AddDeviceController(clusterController) } +// setupOpenRGBController will create RGBController object for OpenRGB Client Integration +func (d *Device) setupOpenRGBController() { + 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) +} + +// 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.NotifyControllerChange(d.Serial) + } + 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 +1812,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 +2146,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 +++ b/web/k100airW.html @@ -148,6 +148,15 @@ + + +
+ {{ .Lang "txtOpenRGB" }} + +
{{ end }}