Build rules from config.
This commit is contained in:
parent
50474f9fb2
commit
428749a519
7 changed files with 186 additions and 106 deletions
79
internal/mappingrules/matching.go
Normal file
79
internal/mappingrules/matching.go
Normal file
|
@ -0,0 +1,79 @@
|
|||
package mappingrules
|
||||
|
||||
import (
|
||||
"git.annabunches.net/annabunches/joyful/internal/logger"
|
||||
"github.com/holoplot/go-evdev"
|
||||
)
|
||||
|
||||
// eventFromTarget creates an outputtable event from a RuleTarget
|
||||
func eventFromTarget(output RuleTarget, value int32) *evdev.InputEvent {
|
||||
return &evdev.InputEvent{
|
||||
Type: output.Type,
|
||||
Code: output.Code,
|
||||
Value: value,
|
||||
}
|
||||
}
|
||||
|
||||
// valueFromTarget determines the value to output from an input specification,given a RuleTarget's constraints
|
||||
func valueFromTarget(rule RuleTarget, event *evdev.InputEvent) int32 {
|
||||
// how we process inverted rules depends on the event type
|
||||
value := event.Value
|
||||
if rule.Inverted {
|
||||
switch rule.Type {
|
||||
case evdev.EV_KEY:
|
||||
if value == 0 {
|
||||
value = 1
|
||||
} else {
|
||||
value = 0
|
||||
}
|
||||
case evdev.EV_ABS:
|
||||
// TODO: how would we invert axes?
|
||||
default:
|
||||
logger.Logf("Inverted rule for unknown event type '%d'. Not inverting value\n", event.Type)
|
||||
}
|
||||
}
|
||||
|
||||
return 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.Inputs {
|
||||
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.Inputs)
|
||||
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
|
||||
}
|
27
internal/mappingrules/types.go
Normal file
27
internal/mappingrules/types.go
Normal file
|
@ -0,0 +1,27 @@
|
|||
package mappingrules
|
||||
|
||||
import "github.com/holoplot/go-evdev"
|
||||
|
||||
type MappingRule interface {
|
||||
MatchEvent(*evdev.InputDevice, *evdev.InputEvent) *evdev.InputEvent
|
||||
}
|
||||
|
||||
// A Simple Mapping Rule can map a button to a button or an axis to an axis.
|
||||
type SimpleMappingRule struct {
|
||||
Input RuleTarget
|
||||
Output RuleTarget
|
||||
}
|
||||
|
||||
// A Combo Mapping Rule can require multiple physical button presses for a single output button
|
||||
type ComboMappingRule struct {
|
||||
Inputs []RuleTarget
|
||||
Output RuleTarget
|
||||
State int
|
||||
}
|
||||
|
||||
type RuleTarget struct {
|
||||
Device *evdev.InputDevice
|
||||
Type evdev.EvType
|
||||
Code evdev.EvCode
|
||||
Inverted bool
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue