|
|
@@ -11,13 +11,13 @@ import (
|
|
|
)
|
|
|
|
|
|
type zoneProtocol interface {
|
|
|
- SetValue(via.LEDType, uint8, uint8) error
|
|
|
- SetColor(via.LEDType, uint8, uint8) error
|
|
|
+ SetValue(via.Channel, uint8, uint8) error
|
|
|
+ SetColor(via.Channel, uint8, uint8) error
|
|
|
}
|
|
|
|
|
|
type rgbProtocol interface {
|
|
|
zoneProtocol
|
|
|
- GetValue(via.LEDType, uint8) ([]byte, error)
|
|
|
+ GetValue(via.Channel, uint8) ([]byte, error)
|
|
|
Close() error
|
|
|
}
|
|
|
|
|
|
@@ -25,7 +25,46 @@ var openRGBProtocol = func() (rgbProtocol, error) {
|
|
|
return OpenDevice()
|
|
|
}
|
|
|
|
|
|
-func forEachSelectedZone(zones []intrgb.Zone, fn func(intrgb.Zone, via.LEDType) error) error {
|
|
|
+// keyboardFor is a seam for tests; it reads the optional keyboards.json.
|
|
|
+var keyboardFor = intdevice.KeyboardFor
|
|
|
+
|
|
|
+// targetDeviceData is everything a command needs before it opens the keyboard.
|
|
|
+type targetDeviceData struct {
|
|
|
+ Device intdevice.Device
|
|
|
+ Display map[uint16]string
|
|
|
+ // Requested is nil when no --zone was given, which means every channel
|
|
|
+ // the keyboard has.
|
|
|
+ Requested []via.Channel
|
|
|
+}
|
|
|
+
|
|
|
+// prepareTarget resolves the keyboard, its display names and the requested
|
|
|
+// channels. Enumeration does not open a HID handle, so an unusable --zone value
|
|
|
+// is still rejected before the device is opened.
|
|
|
+func prepareTarget() (targetDeviceData, error) {
|
|
|
+ devices, err := discoverAll()
|
|
|
+ if err != nil {
|
|
|
+ return targetDeviceData{}, fmt.Errorf("discover: %w", err)
|
|
|
+ }
|
|
|
+
|
|
|
+ dev, err := selectDevice(devices, targetDevice)
|
|
|
+ if err != nil {
|
|
|
+ return targetDeviceData{}, err
|
|
|
+ }
|
|
|
+
|
|
|
+ keyboard, _, err := keyboardFor(dev.VendorID, dev.ProductID)
|
|
|
+ if err != nil {
|
|
|
+ return targetDeviceData{}, err
|
|
|
+ }
|
|
|
+
|
|
|
+ requested, err := resolveZoneName(targetZone, keyboard.Channels)
|
|
|
+ if err != nil {
|
|
|
+ return targetDeviceData{}, err
|
|
|
+ }
|
|
|
+
|
|
|
+ return targetDeviceData{Device: dev, Display: keyboard.Channels, Requested: requested}, nil
|
|
|
+}
|
|
|
+
|
|
|
+func forEachSelectedZone(zones []intrgb.Zone, fn func(intrgb.Zone, via.Channel) error) error {
|
|
|
channels := zoneChannels(zones)
|
|
|
for i, zone := range zones {
|
|
|
if err := fn(zone, channels[i]); err != nil {
|
|
|
@@ -36,7 +75,7 @@ func forEachSelectedZone(zones []intrgb.Zone, fn func(intrgb.Zone, via.LEDType)
|
|
|
}
|
|
|
|
|
|
func setValueOnZones(proto zoneProtocol, zones []intrgb.Zone, param, value uint8) error {
|
|
|
- return forEachSelectedZone(zones, func(_ intrgb.Zone, channel via.LEDType) error {
|
|
|
+ return forEachSelectedZone(zones, func(_ intrgb.Zone, channel via.Channel) error {
|
|
|
return proto.SetValue(channel, param, value)
|
|
|
})
|
|
|
}
|
|
|
@@ -95,7 +134,7 @@ func setValueVerified(proto rgbProtocol, zones []intrgb.Zone, param, value uint8
|
|
|
|
|
|
results := make([]zoneResult, 0, len(zones))
|
|
|
for _, zone := range zones {
|
|
|
- raw, err := proto.GetValue(via.LEDType(zone.Channel()), param)
|
|
|
+ raw, err := proto.GetValue(via.Channel(zone.Channel()), param)
|
|
|
if err != nil {
|
|
|
return nil, fmt.Errorf("read back value 0x%02x for %s: %w", param, zone, err)
|
|
|
}
|
|
|
@@ -145,7 +184,7 @@ func setColorVerified(proto rgbProtocol, zones []intrgb.Zone, hue, saturation ui
|
|
|
|
|
|
results := make([]colorResult, 0, len(zones))
|
|
|
for _, zone := range zones {
|
|
|
- raw, err := proto.GetValue(via.LEDType(zone.Channel()), uint8(intrgb.ColorValue))
|
|
|
+ raw, err := proto.GetValue(via.Channel(zone.Channel()), uint8(intrgb.ColorValue))
|
|
|
if err != nil {
|
|
|
return nil, fmt.Errorf("read back color for %s: %w", zone, err)
|
|
|
}
|
|
|
@@ -168,13 +207,13 @@ func setSpeedOnZones(proto zoneProtocol, zones []intrgb.Zone, value uint8) error
|
|
|
}
|
|
|
|
|
|
func setColorOnZones(proto zoneProtocol, zones []intrgb.Zone, hue, saturation uint8) error {
|
|
|
- return forEachSelectedZone(zones, func(_ intrgb.Zone, channel via.LEDType) error {
|
|
|
+ return forEachSelectedZone(zones, func(_ intrgb.Zone, channel via.Channel) error {
|
|
|
return proto.SetColor(channel, hue, saturation)
|
|
|
})
|
|
|
}
|
|
|
|
|
|
func disableLightingOnZones(proto zoneProtocol, zones []intrgb.Zone) error {
|
|
|
- return forEachSelectedZone(zones, func(_ intrgb.Zone, channel via.LEDType) error {
|
|
|
+ return forEachSelectedZone(zones, func(_ intrgb.Zone, channel via.Channel) error {
|
|
|
if err := proto.SetValue(channel, uint8(intrgb.EffectID), 0); err != nil {
|
|
|
return err
|
|
|
}
|
|
|
@@ -183,7 +222,7 @@ func disableLightingOnZones(proto zoneProtocol, zones []intrgb.Zone) error {
|
|
|
}
|
|
|
|
|
|
func enableLightingOnZones(proto zoneProtocol, zones []intrgb.Zone) error {
|
|
|
- return forEachSelectedZone(zones, func(zone intrgb.Zone, channel via.LEDType) error {
|
|
|
+ return forEachSelectedZone(zones, func(zone intrgb.Zone, channel via.Channel) error {
|
|
|
if err := proto.SetValue(channel, uint8(intrgb.EffectID), intrgb.DefaultEffect(zone)); err != nil {
|
|
|
return err
|
|
|
}
|