Implement rule matching for a couple of basic rule types.
This commit is contained in:
parent
5b3b70da14
commit
970b3ded6e
3 changed files with 64 additions and 15 deletions
|
@ -22,7 +22,8 @@ type DeviceConfig struct {
|
||||||
type RuleConfig struct {
|
type RuleConfig struct {
|
||||||
Name string `yaml:"name,omitempty"`
|
Name string `yaml:"name,omitempty"`
|
||||||
Type string `yaml:"type"`
|
Type string `yaml:"type"`
|
||||||
Input []RuleInputConfig `yaml:"input"`
|
Input RuleInputConfig `yaml:"input,omitempty"`
|
||||||
|
Inputs []RuleInputConfig `yaml:"inputs,omitempty"`
|
||||||
Output RuleOutputConfig `yaml:"output"`
|
Output RuleOutputConfig `yaml:"output"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,10 @@ func Log(msg string) {
|
||||||
fmt.Println(msg)
|
fmt.Println(msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Logf(msg string, params ...interface{}) {
|
||||||
|
fmt.Printf(msg, params...)
|
||||||
|
}
|
||||||
|
|
||||||
func LogError(err error, msg string) {
|
func LogError(err error, msg string) {
|
||||||
if msg == "" {
|
if msg == "" {
|
||||||
fmt.Printf("%s\n", err.Error())
|
fmt.Printf("%s\n", err.Error())
|
||||||
|
|
|
@ -9,42 +9,86 @@ type KeyMappingRule interface {
|
||||||
MatchEvent(*evdev.InputDevice, *evdev.InputEvent)
|
MatchEvent(*evdev.InputDevice, *evdev.InputEvent)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// A Simple Mapping Rule can map a button to a button or an axis to an axis.
|
||||||
type SimpleMappingRule struct {
|
type SimpleMappingRule struct {
|
||||||
Input RuleTarget
|
Input RuleTarget
|
||||||
Output RuleTarget
|
Output RuleTarget
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// A Combo Mapping Rule can require multiple physical button presses for a single output button
|
||||||
type ComboMappingRule struct {
|
type ComboMappingRule struct {
|
||||||
Input []RuleTarget
|
Input []RuleTarget
|
||||||
Output RuleTarget
|
Output RuleTarget
|
||||||
|
State int
|
||||||
}
|
}
|
||||||
|
|
||||||
func (rule *SimpleMappingRule) MatchEvent(device *evdev.InputDevice, event *evdev.InputEvent) *evdev.InputEvent {
|
func eventFromTarget(output RuleTarget, value int32) *evdev.InputEvent {
|
||||||
if event.Type != evdev.EV_KEY ||
|
return &evdev.InputEvent{
|
||||||
device != rule.Input.Device ||
|
Type: output.Type,
|
||||||
event.Code != rule.Input.Code {
|
Code: output.Code,
|
||||||
return nil
|
Value: value,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func valueFromTarget(rule RuleTarget, event *evdev.InputEvent) int32 {
|
||||||
// how we process inverted rules depends on the event type
|
// how we process inverted rules depends on the event type
|
||||||
value := event.Value
|
value := event.Value
|
||||||
if rule.Input.Inverted {
|
if rule.Inverted {
|
||||||
switch rule.Input.Type {
|
switch rule.Type {
|
||||||
case evdev.EV_KEY:
|
case evdev.EV_KEY:
|
||||||
if value == 0 {
|
if value == 0 {
|
||||||
value = 1
|
value = 1
|
||||||
} else {
|
} else {
|
||||||
value = 0
|
value = 0
|
||||||
}
|
}
|
||||||
|
case evdev.EV_ABS:
|
||||||
|
// TODO: how would we invert axes?
|
||||||
default:
|
default:
|
||||||
logger.Log("Tried to handle inverted rule for unknown event type. Skipping rule.")
|
logger.Logf("Inverted rule for unknown event type '%d'. Not inverting value\n", event.Type)
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return &evdev.InputEvent{
|
return value
|
||||||
Type: rule.Output.Type,
|
}
|
||||||
Code: rule.Output.Code,
|
|
||||||
Value: value,
|
func (rule *SimpleMappingRule) MatchEvent(device *evdev.InputDevice, event *evdev.InputEvent) *evdev.InputEvent {
|
||||||
|
if device != rule.Input.Device ||
|
||||||
|
event.Code != rule.Input.Code {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return eventFromTarget(rule.Output, valueFromTarget(rule.Input, event))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rule *ComboMappingRule) MatchEvent(device *evdev.InputDevice, event *evdev.InputEvent) *evdev.InputEvent {
|
||||||
|
// Check each of the inputs, and if we find a match, proceed
|
||||||
|
var match *RuleTarget
|
||||||
|
for _, input := range rule.Input {
|
||||||
|
if device == input.Device &&
|
||||||
|
event.Code == input.Code {
|
||||||
|
match = &input
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if match == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the value and add/subtract it from State
|
||||||
|
inputValue := valueFromTarget(*match, event)
|
||||||
|
oldState := rule.State
|
||||||
|
if inputValue == 0 {
|
||||||
|
rule.State--
|
||||||
|
}
|
||||||
|
if inputValue == 1 {
|
||||||
|
rule.State++
|
||||||
|
}
|
||||||
|
targetState := len(rule.Input)
|
||||||
|
if oldState == targetState-1 && rule.State == targetState {
|
||||||
|
return eventFromTarget(rule.Output, 1)
|
||||||
|
}
|
||||||
|
if oldState == targetState && rule.State == targetState-1 {
|
||||||
|
return eventFromTarget(rule.Output, 0)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue