Add more deadzone specification options. (#9)
Reviewed-on: #9 Co-authored-by: Anna Rose Wiggins <annabunches@gmail.com> Co-committed-by: Anna Rose Wiggins <annabunches@gmail.com>
This commit is contained in:
parent
5b9dfe0967
commit
97a1acd228
20 changed files with 344 additions and 108 deletions
7
internal/config/interfaces.go
Normal file
7
internal/config/interfaces.go
Normal file
|
@ -0,0 +1,7 @@
|
|||
package config
|
||||
|
||||
import "github.com/holoplot/go-evdev"
|
||||
|
||||
type Device interface {
|
||||
AbsInfos() (map[evdev.EvCode]evdev.AbsInfo, error)
|
||||
}
|
|
@ -4,11 +4,12 @@ import (
|
|||
"errors"
|
||||
"fmt"
|
||||
|
||||
"git.annabunches.net/annabunches/joyful/internal/logger"
|
||||
"git.annabunches.net/annabunches/joyful/internal/mappingrules"
|
||||
"github.com/holoplot/go-evdev"
|
||||
)
|
||||
|
||||
func makeRuleTargetButton(targetConfig RuleTargetConfig, devs map[string]*evdev.InputDevice) (*mappingrules.RuleTargetButton, error) {
|
||||
func makeRuleTargetButton(targetConfig RuleTargetConfig, devs map[string]Device) (*mappingrules.RuleTargetButton, error) {
|
||||
device, ok := devs[targetConfig.Device]
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("non-existent device '%s'", targetConfig.Device)
|
||||
|
@ -27,7 +28,7 @@ func makeRuleTargetButton(targetConfig RuleTargetConfig, devs map[string]*evdev.
|
|||
)
|
||||
}
|
||||
|
||||
func makeRuleTargetAxis(targetConfig RuleTargetConfig, devs map[string]*evdev.InputDevice) (*mappingrules.RuleTargetAxis, error) {
|
||||
func makeRuleTargetAxis(targetConfig RuleTargetConfig, devs map[string]Device) (*mappingrules.RuleTargetAxis, error) {
|
||||
device, ok := devs[targetConfig.Device]
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("non-existent device '%s'", targetConfig.Device)
|
||||
|
@ -42,17 +43,22 @@ func makeRuleTargetAxis(targetConfig RuleTargetConfig, devs map[string]*evdev.In
|
|||
return nil, err
|
||||
}
|
||||
|
||||
deadzoneStart, deadzoneEnd, err := calculateDeadzones(targetConfig, device, eventCode)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return mappingrules.NewRuleTargetAxis(
|
||||
targetConfig.Device,
|
||||
device,
|
||||
eventCode,
|
||||
targetConfig.Inverted,
|
||||
targetConfig.DeadzoneStart,
|
||||
targetConfig.DeadzoneEnd,
|
||||
deadzoneStart,
|
||||
deadzoneEnd,
|
||||
)
|
||||
}
|
||||
|
||||
func makeRuleTargetRelaxis(targetConfig RuleTargetConfig, devs map[string]*evdev.InputDevice) (*mappingrules.RuleTargetRelaxis, error) {
|
||||
func makeRuleTargetRelaxis(targetConfig RuleTargetConfig, devs map[string]Device) (*mappingrules.RuleTargetRelaxis, error) {
|
||||
device, ok := devs[targetConfig.Device]
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("non-existent device '%s'", targetConfig.Device)
|
||||
|
@ -83,3 +89,61 @@ func makeRuleTargetModeSelect(targetConfig RuleTargetConfig, allModes []string)
|
|||
func hasError(_ any, err error) bool {
|
||||
return err != nil
|
||||
}
|
||||
|
||||
// calculateDeadzones produces the deadzone start and end values in absolute terms
|
||||
// TODO: on the one hand, this logic feels betten encapsulated in mappingrules. On the other hand,
|
||||
// passing even more parameters to NewRuleTargetAxis feels terrible
|
||||
func calculateDeadzones(targetConfig RuleTargetConfig, 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 = mappingrules.AxisValueMin
|
||||
max = mappingrules.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) {
|
||||
logger.Logf("DEBUG: %d %d %d %d", start, end, min, max)
|
||||
if start < min {
|
||||
end += min - start
|
||||
start = min
|
||||
logger.Logf("DEBUG: %d %d %d %d", start, end, min, max)
|
||||
}
|
||||
if end > max {
|
||||
start -= end - max
|
||||
end = max
|
||||
}
|
||||
|
||||
return start, end
|
||||
}
|
||||
|
|
|
@ -4,12 +4,24 @@ import (
|
|||
"testing"
|
||||
|
||||
"github.com/holoplot/go-evdev"
|
||||
"github.com/stretchr/testify/mock"
|
||||
"github.com/stretchr/testify/suite"
|
||||
)
|
||||
|
||||
type MakeRuleTargetsTests struct {
|
||||
suite.Suite
|
||||
devs map[string]*evdev.InputDevice
|
||||
devs map[string]Device
|
||||
deviceMock *DeviceMock
|
||||
config RuleTargetConfig
|
||||
}
|
||||
|
||||
type DeviceMock struct {
|
||||
mock.Mock
|
||||
}
|
||||
|
||||
func (m *DeviceMock) AbsInfos() (map[evdev.EvCode]evdev.AbsInfo, error) {
|
||||
args := m.Called()
|
||||
return args.Get(0).(map[evdev.EvCode]evdev.AbsInfo), args.Error(1)
|
||||
}
|
||||
|
||||
func TestRunnerMakeRuleTargets(t *testing.T) {
|
||||
|
@ -17,131 +29,216 @@ func TestRunnerMakeRuleTargets(t *testing.T) {
|
|||
}
|
||||
|
||||
func (t *MakeRuleTargetsTests) SetupSuite() {
|
||||
t.devs = map[string]*evdev.InputDevice{
|
||||
"test": {},
|
||||
t.deviceMock = new(DeviceMock)
|
||||
t.deviceMock.On("AbsInfos").Return(
|
||||
map[evdev.EvCode]evdev.AbsInfo{
|
||||
evdev.ABS_X: {
|
||||
Minimum: 0,
|
||||
Maximum: 10000,
|
||||
},
|
||||
evdev.ABS_Y: {
|
||||
Minimum: 0,
|
||||
Maximum: 10000,
|
||||
},
|
||||
}, nil,
|
||||
)
|
||||
t.devs = map[string]Device{
|
||||
"test": t.deviceMock,
|
||||
}
|
||||
}
|
||||
|
||||
func (t *MakeRuleTargetsTests) SetupSubTest() {
|
||||
t.config = RuleTargetConfig{
|
||||
Device: "test",
|
||||
}
|
||||
}
|
||||
|
||||
func (t *MakeRuleTargetsTests) TestMakeRuleTargetButton() {
|
||||
config := RuleTargetConfig{
|
||||
Device: "test",
|
||||
}
|
||||
t.Run("Standard keycode", func() {
|
||||
config.Button = "BTN_TRIGGER"
|
||||
rule, err := makeRuleTargetButton(config, t.devs)
|
||||
t.config.Button = "BTN_TRIGGER"
|
||||
rule, err := makeRuleTargetButton(t.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)
|
||||
t.config.Button = "0x2fd"
|
||||
rule, err := makeRuleTargetButton(t.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)
|
||||
t.config.Button = "3"
|
||||
rule, err := makeRuleTargetButton(t.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)
|
||||
t.config.Button = "74"
|
||||
_, err := makeRuleTargetButton(t.config, t.devs)
|
||||
t.NotNil(err)
|
||||
})
|
||||
|
||||
t.Run("Un-prefixed keycode", func() {
|
||||
config.Button = "pinkie"
|
||||
rule, err := makeRuleTargetButton(config, t.devs)
|
||||
t.config.Button = "pinkie"
|
||||
rule, err := makeRuleTargetButton(t.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)
|
||||
t.config.Button = "foo"
|
||||
_, err := makeRuleTargetButton(t.config, t.devs)
|
||||
t.NotNil(err)
|
||||
})
|
||||
}
|
||||
|
||||
func (t *MakeRuleTargetsTests) TestMakeRuleTargetAxis() {
|
||||
config := RuleTargetConfig{
|
||||
Device: "test",
|
||||
}
|
||||
|
||||
t.Run("Standard keycode", func() {
|
||||
config.Axis = "ABS_X"
|
||||
rule, err := makeRuleTargetAxis(config, t.devs)
|
||||
t.Run("Standard code", func() {
|
||||
t.config.Axis = "ABS_X"
|
||||
rule, err := makeRuleTargetAxis(t.config, t.devs)
|
||||
t.Nil(err)
|
||||
t.EqualValues(evdev.ABS_X, rule.Axis)
|
||||
})
|
||||
|
||||
t.Run("Hex keycode", func() {
|
||||
config.Axis = "0x01"
|
||||
rule, err := makeRuleTargetAxis(config, t.devs)
|
||||
t.Run("Hex code", func() {
|
||||
t.config.Axis = "0x01"
|
||||
rule, err := makeRuleTargetAxis(t.config, t.devs)
|
||||
t.Nil(err)
|
||||
t.EqualValues(evdev.ABS_Y, rule.Axis)
|
||||
})
|
||||
|
||||
t.Run("Un-prefixed keycode", func() {
|
||||
config.Axis = "x"
|
||||
rule, err := makeRuleTargetAxis(config, t.devs)
|
||||
t.Run("Un-prefixed code", func() {
|
||||
t.config.Axis = "x"
|
||||
rule, err := makeRuleTargetAxis(t.config, t.devs)
|
||||
t.Nil(err)
|
||||
t.EqualValues(evdev.ABS_X, rule.Axis)
|
||||
})
|
||||
|
||||
t.Run("Invalid keycode", func() {
|
||||
config.Axis = "foo"
|
||||
_, err := makeRuleTargetAxis(config, t.devs)
|
||||
t.Run("Invalid code", func() {
|
||||
t.config.Axis = "foo"
|
||||
_, err := makeRuleTargetAxis(t.config, t.devs)
|
||||
t.NotNil(err)
|
||||
})
|
||||
|
||||
t.Run("Invalid deadzone", func() {
|
||||
config.DeadzoneEnd = 100
|
||||
config.DeadzoneStart = 1000
|
||||
_, err := makeRuleTargetAxis(config, t.devs)
|
||||
t.config.Axis = "x"
|
||||
t.config.DeadzoneEnd = 100
|
||||
t.config.DeadzoneStart = 1000
|
||||
_, err := makeRuleTargetAxis(t.config, t.devs)
|
||||
t.NotNil(err)
|
||||
})
|
||||
|
||||
t.Run("Deadzone center/size", func() {
|
||||
t.config.Axis = "x"
|
||||
t.config.DeadzoneCenter = 5000
|
||||
t.config.DeadzoneSize = 1000
|
||||
rule, err := makeRuleTargetAxis(t.config, t.devs)
|
||||
t.Nil(err)
|
||||
t.EqualValues(4500, rule.DeadzoneStart)
|
||||
t.EqualValues(5500, rule.DeadzoneEnd)
|
||||
})
|
||||
|
||||
t.Run("Deadzone center/size lower boundary", func() {
|
||||
t.config.Axis = "x"
|
||||
t.config.DeadzoneCenter = 0
|
||||
t.config.DeadzoneSize = 500
|
||||
rule, err := makeRuleTargetAxis(t.config, t.devs)
|
||||
t.Nil(err)
|
||||
t.EqualValues(0, rule.DeadzoneStart)
|
||||
t.EqualValues(500, rule.DeadzoneEnd)
|
||||
})
|
||||
|
||||
t.Run("Deadzone center/size upper boundary", func() {
|
||||
t.config.Axis = "x"
|
||||
t.config.DeadzoneCenter = 10000
|
||||
t.config.DeadzoneSize = 500
|
||||
rule, err := makeRuleTargetAxis(t.config, t.devs)
|
||||
t.Nil(err)
|
||||
t.EqualValues(9500, rule.DeadzoneStart)
|
||||
t.EqualValues(10000, rule.DeadzoneEnd)
|
||||
})
|
||||
|
||||
t.Run("Deadzone center/size invalid center", func() {
|
||||
t.config.Axis = "x"
|
||||
t.config.DeadzoneCenter = 20000
|
||||
t.config.DeadzoneSize = 500
|
||||
_, err := makeRuleTargetAxis(t.config, t.devs)
|
||||
t.NotNil(err)
|
||||
})
|
||||
|
||||
t.Run("Deadzone center/percent", func() {
|
||||
t.config.Axis = "x"
|
||||
t.config.DeadzoneCenter = 5000
|
||||
t.config.DeadzoneSizePercent = 10
|
||||
rule, err := makeRuleTargetAxis(t.config, t.devs)
|
||||
t.Nil(err)
|
||||
t.EqualValues(4500, rule.DeadzoneStart)
|
||||
t.EqualValues(5500, rule.DeadzoneEnd)
|
||||
})
|
||||
|
||||
t.Run("Deadzone center/percent lower boundary", func() {
|
||||
t.config.Axis = "x"
|
||||
t.config.DeadzoneCenter = 0
|
||||
t.config.DeadzoneSizePercent = 10
|
||||
rule, err := makeRuleTargetAxis(t.config, t.devs)
|
||||
t.Nil(err)
|
||||
t.EqualValues(0, rule.DeadzoneStart)
|
||||
t.EqualValues(1000, rule.DeadzoneEnd)
|
||||
})
|
||||
|
||||
t.Run("Deadzone center/percent upper boundary", func() {
|
||||
t.config.Axis = "x"
|
||||
t.config.DeadzoneCenter = 10000
|
||||
t.config.DeadzoneSizePercent = 10
|
||||
rule, err := makeRuleTargetAxis(t.config, t.devs)
|
||||
t.Nil(err)
|
||||
t.EqualValues(9000, rule.DeadzoneStart)
|
||||
t.EqualValues(10000, rule.DeadzoneEnd)
|
||||
})
|
||||
|
||||
t.Run("Deadzone center/percent invalid center", func() {
|
||||
t.config.Axis = "x"
|
||||
t.config.DeadzoneCenter = 20000
|
||||
t.config.DeadzoneSizePercent = 10
|
||||
_, err := makeRuleTargetAxis(t.config, t.devs)
|
||||
t.NotNil(err)
|
||||
})
|
||||
}
|
||||
|
||||
func (t *MakeRuleTargetsTests) TestMakeRuleTargetRelaxis() {
|
||||
config := RuleTargetConfig{
|
||||
Device: "test",
|
||||
}
|
||||
|
||||
t.Run("Standard keycode", func() {
|
||||
config.Axis = "REL_WHEEL"
|
||||
rule, err := makeRuleTargetRelaxis(config, t.devs)
|
||||
t.config.Axis = "REL_WHEEL"
|
||||
rule, err := makeRuleTargetRelaxis(t.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)
|
||||
t.config.Axis = "0x00"
|
||||
rule, err := makeRuleTargetRelaxis(t.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)
|
||||
t.config.Axis = "wheel"
|
||||
rule, err := makeRuleTargetRelaxis(t.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)
|
||||
t.config.Axis = "foo"
|
||||
_, err := makeRuleTargetRelaxis(t.config, t.devs)
|
||||
t.NotNil(err)
|
||||
})
|
||||
|
||||
t.Run("Incorrect axis type", func() {
|
||||
config.Axis = "ABS_X"
|
||||
_, err := makeRuleTargetRelaxis(config, t.devs)
|
||||
t.config.Axis = "ABS_X"
|
||||
_, err := makeRuleTargetRelaxis(t.config, t.devs)
|
||||
t.NotNil(err)
|
||||
})
|
||||
}
|
||||
|
|
|
@ -10,14 +10,25 @@ import (
|
|||
)
|
||||
|
||||
// TODO: At some point it would *very likely* make sense to map each rule to all of the physical devices that can
|
||||
// trigger it, and return that instead. Something like a map[*evdev.InputDevice][]mappingrule.MappingRule.
|
||||
// trigger it, and return that instead. Something like a map[Device][]mappingrule.MappingRule.
|
||||
// This would speed up rule matching by only checking relevant rules for a given input event.
|
||||
// We could take this further and make it a map[<struct of *inputdevice, type, and code>][]rule
|
||||
// For very large rule-bases this may be helpful for staying performant.
|
||||
func (parser *ConfigParser) BuildRules(pDevs map[string]*evdev.InputDevice, vDevs map[string]*evdev.InputDevice) []mappingrules.MappingRule {
|
||||
func (parser *ConfigParser) BuildRules(pInputDevs map[string]*evdev.InputDevice, vInputDevs map[string]*evdev.InputDevice) []mappingrules.MappingRule {
|
||||
rules := make([]mappingrules.MappingRule, 0)
|
||||
modes := parser.GetModes()
|
||||
|
||||
// Golang can't inspect the concrete map type to determine interface conformance,
|
||||
// so we handle that here.
|
||||
pDevs := make(map[string]Device)
|
||||
for name, dev := range pInputDevs {
|
||||
pDevs[name] = dev
|
||||
}
|
||||
vDevs := make(map[string]Device)
|
||||
for name, dev := range vInputDevs {
|
||||
vDevs[name] = dev
|
||||
}
|
||||
|
||||
for _, ruleConfig := range parser.config.Rules {
|
||||
var newRule mappingrules.MappingRule
|
||||
var err error
|
||||
|
@ -60,8 +71,8 @@ func (parser *ConfigParser) BuildRules(pDevs map[string]*evdev.InputDevice, vDev
|
|||
}
|
||||
|
||||
func makeMappingRuleButton(ruleConfig RuleConfig,
|
||||
pDevs map[string]*evdev.InputDevice,
|
||||
vDevs map[string]*evdev.InputDevice,
|
||||
pDevs map[string]Device,
|
||||
vDevs map[string]Device,
|
||||
base mappingrules.MappingRuleBase) (*mappingrules.MappingRuleButton, error) {
|
||||
|
||||
input, err := makeRuleTargetButton(ruleConfig.Input, pDevs)
|
||||
|
@ -78,8 +89,8 @@ func makeMappingRuleButton(ruleConfig RuleConfig,
|
|||
}
|
||||
|
||||
func makeMappingRuleCombo(ruleConfig RuleConfig,
|
||||
pDevs map[string]*evdev.InputDevice,
|
||||
vDevs map[string]*evdev.InputDevice,
|
||||
pDevs map[string]Device,
|
||||
vDevs map[string]Device,
|
||||
base mappingrules.MappingRuleBase) (*mappingrules.MappingRuleButtonCombo, error) {
|
||||
|
||||
inputs := make([]*mappingrules.RuleTargetButton, 0)
|
||||
|
@ -100,8 +111,8 @@ func makeMappingRuleCombo(ruleConfig RuleConfig,
|
|||
}
|
||||
|
||||
func makeMappingRuleLatched(ruleConfig RuleConfig,
|
||||
pDevs map[string]*evdev.InputDevice,
|
||||
vDevs map[string]*evdev.InputDevice,
|
||||
pDevs map[string]Device,
|
||||
vDevs map[string]Device,
|
||||
base mappingrules.MappingRuleBase) (*mappingrules.MappingRuleButtonLatched, error) {
|
||||
|
||||
input, err := makeRuleTargetButton(ruleConfig.Input, pDevs)
|
||||
|
@ -118,8 +129,8 @@ func makeMappingRuleLatched(ruleConfig RuleConfig,
|
|||
}
|
||||
|
||||
func makeMappingRuleAxis(ruleConfig RuleConfig,
|
||||
pDevs map[string]*evdev.InputDevice,
|
||||
vDevs map[string]*evdev.InputDevice,
|
||||
pDevs map[string]Device,
|
||||
vDevs map[string]Device,
|
||||
base mappingrules.MappingRuleBase) (*mappingrules.MappingRuleAxis, error) {
|
||||
|
||||
input, err := makeRuleTargetAxis(ruleConfig.Input, pDevs)
|
||||
|
@ -136,8 +147,8 @@ func makeMappingRuleAxis(ruleConfig RuleConfig,
|
|||
}
|
||||
|
||||
func makeMappingRuleAxisToButton(ruleConfig RuleConfig,
|
||||
pDevs map[string]*evdev.InputDevice,
|
||||
vDevs map[string]*evdev.InputDevice,
|
||||
pDevs map[string]Device,
|
||||
vDevs map[string]Device,
|
||||
base mappingrules.MappingRuleBase) (*mappingrules.MappingRuleAxisToButton, error) {
|
||||
|
||||
input, err := makeRuleTargetAxis(ruleConfig.Input, pDevs)
|
||||
|
@ -154,8 +165,8 @@ func makeMappingRuleAxisToButton(ruleConfig RuleConfig,
|
|||
}
|
||||
|
||||
func makeMappingRuleAxisToRelaxis(ruleConfig RuleConfig,
|
||||
pDevs map[string]*evdev.InputDevice,
|
||||
vDevs map[string]*evdev.InputDevice,
|
||||
pDevs map[string]Device,
|
||||
vDevs map[string]Device,
|
||||
base mappingrules.MappingRuleBase) (*mappingrules.MappingRuleAxisToRelaxis, error) {
|
||||
|
||||
input, err := makeRuleTargetAxis(ruleConfig.Input, pDevs)
|
||||
|
@ -176,7 +187,7 @@ func makeMappingRuleAxisToRelaxis(ruleConfig RuleConfig,
|
|||
}
|
||||
|
||||
func makeMappingRuleModeSelect(ruleConfig RuleConfig,
|
||||
pDevs map[string]*evdev.InputDevice,
|
||||
pDevs map[string]Device,
|
||||
modes []string,
|
||||
base mappingrules.MappingRuleBase) (*mappingrules.MappingRuleModeSelect, error) {
|
||||
|
||||
|
|
|
@ -41,11 +41,14 @@ type RuleConfig struct {
|
|||
}
|
||||
|
||||
type RuleTargetConfig struct {
|
||||
Device string `yaml:"device,omitempty"`
|
||||
Button string `yaml:"button,omitempty"`
|
||||
Axis string `yaml:"axis,omitempty"`
|
||||
DeadzoneStart int32 `yaml:"deadzone_start,omitempty"`
|
||||
DeadzoneEnd int32 `yaml:"deadzone_end,omitempty"`
|
||||
Inverted bool `yaml:"inverted,omitempty"`
|
||||
Modes []string `yaml:"modes,omitempty"`
|
||||
Device string `yaml:"device,omitempty"`
|
||||
Button string `yaml:"button,omitempty"`
|
||||
Axis string `yaml:"axis,omitempty"`
|
||||
DeadzoneCenter int32 `yaml:"deadzone_center,omitempty"`
|
||||
DeadzoneSize int32 `yaml:"deadzone_size,omitempty"`
|
||||
DeadzoneSizePercent int32 `yaml:"deadzone_size_percent,omitempty"`
|
||||
DeadzoneStart int32 `yaml:"deadzone_start,omitempty"`
|
||||
DeadzoneEnd int32 `yaml:"deadzone_end,omitempty"`
|
||||
Inverted bool `yaml:"inverted,omitempty"`
|
||||
Modes []string `yaml:"modes,omitempty"`
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@ import (
|
|||
)
|
||||
|
||||
type MappingRule interface {
|
||||
MatchEvent(RuleTargetDevice, *evdev.InputEvent, *string) (*evdev.InputDevice, *evdev.InputEvent)
|
||||
MatchEvent(Device, *evdev.InputEvent, *string) (*evdev.InputDevice, *evdev.InputEvent)
|
||||
}
|
||||
|
||||
type TimedEventEmitter interface {
|
||||
|
@ -35,13 +35,13 @@ type RuleTarget interface {
|
|||
// for most implementations.
|
||||
CreateEvent(int32, *string) *evdev.InputEvent
|
||||
|
||||
MatchEvent(device RuleTargetDevice, event *evdev.InputEvent) bool
|
||||
MatchEvent(device Device, event *evdev.InputEvent) bool
|
||||
}
|
||||
|
||||
// RuleTargetDevice is an interface abstraction on top of evdev.InputDevice, implementing
|
||||
// Device is an interface abstraction on top of evdev.InputDevice, implementing
|
||||
// only the methods we need in this package. This is used for testing, and the
|
||||
// RuleTargetDevice can be safely cast to an *evdev.InputDevice when necessary.
|
||||
type RuleTargetDevice interface {
|
||||
// Device can be safely cast to an *evdev.InputDevice when necessary.
|
||||
type Device interface {
|
||||
AbsInfos() (map[evdev.EvCode]evdev.AbsInfo, error)
|
||||
}
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@ func NewMappingRuleAxis(base MappingRuleBase, input *RuleTargetAxis, output *Rul
|
|||
}
|
||||
}
|
||||
|
||||
func (rule *MappingRuleAxis) MatchEvent(device RuleTargetDevice, event *evdev.InputEvent, mode *string) (*evdev.InputDevice, *evdev.InputEvent) {
|
||||
func (rule *MappingRuleAxis) MatchEvent(device Device, event *evdev.InputEvent, mode *string) (*evdev.InputDevice, *evdev.InputEvent) {
|
||||
if !rule.MappingRuleBase.modeCheck(mode) ||
|
||||
!rule.Input.MatchEvent(device, event) {
|
||||
return nil, nil
|
||||
|
|
|
@ -39,7 +39,7 @@ func NewMappingRuleAxisToButton(base MappingRuleBase, input *RuleTargetAxis, out
|
|||
}
|
||||
}
|
||||
|
||||
func (rule *MappingRuleAxisToButton) MatchEvent(device RuleTargetDevice, event *evdev.InputEvent, mode *string) (*evdev.InputDevice, *evdev.InputEvent) {
|
||||
func (rule *MappingRuleAxisToButton) MatchEvent(device Device, event *evdev.InputEvent, mode *string) (*evdev.InputDevice, *evdev.InputEvent) {
|
||||
|
||||
if !rule.MappingRuleBase.modeCheck(mode) ||
|
||||
!rule.Input.MatchEventDeviceAndCode(device, event) {
|
||||
|
@ -105,5 +105,5 @@ func (rule *MappingRuleAxisToButton) TimerEvent() *evdev.InputEvent {
|
|||
}
|
||||
|
||||
func (rule *MappingRuleAxisToButton) GetOutputDevice() *evdev.InputDevice {
|
||||
return rule.Output.Device
|
||||
return rule.Output.Device.(*evdev.InputDevice)
|
||||
}
|
||||
|
|
|
@ -43,7 +43,7 @@ func NewMappingRuleAxisToRelaxis(
|
|||
}
|
||||
|
||||
func (rule *MappingRuleAxisToRelaxis) MatchEvent(
|
||||
device RuleTargetDevice,
|
||||
device Device,
|
||||
event *evdev.InputEvent,
|
||||
mode *string) (*evdev.InputDevice, *evdev.InputEvent) {
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@ func NewMappingRuleButton(
|
|||
}
|
||||
}
|
||||
|
||||
func (rule *MappingRuleButton) MatchEvent(device RuleTargetDevice, event *evdev.InputEvent, mode *string) (*evdev.InputDevice, *evdev.InputEvent) {
|
||||
func (rule *MappingRuleButton) MatchEvent(device Device, event *evdev.InputEvent, mode *string) (*evdev.InputDevice, *evdev.InputEvent) {
|
||||
if !rule.MappingRuleBase.modeCheck(mode) {
|
||||
return nil, nil
|
||||
}
|
||||
|
@ -31,5 +31,5 @@ func (rule *MappingRuleButton) MatchEvent(device RuleTargetDevice, event *evdev.
|
|||
return nil, nil
|
||||
}
|
||||
|
||||
return rule.Output.Device, rule.Output.CreateEvent(rule.Input.NormalizeValue(event.Value), mode)
|
||||
return rule.Output.Device.(*evdev.InputDevice), rule.Output.CreateEvent(rule.Input.NormalizeValue(event.Value), mode)
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@ func NewMappingRuleButtonCombo(
|
|||
}
|
||||
}
|
||||
|
||||
func (rule *MappingRuleButtonCombo) MatchEvent(device RuleTargetDevice, event *evdev.InputEvent, mode *string) (*evdev.InputDevice, *evdev.InputEvent) {
|
||||
func (rule *MappingRuleButtonCombo) MatchEvent(device Device, event *evdev.InputEvent, mode *string) (*evdev.InputDevice, *evdev.InputEvent) {
|
||||
if !rule.MappingRuleBase.modeCheck(mode) {
|
||||
return nil, nil
|
||||
}
|
||||
|
@ -53,10 +53,10 @@ func (rule *MappingRuleButtonCombo) MatchEvent(device RuleTargetDevice, event *e
|
|||
targetState := len(rule.Inputs)
|
||||
|
||||
if oldState == targetState-1 && rule.State == targetState {
|
||||
return rule.Output.Device, rule.Output.CreateEvent(1, mode)
|
||||
return rule.Output.Device.(*evdev.InputDevice), rule.Output.CreateEvent(1, mode)
|
||||
}
|
||||
if oldState == targetState && rule.State == targetState-1 {
|
||||
return rule.Output.Device, rule.Output.CreateEvent(0, mode)
|
||||
return rule.Output.Device.(*evdev.InputDevice), rule.Output.CreateEvent(0, mode)
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@ func NewMappingRuleButtonLatched(
|
|||
}
|
||||
}
|
||||
|
||||
func (rule *MappingRuleButtonLatched) MatchEvent(device RuleTargetDevice, event *evdev.InputEvent, mode *string) (*evdev.InputDevice, *evdev.InputEvent) {
|
||||
func (rule *MappingRuleButtonLatched) MatchEvent(device Device, event *evdev.InputEvent, mode *string) (*evdev.InputDevice, *evdev.InputEvent) {
|
||||
if !rule.MappingRuleBase.modeCheck(mode) {
|
||||
return nil, nil
|
||||
}
|
||||
|
@ -42,5 +42,5 @@ func (rule *MappingRuleButtonLatched) MatchEvent(device RuleTargetDevice, event
|
|||
value = 0
|
||||
}
|
||||
|
||||
return rule.Output.Device, rule.Output.CreateEvent(value, mode)
|
||||
return rule.Output.Device.(*evdev.InputDevice), rule.Output.CreateEvent(value, mode)
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@ func NewMappingRuleModeSelect(
|
|||
}
|
||||
|
||||
func (rule *MappingRuleModeSelect) MatchEvent(
|
||||
device RuleTargetDevice,
|
||||
device Device,
|
||||
event *evdev.InputEvent,
|
||||
mode *string) (*evdev.InputDevice, *evdev.InputEvent) {
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ import (
|
|||
|
||||
type RuleTargetAxis struct {
|
||||
DeviceName string
|
||||
Device RuleTargetDevice
|
||||
Device Device
|
||||
Axis evdev.EvCode
|
||||
Inverted bool
|
||||
DeadzoneStart int32
|
||||
|
@ -19,7 +19,7 @@ type RuleTargetAxis struct {
|
|||
}
|
||||
|
||||
func NewRuleTargetAxis(device_name string,
|
||||
device RuleTargetDevice,
|
||||
device Device,
|
||||
axis evdev.EvCode,
|
||||
inverted bool,
|
||||
deadzoneStart int32,
|
||||
|
@ -89,13 +89,13 @@ func (target *RuleTargetAxis) CreateEvent(value int32, mode *string) *evdev.Inpu
|
|||
}
|
||||
}
|
||||
|
||||
func (target *RuleTargetAxis) MatchEvent(device RuleTargetDevice, event *evdev.InputEvent) bool {
|
||||
func (target *RuleTargetAxis) MatchEvent(device Device, event *evdev.InputEvent) bool {
|
||||
return target.MatchEventDeviceAndCode(device, event) &&
|
||||
!target.InDeadZone(event.Value)
|
||||
}
|
||||
|
||||
// TODO: Add tests
|
||||
func (target *RuleTargetAxis) MatchEventDeviceAndCode(device RuleTargetDevice, event *evdev.InputEvent) bool {
|
||||
func (target *RuleTargetAxis) MatchEventDeviceAndCode(device Device, event *evdev.InputEvent) bool {
|
||||
return device == target.Device &&
|
||||
event.Type == evdev.EV_ABS &&
|
||||
event.Code == target.Axis
|
||||
|
|
|
@ -4,12 +4,12 @@ import "github.com/holoplot/go-evdev"
|
|||
|
||||
type RuleTargetButton struct {
|
||||
DeviceName string
|
||||
Device *evdev.InputDevice
|
||||
Device Device
|
||||
Button evdev.EvCode
|
||||
Inverted bool
|
||||
}
|
||||
|
||||
func NewRuleTargetButton(device_name string, device *evdev.InputDevice, code evdev.EvCode, inverted bool) (*RuleTargetButton, error) {
|
||||
func NewRuleTargetButton(device_name string, device Device, code evdev.EvCode, inverted bool) (*RuleTargetButton, error) {
|
||||
return &RuleTargetButton{
|
||||
DeviceName: device_name,
|
||||
Device: device,
|
||||
|
@ -36,7 +36,7 @@ func (target *RuleTargetButton) CreateEvent(value int32, _ *string) *evdev.Input
|
|||
}
|
||||
}
|
||||
|
||||
func (target *RuleTargetButton) MatchEvent(device RuleTargetDevice, event *evdev.InputEvent) bool {
|
||||
func (target *RuleTargetButton) MatchEvent(device Device, event *evdev.InputEvent) bool {
|
||||
return device == target.Device &&
|
||||
event.Type == evdev.EV_KEY &&
|
||||
event.Code == target.Button
|
||||
|
|
|
@ -6,13 +6,13 @@ import (
|
|||
|
||||
type RuleTargetRelaxis struct {
|
||||
DeviceName string
|
||||
Device RuleTargetDevice
|
||||
Device Device
|
||||
Axis evdev.EvCode
|
||||
Inverted bool
|
||||
}
|
||||
|
||||
func NewRuleTargetRelaxis(device_name string,
|
||||
device RuleTargetDevice,
|
||||
device Device,
|
||||
axis evdev.EvCode,
|
||||
inverted bool) (*RuleTargetRelaxis, error) {
|
||||
|
||||
|
@ -41,6 +41,6 @@ func (target *RuleTargetRelaxis) CreateEvent(value int32, mode *string) *evdev.I
|
|||
}
|
||||
|
||||
// Relative axis is only supported for output.
|
||||
func (target *RuleTargetRelaxis) MatchEvent(device RuleTargetDevice, event *evdev.InputEvent) bool {
|
||||
func (target *RuleTargetRelaxis) MatchEvent(device Device, event *evdev.InputEvent) bool {
|
||||
return false
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue