Read events from multiple devices.
This commit is contained in:
parent
a5b59bf39e
commit
a078dcb193
4 changed files with 59 additions and 31 deletions
|
@ -1,9 +1,9 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"time"
|
|
||||||
|
|
||||||
"git.annabunches.net/annabunches/joyful/internal/config"
|
"git.annabunches.net/annabunches/joyful/internal/config"
|
||||||
"git.annabunches.net/annabunches/joyful/internal/logger"
|
"git.annabunches.net/annabunches/joyful/internal/logger"
|
||||||
|
@ -63,38 +63,56 @@ func main() {
|
||||||
// Initialize rules
|
// Initialize rules
|
||||||
rules := config.BuildRules(pDevices, getVirtualDevices(vBuffers))
|
rules := config.BuildRules(pDevices, getVirtualDevices(vBuffers))
|
||||||
|
|
||||||
// TEST CODE
|
// Listen for events and map them forever
|
||||||
testDriver(vBuffers, pDevices, rules)
|
mapEvents(vBuffers, pDevices, rules)
|
||||||
}
|
}
|
||||||
|
|
||||||
func testDriver(vBuffers map[string]*virtualdevice.EventBuffer, pDevices map[string]*evdev.InputDevice, rules []mappingrules.MappingRule) {
|
type ChannelEvent struct {
|
||||||
pDevice := pDevices["right-stick"]
|
Device *evdev.InputDevice
|
||||||
buffer := vBuffers["main"]
|
Event *evdev.InputEvent
|
||||||
for {
|
}
|
||||||
// Get the first event for this report
|
|
||||||
event, err := pDevice.ReadOne()
|
|
||||||
logger.LogIfError(err, "Error while reading event")
|
|
||||||
|
|
||||||
for event.Code != evdev.SYN_REPORT {
|
func mapEvents(vBuffers map[string]*virtualdevice.EventBuffer, pDevices map[string]*evdev.InputDevice, rules []mappingrules.MappingRule) {
|
||||||
|
// start listening for events on all devices
|
||||||
|
eventChannel := make(chan *ChannelEvent, 1000)
|
||||||
|
for _, device := range pDevices {
|
||||||
|
go eventWatcher(device, eventChannel)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("Joyful Running! Press Ctrl+C to quit.")
|
||||||
|
for {
|
||||||
|
// Get an event (blocks if necessary)
|
||||||
|
wrapper := <-eventChannel
|
||||||
|
|
||||||
|
switch wrapper.Event.Type {
|
||||||
|
case evdev.EV_SYN:
|
||||||
|
// We've received a SYN_REPORT, so now we send all of our pending events
|
||||||
|
for _, buffer := range vBuffers {
|
||||||
|
buffer.SendEvents()
|
||||||
|
}
|
||||||
|
|
||||||
|
case evdev.EV_KEY:
|
||||||
|
case evdev.EV_ABS:
|
||||||
|
// We have a matchable event type. Check all the events
|
||||||
for _, rule := range rules {
|
for _, rule := range rules {
|
||||||
event := rule.MatchEvent(pDevice, event)
|
outputEvent := rule.MatchEvent(wrapper.Device, wrapper.Event)
|
||||||
if event == nil {
|
if outputEvent == nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
buffer.AddEvent(event)
|
vBuffers[rule.OutputName()].AddEvent(outputEvent)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the next event
|
func eventWatcher(device *evdev.InputDevice, channel chan *ChannelEvent) {
|
||||||
event, err = pDevice.ReadOne()
|
for {
|
||||||
logger.LogIfError(err, "Error while reading event")
|
event, err := device.ReadOne()
|
||||||
|
if err != nil {
|
||||||
|
logger.LogError(err, "Error while reading event")
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
|
channel <- &ChannelEvent{Device: device, Event: event}
|
||||||
// We've received a SYN_REPORT, so now we can send all of our events
|
|
||||||
// TODO: how shall we handle this when dealing with multiple devices?
|
|
||||||
buffer.SendEvents()
|
|
||||||
|
|
||||||
time.Sleep(1 * time.Millisecond)
|
|
||||||
}
|
}
|
||||||
// END TEST CODE
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -64,6 +64,7 @@ func makeRuleTarget(targetConfig RuleTargetConfig, devs map[string]*evdev.InputD
|
||||||
ruleTarget.Type = eventType
|
ruleTarget.Type = eventType
|
||||||
ruleTarget.Code = eventCode
|
ruleTarget.Code = eventCode
|
||||||
ruleTarget.Inverted = targetConfig.Inverted
|
ruleTarget.Inverted = targetConfig.Inverted
|
||||||
|
ruleTarget.DeviceName = targetConfig.Device
|
||||||
|
|
||||||
return ruleTarget, nil
|
return ruleTarget, nil
|
||||||
}
|
}
|
||||||
|
@ -83,8 +84,7 @@ func decodeRuleTargetValues(target RuleTargetConfig) (evdev.EvType, evdev.EvCode
|
||||||
if !ok {
|
if !ok {
|
||||||
return 0, 0, fmt.Errorf("skipping rule due to invalid button code '%s'", target.Button)
|
return 0, 0, fmt.Errorf("skipping rule due to invalid button code '%s'", target.Button)
|
||||||
}
|
}
|
||||||
}
|
} else if target.Axis != "" {
|
||||||
if target.Axis != "" {
|
|
||||||
eventType = evdev.EV_ABS
|
eventType = evdev.EV_ABS
|
||||||
eventCode, ok = evdev.ABSFromString[target.Axis]
|
eventCode, ok = evdev.ABSFromString[target.Axis]
|
||||||
if !ok {
|
if !ok {
|
||||||
|
|
|
@ -78,3 +78,11 @@ func (rule *ComboMappingRule) MatchEvent(device *evdev.InputDevice, event *evdev
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (rule *SimpleMappingRule) OutputName() string {
|
||||||
|
return rule.Output.DeviceName
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rule *ComboMappingRule) OutputName() string {
|
||||||
|
return rule.Output.DeviceName
|
||||||
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@ import "github.com/holoplot/go-evdev"
|
||||||
|
|
||||||
type MappingRule interface {
|
type MappingRule interface {
|
||||||
MatchEvent(*evdev.InputDevice, *evdev.InputEvent) *evdev.InputEvent
|
MatchEvent(*evdev.InputDevice, *evdev.InputEvent) *evdev.InputEvent
|
||||||
|
OutputName() string
|
||||||
}
|
}
|
||||||
|
|
||||||
// A Simple Mapping Rule can map a button to a button or an axis to an axis.
|
// A Simple Mapping Rule can map a button to a button or an axis to an axis.
|
||||||
|
@ -22,6 +23,7 @@ type ComboMappingRule struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type RuleTarget struct {
|
type RuleTarget struct {
|
||||||
|
DeviceName string
|
||||||
Device *evdev.InputDevice
|
Device *evdev.InputDevice
|
||||||
Type evdev.EvType
|
Type evdev.EvType
|
||||||
Code evdev.EvCode
|
Code evdev.EvCode
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue