diff --git a/internal/mappingrules/init_rule_targets.go b/internal/mappingrules/init_rule_targets.go deleted file mode 100644 index 2e26276..0000000 --- a/internal/mappingrules/init_rule_targets.go +++ /dev/null @@ -1,156 +0,0 @@ -package mappingrules - -import ( - "errors" - "fmt" - "slices" - - "git.annabunches.net/annabunches/joyful/internal/configparser" - "git.annabunches.net/annabunches/joyful/internal/eventcodes" - "github.com/holoplot/go-evdev" -) - -func makeRuleTargetButton(targetConfig configparser.RuleTargetConfigButton, devs map[string]Device) (*RuleTargetButton, error) { - device, ok := devs[targetConfig.Device] - if !ok { - return nil, fmt.Errorf("non-existent device '%s'", targetConfig.Device) - } - - eventCode, err := eventcodes.ParseCodeButton(targetConfig.Button) - if err != nil { - return nil, err - } - - return NewRuleTargetButton( - targetConfig.Device, - device, - eventCode, - targetConfig.Inverted, - ) -} - -func makeRuleTargetAxis(targetConfig configparser.RuleTargetConfigAxis, devs map[string]Device) (*RuleTargetAxis, error) { - device, ok := devs[targetConfig.Device] - if !ok { - return nil, fmt.Errorf("non-existent device '%s'", targetConfig.Device) - } - - if targetConfig.DeadzoneEnd < targetConfig.DeadzoneStart { - return nil, errors.New("deadzone_end must be greater than deadzone_start") - } - - eventCode, err := eventcodes.ParseCode(targetConfig.Axis, eventcodes.CodePrefixAxis) - if err != nil { - return nil, err - } - - deadzoneStart, deadzoneEnd, err := calculateDeadzones(targetConfig, device, eventCode) - if err != nil { - return nil, err - } - - return NewRuleTargetAxis( - targetConfig.Device, - device, - eventCode, - targetConfig.Inverted, - deadzoneStart, - deadzoneEnd, - ) -} - -func makeRuleTargetRelaxis(targetConfig configparser.RuleTargetConfigRelaxis, devs map[string]Device) (*RuleTargetRelaxis, error) { - device, ok := devs[targetConfig.Device] - if !ok { - return nil, fmt.Errorf("non-existent device '%s'", targetConfig.Device) - } - - eventCode, err := eventcodes.ParseCode(targetConfig.Axis, eventcodes.CodePrefixRelaxis) - if err != nil { - return nil, err - } - - return NewRuleTargetRelaxis( - targetConfig.Device, - device, - eventCode, - ) -} - -func makeRuleTargetModeSelect(targetConfig configparser.RuleTargetConfigModeSelect, allModes []string) (*RuleTargetModeSelect, error) { - if ok := validateModes(targetConfig.Modes, allModes); !ok { - return nil, errors.New("undefined mode in mode select list") - } - - return NewRuleTargetModeSelect(targetConfig.Modes) -} - -// calculateDeadzones produces the deadzone start and end values in absolute terms -func calculateDeadzones(targetConfig configparser.RuleTargetConfigAxis, device Device, axis evdev.EvCode) (int32, int32, error) { - - var deadzoneStart, deadzoneEnd int32 - deadzoneStart = 0 - deadzoneEnd = 0 - - if targetConfig.DeadzoneStart != 0 || targetConfig.DeadzoneEnd != 0 { - return targetConfig.DeadzoneStart, targetConfig.DeadzoneEnd, nil - } - - var min, max int32 - absInfoMap, err := device.AbsInfos() - - if err != nil { - min = AxisValueMin - max = AxisValueMax - } else { - absInfo := absInfoMap[axis] - min = absInfo.Minimum - max = absInfo.Maximum - } - - if targetConfig.DeadzoneCenter < min || targetConfig.DeadzoneCenter > max { - return 0, 0, fmt.Errorf("deadzone_center '%d' is out of bounds", targetConfig.DeadzoneCenter) - } - - switch { - case targetConfig.DeadzoneSize != 0: - deadzoneStart = targetConfig.DeadzoneCenter - targetConfig.DeadzoneSize/2 - deadzoneEnd = targetConfig.DeadzoneCenter + targetConfig.DeadzoneSize/2 - case targetConfig.DeadzoneSizePercent != 0: - deadzoneSize := (max - min) / targetConfig.DeadzoneSizePercent - deadzoneStart = targetConfig.DeadzoneCenter - deadzoneSize/2 - deadzoneEnd = targetConfig.DeadzoneCenter + deadzoneSize/2 - } - - deadzoneStart, deadzoneEnd = clampAndShift(deadzoneStart, deadzoneEnd, min, max) - return deadzoneStart, deadzoneEnd, nil -} - -func clampAndShift(start, end, min, max int32) (int32, int32) { - if start < min { - end += min - start - start = min - } - if end > max { - start -= end - max - end = max - } - - return start, end -} - -// validateModes checks the provided modes against a larger subset of modes (usually all defined ones) -// and returns false if any of the modes are not defined. -func validateModes(modes []string, allModes []string) bool { - if len(modes) == 0 { - return true - } - - for _, mode := range modes { - if !slices.Contains(allModes, mode) { - return false - } - } - - return true -} diff --git a/internal/mappingrules/init_rule_targets_test.go b/internal/mappingrules/init_rule_targets_test.go index 2aa85b4..4554508 100644 --- a/internal/mappingrules/init_rule_targets_test.go +++ b/internal/mappingrules/init_rule_targets_test.go @@ -53,41 +53,41 @@ func (t *MakeRuleTargetsTests) TestMakeRuleTargetButton() { t.Run("Standard keycode", func() { config.Button = "BTN_TRIGGER" - rule, err := makeRuleTargetButton(config, t.devs) + rule, err := NewRuleTargetButtonFromConfig(config, t.devs) t.Nil(err) t.EqualValues(evdev.BTN_TRIGGER, rule.Button) }) t.Run("Hex code", func() { config.Button = "0x2fd" - rule, err := makeRuleTargetButton(config, t.devs) + rule, err := NewRuleTargetButtonFromConfig(config, t.devs) t.Nil(err) t.EqualValues(evdev.EvCode(0x2fd), rule.Button) }) t.Run("Index", func() { config.Button = "3" - rule, err := makeRuleTargetButton(config, t.devs) + rule, err := NewRuleTargetButtonFromConfig(config, t.devs) t.Nil(err) t.EqualValues(evdev.BTN_TOP, rule.Button) }) t.Run("Index too high", func() { config.Button = "74" - _, err := makeRuleTargetButton(config, t.devs) + _, err := NewRuleTargetButtonFromConfig(config, t.devs) t.NotNil(err) }) t.Run("Un-prefixed keycode", func() { config.Button = "pinkie" - rule, err := makeRuleTargetButton(config, t.devs) + rule, err := NewRuleTargetButtonFromConfig(config, t.devs) t.Nil(err) t.EqualValues(evdev.BTN_PINKIE, rule.Button) }) t.Run("Invalid keycode", func() { config.Button = "foo" - _, err := makeRuleTargetButton(config, t.devs) + _, err := NewRuleTargetButtonFromConfig(config, t.devs) t.NotNil(err) }) } @@ -106,7 +106,7 @@ func (t *MakeRuleTargetsTests) TestMakeRuleTargetAxis() { t.Run(fmt.Sprintf("KeyCode %s", tc.input), func() { config := configparser.RuleTargetConfigAxis{Device: "test"} config.Axis = tc.input - rule, err := makeRuleTargetAxis(config, t.devs) + rule, err := NewRuleTargetAxisFromConfig(config, t.devs) t.Nil(err) t.EqualValues(tc.output, rule.Axis) @@ -116,7 +116,7 @@ func (t *MakeRuleTargetsTests) TestMakeRuleTargetAxis() { t.Run("Invalid code", func() { config := configparser.RuleTargetConfigAxis{Device: "test"} config.Axis = "foo" - _, err := makeRuleTargetAxis(config, t.devs) + _, err := NewRuleTargetAxisFromConfig(config, t.devs) t.NotNil(err) }) @@ -125,7 +125,7 @@ func (t *MakeRuleTargetsTests) TestMakeRuleTargetAxis() { config.Axis = "x" config.DeadzoneEnd = 100 config.DeadzoneStart = 1000 - _, err := makeRuleTargetAxis(config, t.devs) + _, err := NewRuleTargetAxisFromConfig(config, t.devs) t.NotNil(err) }) @@ -148,7 +148,7 @@ func (t *MakeRuleTargetsTests) TestMakeRuleTargetAxis() { DeadzoneCenter: tc.inCenter, DeadzoneSize: tc.inSize, } - rule, err := makeRuleTargetAxis(config, t.devs) + rule, err := NewRuleTargetAxisFromConfig(config, t.devs) t.Nil(err) t.Equal(tc.outStart, rule.DeadzoneStart) @@ -163,7 +163,7 @@ func (t *MakeRuleTargetsTests) TestMakeRuleTargetAxis() { DeadzoneCenter: 20000, DeadzoneSize: 500, } - _, err := makeRuleTargetAxis(config, t.devs) + _, err := NewRuleTargetAxisFromConfig(config, t.devs) t.NotNil(err) }) @@ -186,7 +186,7 @@ func (t *MakeRuleTargetsTests) TestMakeRuleTargetAxis() { DeadzoneCenter: tc.inCenter, DeadzoneSizePercent: tc.inSizePercent, } - rule, err := makeRuleTargetAxis(config, t.devs) + rule, err := NewRuleTargetAxisFromConfig(config, t.devs) t.Nil(err) t.Equal(tc.outStart, rule.DeadzoneStart) @@ -201,7 +201,7 @@ func (t *MakeRuleTargetsTests) TestMakeRuleTargetAxis() { DeadzoneCenter: 20000, DeadzoneSizePercent: 10, } - _, err := makeRuleTargetAxis(config, t.devs) + _, err := NewRuleTargetAxisFromConfig(config, t.devs) t.NotNil(err) }) } @@ -211,34 +211,34 @@ func (t *MakeRuleTargetsTests) TestMakeRuleTargetRelaxis() { t.Run("Standard keycode", func() { config.Axis = "REL_WHEEL" - rule, err := makeRuleTargetRelaxis(config, t.devs) + rule, err := NewRuleTargetRelaxisFromConfig(config, t.devs) t.Nil(err) t.EqualValues(evdev.REL_WHEEL, rule.Axis) }) t.Run("Hex keycode", func() { config.Axis = "0x00" - rule, err := makeRuleTargetRelaxis(config, t.devs) + rule, err := NewRuleTargetRelaxisFromConfig(config, t.devs) t.Nil(err) t.EqualValues(evdev.REL_X, rule.Axis) }) t.Run("Un-prefixed keycode", func() { config.Axis = "wheel" - rule, err := makeRuleTargetRelaxis(config, t.devs) + rule, err := NewRuleTargetRelaxisFromConfig(config, t.devs) t.Nil(err) t.EqualValues(evdev.REL_WHEEL, rule.Axis) }) t.Run("Invalid keycode", func() { config.Axis = "foo" - _, err := makeRuleTargetRelaxis(config, t.devs) + _, err := NewRuleTargetRelaxisFromConfig(config, t.devs) t.NotNil(err) }) t.Run("Incorrect axis type", func() { config.Axis = "ABS_X" - _, err := makeRuleTargetRelaxis(config, t.devs) + _, err := NewRuleTargetRelaxisFromConfig(config, t.devs) t.NotNil(err) }) } diff --git a/internal/mappingrules/init_rules.go b/internal/mappingrules/init_rules.go index 189e335..7ea0ea4 100644 --- a/internal/mappingrules/init_rules.go +++ b/internal/mappingrules/init_rules.go @@ -3,6 +3,7 @@ package mappingrules import ( "errors" "fmt" + "slices" "strings" "git.annabunches.net/annabunches/joyful/internal/configparser" @@ -60,3 +61,19 @@ func NewRule(config configparser.RuleConfig, pDevs map[string]Device, vDevs map[ return newRule, nil } + +// validateModes checks the provided modes against a larger subset of modes (usually all defined ones) +// and returns false if any of the modes are not defined. +func validateModes(modes []string, allModes []string) bool { + if len(modes) == 0 { + return true + } + + for _, mode := range modes { + if !slices.Contains(allModes, mode) { + return false + } + } + + return true +} diff --git a/internal/mappingrules/mapping_rule_axis.go b/internal/mappingrules/mapping_rule_axis.go index fb2d95c..a4d1ed1 100644 --- a/internal/mappingrules/mapping_rule_axis.go +++ b/internal/mappingrules/mapping_rule_axis.go @@ -17,12 +17,12 @@ func NewMappingRuleAxis(ruleConfig configparser.RuleConfigAxis, vDevs map[string]Device, base MappingRuleBase) (*MappingRuleAxis, error) { - input, err := makeRuleTargetAxis(ruleConfig.Input, pDevs) + input, err := NewRuleTargetAxisFromConfig(ruleConfig.Input, pDevs) if err != nil { return nil, err } - output, err := makeRuleTargetAxis(ruleConfig.Output, vDevs) + output, err := NewRuleTargetAxisFromConfig(ruleConfig.Output, vDevs) if err != nil { return nil, err } diff --git a/internal/mappingrules/mapping_rule_axis_combined.go b/internal/mappingrules/mapping_rule_axis_combined.go index 9ff0ccc..62ce542 100644 --- a/internal/mappingrules/mapping_rule_axis_combined.go +++ b/internal/mappingrules/mapping_rule_axis_combined.go @@ -18,17 +18,17 @@ func NewMappingRuleAxisCombined(ruleConfig configparser.RuleConfigAxisCombined, vDevs map[string]Device, base MappingRuleBase) (*MappingRuleAxisCombined, error) { - inputLower, err := makeRuleTargetAxis(ruleConfig.InputLower, pDevs) + inputLower, err := NewRuleTargetAxisFromConfig(ruleConfig.InputLower, pDevs) if err != nil { return nil, err } - inputUpper, err := makeRuleTargetAxis(ruleConfig.InputUpper, pDevs) + inputUpper, err := NewRuleTargetAxisFromConfig(ruleConfig.InputUpper, pDevs) if err != nil { return nil, err } - output, err := makeRuleTargetAxis(ruleConfig.Output, vDevs) + output, err := NewRuleTargetAxisFromConfig(ruleConfig.Output, vDevs) if err != nil { return nil, err } diff --git a/internal/mappingrules/mapping_rule_axis_combined_test.go b/internal/mappingrules/mapping_rule_axis_combined_test.go index 7914a50..c514ed7 100644 --- a/internal/mappingrules/mapping_rule_axis_combined_test.go +++ b/internal/mappingrules/mapping_rule_axis_combined_test.go @@ -59,6 +59,7 @@ func (t *MappingRuleAxisCombinedTests) TearDownSubTest() { t.inputDevice.Reset() } +// TODO: this test sucks func (t *MappingRuleAxisCombinedTests) TestNewMappingRuleAxisCombined() { t.inputDevice.Stub("AbsInfos").Return(map[evdev.EvCode]evdev.AbsInfo{ evdev.ABS_X: {Minimum: 0, Maximum: 10000}, diff --git a/internal/mappingrules/mapping_rule_axis_to_button.go b/internal/mappingrules/mapping_rule_axis_to_button.go index 72ab081..82862ee 100644 --- a/internal/mappingrules/mapping_rule_axis_to_button.go +++ b/internal/mappingrules/mapping_rule_axis_to_button.go @@ -29,12 +29,12 @@ func NewMappingRuleAxisToButton(ruleConfig configparser.RuleConfigAxisToButton, vDevs map[string]Device, base MappingRuleBase) (*MappingRuleAxisToButton, error) { - input, err := makeRuleTargetAxis(ruleConfig.Input, pDevs) + input, err := NewRuleTargetAxisFromConfig(ruleConfig.Input, pDevs) if err != nil { return nil, err } - output, err := makeRuleTargetButton(ruleConfig.Output, vDevs) + output, err := NewRuleTargetButtonFromConfig(ruleConfig.Output, vDevs) if err != nil { return nil, err } diff --git a/internal/mappingrules/mapping_rule_axis_to_relaxis.go b/internal/mappingrules/mapping_rule_axis_to_relaxis.go index e07afd9..a6b418e 100644 --- a/internal/mappingrules/mapping_rule_axis_to_relaxis.go +++ b/internal/mappingrules/mapping_rule_axis_to_relaxis.go @@ -29,12 +29,12 @@ func NewMappingRuleAxisToRelaxis(ruleConfig configparser.RuleConfigAxisToRelaxis vDevs map[string]Device, base MappingRuleBase) (*MappingRuleAxisToRelaxis, error) { - input, err := makeRuleTargetAxis(ruleConfig.Input, pDevs) + input, err := NewRuleTargetAxisFromConfig(ruleConfig.Input, pDevs) if err != nil { return nil, err } - output, err := makeRuleTargetRelaxis(ruleConfig.Output, vDevs) + output, err := NewRuleTargetRelaxisFromConfig(ruleConfig.Output, vDevs) if err != nil { return nil, err } diff --git a/internal/mappingrules/mapping_rule_button.go b/internal/mappingrules/mapping_rule_button.go index 4781191..3b7befa 100644 --- a/internal/mappingrules/mapping_rule_button.go +++ b/internal/mappingrules/mapping_rule_button.go @@ -17,12 +17,12 @@ func NewMappingRuleButton(ruleConfig configparser.RuleConfigButton, vDevs map[string]Device, base MappingRuleBase) (*MappingRuleButton, error) { - input, err := makeRuleTargetButton(ruleConfig.Input, pDevs) + input, err := NewRuleTargetButtonFromConfig(ruleConfig.Input, pDevs) if err != nil { return nil, err } - output, err := makeRuleTargetButton(ruleConfig.Output, vDevs) + output, err := NewRuleTargetButtonFromConfig(ruleConfig.Output, vDevs) if err != nil { return nil, err } diff --git a/internal/mappingrules/mapping_rule_button_combo.go b/internal/mappingrules/mapping_rule_button_combo.go index 62c7fe4..12c8ef3 100644 --- a/internal/mappingrules/mapping_rule_button_combo.go +++ b/internal/mappingrules/mapping_rule_button_combo.go @@ -20,14 +20,14 @@ func NewMappingRuleButtonCombo(ruleConfig configparser.RuleConfigButtonCombo, inputs := make([]*RuleTargetButton, 0) for _, inputConfig := range ruleConfig.Inputs { - input, err := makeRuleTargetButton(inputConfig, pDevs) + input, err := NewRuleTargetButtonFromConfig(inputConfig, pDevs) if err != nil { return nil, err } inputs = append(inputs, input) } - output, err := makeRuleTargetButton(ruleConfig.Output, vDevs) + output, err := NewRuleTargetButtonFromConfig(ruleConfig.Output, vDevs) if err != nil { return nil, err } diff --git a/internal/mappingrules/mapping_rule_button_latched.go b/internal/mappingrules/mapping_rule_button_latched.go index aeabef4..4536ca9 100644 --- a/internal/mappingrules/mapping_rule_button_latched.go +++ b/internal/mappingrules/mapping_rule_button_latched.go @@ -17,12 +17,12 @@ func NewMappingRuleButtonLatched(ruleConfig configparser.RuleConfigButtonLatched vDevs map[string]Device, base MappingRuleBase) (*MappingRuleButtonLatched, error) { - input, err := makeRuleTargetButton(ruleConfig.Input, pDevs) + input, err := NewRuleTargetButtonFromConfig(ruleConfig.Input, pDevs) if err != nil { return nil, err } - output, err := makeRuleTargetButton(ruleConfig.Output, vDevs) + output, err := NewRuleTargetButtonFromConfig(ruleConfig.Output, vDevs) if err != nil { return nil, err } diff --git a/internal/mappingrules/mapping_rule_mode_select.go b/internal/mappingrules/mapping_rule_mode_select.go index 2ed793f..23a0757 100644 --- a/internal/mappingrules/mapping_rule_mode_select.go +++ b/internal/mappingrules/mapping_rule_mode_select.go @@ -16,12 +16,12 @@ func NewMappingRuleModeSelect(ruleConfig configparser.RuleConfigModeSelect, modes []string, base MappingRuleBase) (*MappingRuleModeSelect, error) { - input, err := makeRuleTargetButton(ruleConfig.Input, pDevs) + input, err := NewRuleTargetButtonFromConfig(ruleConfig.Input, pDevs) if err != nil { return nil, err } - output, err := makeRuleTargetModeSelect(ruleConfig.Output, modes) + output, err := NewRuleTargetModeSelectFromConfig(ruleConfig.Output, modes) if err != nil { return nil, err } diff --git a/internal/mappingrules/math.go b/internal/mappingrules/math.go index 37de4a2..6d036df 100644 --- a/internal/mappingrules/math.go +++ b/internal/mappingrules/math.go @@ -28,3 +28,16 @@ func Clamp[T Numeric](value, min, max T) T { } return value } + +func clampAndShift(start, end, min, max int32) (int32, int32) { + if start < min { + end += min - start + start = min + } + if end > max { + start -= end - max + end = max + } + + return start, end +} diff --git a/internal/mappingrules/rule_target_axis.go b/internal/mappingrules/rule_target_axis.go index fece9b8..1d92d37 100644 --- a/internal/mappingrules/rule_target_axis.go +++ b/internal/mappingrules/rule_target_axis.go @@ -4,6 +4,8 @@ import ( "errors" "fmt" + "git.annabunches.net/annabunches/joyful/internal/configparser" + "git.annabunches.net/annabunches/joyful/internal/eventcodes" "github.com/holoplot/go-evdev" ) @@ -20,6 +22,77 @@ type RuleTargetAxis struct { deadzoneSize int32 } +func NewRuleTargetAxisFromConfig(targetConfig configparser.RuleTargetConfigAxis, devs map[string]Device) (*RuleTargetAxis, error) { + device, ok := devs[targetConfig.Device] + if !ok { + return nil, fmt.Errorf("non-existent device '%s'", targetConfig.Device) + } + + if targetConfig.DeadzoneEnd < targetConfig.DeadzoneStart { + return nil, errors.New("deadzone_end must be greater than deadzone_start") + } + + eventCode, err := eventcodes.ParseCode(targetConfig.Axis, eventcodes.CodePrefixAxis) + if err != nil { + return nil, err + } + + deadzoneStart, deadzoneEnd, err := calculateDeadzones(targetConfig, device, eventCode) + if err != nil { + return nil, err + } + + return NewRuleTargetAxis( + targetConfig.Device, + device, + eventCode, + targetConfig.Inverted, + deadzoneStart, + deadzoneEnd, + ) +} + +// calculateDeadzones produces the deadzone start and end values in absolute terms +func calculateDeadzones(targetConfig configparser.RuleTargetConfigAxis, device Device, axis evdev.EvCode) (int32, int32, error) { + + var deadzoneStart, deadzoneEnd int32 + deadzoneStart = 0 + deadzoneEnd = 0 + + if targetConfig.DeadzoneStart != 0 || targetConfig.DeadzoneEnd != 0 { + return targetConfig.DeadzoneStart, targetConfig.DeadzoneEnd, nil + } + + var min, max int32 + absInfoMap, err := device.AbsInfos() + + if err != nil { + min = AxisValueMin + max = AxisValueMax + } else { + absInfo := absInfoMap[axis] + min = absInfo.Minimum + max = absInfo.Maximum + } + + if targetConfig.DeadzoneCenter < min || targetConfig.DeadzoneCenter > max { + return 0, 0, fmt.Errorf("deadzone_center '%d' is out of bounds", targetConfig.DeadzoneCenter) + } + + switch { + case targetConfig.DeadzoneSize != 0: + deadzoneStart = targetConfig.DeadzoneCenter - targetConfig.DeadzoneSize/2 + deadzoneEnd = targetConfig.DeadzoneCenter + targetConfig.DeadzoneSize/2 + case targetConfig.DeadzoneSizePercent != 0: + deadzoneSize := (max - min) / targetConfig.DeadzoneSizePercent + deadzoneStart = targetConfig.DeadzoneCenter - deadzoneSize/2 + deadzoneEnd = targetConfig.DeadzoneCenter + deadzoneSize/2 + } + + deadzoneStart, deadzoneEnd = clampAndShift(deadzoneStart, deadzoneEnd, min, max) + return deadzoneStart, deadzoneEnd, nil +} + func NewRuleTargetAxis(device_name string, device Device, axis evdev.EvCode, diff --git a/internal/mappingrules/rule_target_button.go b/internal/mappingrules/rule_target_button.go index 68fd252..316e7c5 100644 --- a/internal/mappingrules/rule_target_button.go +++ b/internal/mappingrules/rule_target_button.go @@ -1,6 +1,12 @@ package mappingrules -import "github.com/holoplot/go-evdev" +import ( + "fmt" + + "git.annabunches.net/annabunches/joyful/internal/configparser" + "git.annabunches.net/annabunches/joyful/internal/eventcodes" + "github.com/holoplot/go-evdev" +) type RuleTargetButton struct { DeviceName string @@ -9,6 +15,25 @@ type RuleTargetButton struct { Inverted bool } +func NewRuleTargetButtonFromConfig(targetConfig configparser.RuleTargetConfigButton, devs map[string]Device) (*RuleTargetButton, error) { + device, ok := devs[targetConfig.Device] + if !ok { + return nil, fmt.Errorf("non-existent device '%s'", targetConfig.Device) + } + + eventCode, err := eventcodes.ParseCodeButton(targetConfig.Button) + if err != nil { + return nil, err + } + + return NewRuleTargetButton( + targetConfig.Device, + device, + eventCode, + targetConfig.Inverted, + ) +} + func NewRuleTargetButton(device_name string, device Device, code evdev.EvCode, inverted bool) (*RuleTargetButton, error) { return &RuleTargetButton{ DeviceName: device_name, diff --git a/internal/mappingrules/rule_target_modeselect.go b/internal/mappingrules/rule_target_modeselect.go index 55c8f46..0235700 100644 --- a/internal/mappingrules/rule_target_modeselect.go +++ b/internal/mappingrules/rule_target_modeselect.go @@ -4,6 +4,7 @@ import ( "errors" "slices" + "git.annabunches.net/annabunches/joyful/internal/configparser" "git.annabunches.net/annabunches/joyful/internal/logger" "github.com/holoplot/go-evdev" ) @@ -12,6 +13,14 @@ type RuleTargetModeSelect struct { Modes []string } +func NewRuleTargetModeSelectFromConfig(targetConfig configparser.RuleTargetConfigModeSelect, allModes []string) (*RuleTargetModeSelect, error) { + if ok := validateModes(targetConfig.Modes, allModes); !ok { + return nil, errors.New("undefined mode in mode select list") + } + + return NewRuleTargetModeSelect(targetConfig.Modes) +} + func NewRuleTargetModeSelect(modes []string) (*RuleTargetModeSelect, error) { if len(modes) == 0 { return nil, errors.New("cannot create RuleTargetModeSelect: mode list is empty") diff --git a/internal/mappingrules/rule_target_relaxis.go b/internal/mappingrules/rule_target_relaxis.go index 1942c4b..6b79812 100644 --- a/internal/mappingrules/rule_target_relaxis.go +++ b/internal/mappingrules/rule_target_relaxis.go @@ -1,6 +1,10 @@ package mappingrules import ( + "fmt" + + "git.annabunches.net/annabunches/joyful/internal/configparser" + "git.annabunches.net/annabunches/joyful/internal/eventcodes" "github.com/holoplot/go-evdev" ) @@ -10,12 +14,30 @@ type RuleTargetRelaxis struct { Axis evdev.EvCode } -func NewRuleTargetRelaxis(device_name string, +func NewRuleTargetRelaxisFromConfig(targetConfig configparser.RuleTargetConfigRelaxis, devs map[string]Device) (*RuleTargetRelaxis, error) { + device, ok := devs[targetConfig.Device] + if !ok { + return nil, fmt.Errorf("non-existent device '%s'", targetConfig.Device) + } + + eventCode, err := eventcodes.ParseCode(targetConfig.Axis, eventcodes.CodePrefixRelaxis) + if err != nil { + return nil, err + } + + return NewRuleTargetRelaxis( + targetConfig.Device, + device, + eventCode, + ) +} + +func NewRuleTargetRelaxis(deviceName string, device Device, axis evdev.EvCode) (*RuleTargetRelaxis, error) { return &RuleTargetRelaxis{ - DeviceName: device_name, + DeviceName: deviceName, Device: device, Axis: axis, }, nil