From db848db810e55b8a3d71192f91901a96d1f4d1fd Mon Sep 17 00:00:00 2001 From: Anna Rose Wiggins Date: Fri, 4 Jul 2025 12:34:39 -0400 Subject: [PATCH] Fix up refactored rule targets. --- internal/config/rules.go | 40 +++++++++++++++++++++---------- internal/config/schema.go | 2 ++ internal/mappingrules/matching.go | 26 ++++++++++---------- internal/mappingrules/targets.go | 38 +++++++++++++++++++---------- internal/mappingrules/types.go | 3 +++ 5 files changed, 71 insertions(+), 38 deletions(-) diff --git a/internal/config/rules.go b/internal/config/rules.go index 6822ea7..caab802 100644 --- a/internal/config/rules.go +++ b/internal/config/rules.go @@ -107,29 +107,45 @@ func makeLatchedRule(ruleConfig RuleConfig, pDevs map[string]*evdev.InputDevice, // makeInputRuleTarget takes an Input declaration from the YAML and returns a fully formed RuleTarget. func makeRuleTarget(targetConfig RuleTargetConfig, devs map[string]*evdev.InputDevice) (mappingrules.RuleTarget, error) { - ruleTarget := mappingrules.RuleTarget{} - if len(targetConfig.ModeSelect) > 0 { - ruleTarget.ModeSelect = targetConfig.ModeSelect - return ruleTarget, nil + return &mappingrules.RuleTargetModeSelect{ + ModeSelect: targetConfig.ModeSelect, + }, nil } device, ok := devs[targetConfig.Device] if !ok { - return mappingrules.RuleTarget{}, fmt.Errorf("couldn't build rule due to non-existent device '%s'", targetConfig.Device) + return nil, fmt.Errorf("couldn't build rule due to non-existent device '%s'", targetConfig.Device) } - ruleTarget.Device = device eventType, eventCode, err := decodeRuleTargetValues(targetConfig) if err != nil { - return ruleTarget, err + return nil, err } - ruleTarget.Type = eventType - ruleTarget.Code = eventCode - ruleTarget.Inverted = targetConfig.Inverted - ruleTarget.DeviceName = targetConfig.Device - return ruleTarget, nil + baseParams := mappingrules.RuleTargetBase{ + DeviceName: targetConfig.Device, + Device: device, + Inverted: targetConfig.Inverted, + Code: eventCode, + } + + switch eventType { + case evdev.EV_KEY: + return &mappingrules.RuleTargetButton{ + RuleTargetBase: baseParams, + }, nil + + case evdev.EV_ABS: + return &mappingrules.RuleTargetAxis{ + RuleTargetBase: baseParams, + AxisStart: targetConfig.AxisStart, + AxisEnd: targetConfig.AxisEnd, + }, nil + + default: + return nil, fmt.Errorf("skipping rule due to unsupported event type '%d'", eventType) + } } // decodeRuleTargetValues returns the appropriate evdev.EvType and evdev.EvCode values diff --git a/internal/config/schema.go b/internal/config/schema.go index 787bafe..2ea4c97 100644 --- a/internal/config/schema.go +++ b/internal/config/schema.go @@ -31,6 +31,8 @@ type RuleTargetConfig struct { Device string `yaml:"device,omitempty"` Button string `yaml:"button,omitempty"` Axis string `yaml:"axis,omitempty"` + AxisStart int32 `yaml:"axis_start,omitempty"` + AxisEnd int32 `yaml:"axis_end,omitempty"` Inverted bool `yaml:"inverted,omitempty"` ModeSelect []string `yaml:"mode_select,omitempty"` } diff --git a/internal/mappingrules/matching.go b/internal/mappingrules/matching.go index ae849f1..7bbad7c 100644 --- a/internal/mappingrules/matching.go +++ b/internal/mappingrules/matching.go @@ -7,7 +7,7 @@ import ( ) func (rule *MappingRuleBase) OutputName() string { - return rule.Output.DeviceName + return rule.Output.GetDeviceName() } func (rule *MappingRuleBase) modeCheck(mode *string) bool { @@ -22,12 +22,12 @@ func (rule *SimpleMappingRule) MatchEvent(device *evdev.InputDevice, event *evde return nil } - if device != rule.Input.Device || - event.Code != rule.Input.Code { + if device != rule.Input.GetDevice() || + event.Code != rule.Input.GetCode() { return nil } - return eventFromTarget(rule.Output, valueFromTarget(rule.Input, event), mode) + return rule.Output.CreateEvent(rule.Input.NormalizeValue(event.Value), mode) } func (rule *ComboMappingRule) MatchEvent(device *evdev.InputDevice, event *evdev.InputEvent, mode *string) *evdev.InputEvent { @@ -36,11 +36,11 @@ func (rule *ComboMappingRule) MatchEvent(device *evdev.InputDevice, event *evdev } // Check each of the inputs, and if we find a match, proceed - var match *RuleTarget + var match RuleTarget for _, input := range rule.Inputs { - if device == input.Device && - event.Code == input.Code { - match = &input + if device == input.GetDevice() && + event.Code == input.GetCode() { + match = input } } @@ -49,7 +49,7 @@ func (rule *ComboMappingRule) MatchEvent(device *evdev.InputDevice, event *evdev } // Get the value and add/subtract it from State - inputValue := valueFromTarget(*match, event) + inputValue := match.NormalizeValue(event.Value) oldState := rule.State if inputValue == 0 { rule.State = max(rule.State-1, 0) @@ -60,10 +60,10 @@ func (rule *ComboMappingRule) MatchEvent(device *evdev.InputDevice, event *evdev targetState := len(rule.Inputs) if oldState == targetState-1 && rule.State == targetState { - return eventFromTarget(rule.Output, 1, mode) + return rule.Output.CreateEvent(1, mode) } if oldState == targetState && rule.State == targetState-1 { - return eventFromTarget(rule.Output, 0, mode) + return rule.Output.CreateEvent(0, mode) } return nil } @@ -73,8 +73,8 @@ func (rule *LatchedMappingRule) MatchEvent(device *evdev.InputDevice, event *evd return nil } - if device != rule.Input.Device || - event.Code != rule.Input.Code || + if device != rule.Input.GetDevice() || + event.Code != rule.Input.GetCode() || rule.Input.NormalizeValue(event.Value) == 0 { return nil } diff --git a/internal/mappingrules/targets.go b/internal/mappingrules/targets.go index e8036d3..81c6022 100644 --- a/internal/mappingrules/targets.go +++ b/internal/mappingrules/targets.go @@ -7,6 +7,18 @@ import ( "github.com/holoplot/go-evdev" ) +func (target *RuleTargetBase) GetCode() evdev.EvCode { + return target.Code +} + +func (target *RuleTargetBase) GetDeviceName() string { + return target.DeviceName +} + +func (target *RuleTargetBase) GetDevice() *evdev.InputDevice { + return target.Device +} + func (target *RuleTargetButton) NormalizeValue(value int32) int32 { if value == 0 { return 1 @@ -14,6 +26,14 @@ func (target *RuleTargetButton) NormalizeValue(value int32) int32 { return 0 } +func (target *RuleTargetButton) CreateEvent(value int32, mode *string) *evdev.InputEvent { + return &evdev.InputEvent{ + Type: evdev.EV_KEY, + Code: target.Code, + Value: value, + } +} + func (target *RuleTargetAxis) NormalizeValue(value int32) int32 { if !target.Inverted { return value @@ -37,19 +57,6 @@ func (target *RuleTargetAxis) NormalizeValue(value int32) int32 { return value } -// RuleTargetModeSelect doesn't make sense as an input type -func (target *RuleTargetModeSelect) NormalizeValue(value int32) int32 { - return -1 -} - -func (target *RuleTargetButton) CreateEvent(value int32, mode *string) *evdev.InputEvent { - return &evdev.InputEvent{ - Type: evdev.EV_KEY, - Code: target.Code, - Value: value, - } -} - func (target *RuleTargetAxis) CreateEvent(value int32, mode *string) *evdev.InputEvent { return &evdev.InputEvent{ Type: evdev.EV_ABS, @@ -58,6 +65,11 @@ func (target *RuleTargetAxis) CreateEvent(value int32, mode *string) *evdev.Inpu } } +// RuleTargetModeSelect doesn't make sense as an input type +func (target *RuleTargetModeSelect) NormalizeValue(value int32) int32 { + return -1 +} + func (target *RuleTargetModeSelect) CreateEvent(value int32, mode *string) *evdev.InputEvent { if value == 0 { return nil diff --git a/internal/mappingrules/types.go b/internal/mappingrules/types.go index a889689..d45b22a 100644 --- a/internal/mappingrules/types.go +++ b/internal/mappingrules/types.go @@ -47,6 +47,9 @@ type ProportionalAxisMappingRule struct { type RuleTarget interface { NormalizeValue(int32) int32 CreateEvent(int32, *string) *evdev.InputEvent + GetCode() evdev.EvCode + GetDeviceName() string + GetDevice() *evdev.InputDevice } type RuleTargetBase struct {