Small fixes for config parsing, and start plumbing it into our main program.
This commit is contained in:
parent
02c8642ead
commit
eeebb6d0b1
5 changed files with 144 additions and 124 deletions
|
@ -4,61 +4,34 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"git.annabunches.net/annabunches/joyful/internal/config"
|
||||||
"git.annabunches.net/annabunches/joyful/internal/logger"
|
"git.annabunches.net/annabunches/joyful/internal/logger"
|
||||||
"git.annabunches.net/annabunches/joyful/internal/virtualdevice"
|
"git.annabunches.net/annabunches/joyful/internal/virtualdevice"
|
||||||
"github.com/holoplot/go-evdev"
|
"github.com/holoplot/go-evdev"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
// STUB: parse virtual device config
|
// parse configs
|
||||||
|
parser := &config.ConfigParser{}
|
||||||
|
parser.Parse("~/.config/joyful") // TODO: make ~ work here
|
||||||
|
|
||||||
// STUB: parse mapping config
|
vDevices := parser.CreateVirtualDevices()
|
||||||
|
vBuffers := make(map[string]*virtualdevice.EventBuffer)
|
||||||
// Define virtual device
|
for name, device := range vDevices {
|
||||||
// TODO: create virtual devices from config
|
vBuffers[name] = virtualdevice.NewEventBuffer(device)
|
||||||
vDevice, err := evdev.CreateDevice(
|
|
||||||
"joyful-joystick",
|
|
||||||
evdev.InputID{
|
|
||||||
BusType: 0x03,
|
|
||||||
Vendor: 0x4711,
|
|
||||||
Product: 0x0816,
|
|
||||||
Version: 1,
|
|
||||||
},
|
|
||||||
map[evdev.EvType][]evdev.EvCode{
|
|
||||||
evdev.EV_KEY: jsButtons(),
|
|
||||||
evdev.EV_ABS: {
|
|
||||||
evdev.ABS_X,
|
|
||||||
evdev.ABS_Y,
|
|
||||||
evdev.ABS_Z,
|
|
||||||
evdev.ABS_RX,
|
|
||||||
evdev.ABS_RY,
|
|
||||||
evdev.ABS_RZ,
|
|
||||||
evdev.ABS_THROTTLE,
|
|
||||||
evdev.ABS_WHEEL,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
)
|
|
||||||
logger.FatalIfError(err, "Failed to create virtual device")
|
|
||||||
|
|
||||||
buffer := virtualdevice.NewEventBuffer(vDevice)
|
|
||||||
|
|
||||||
name, err := vDevice.Name()
|
|
||||||
if err != nil {
|
|
||||||
name = "Unknown"
|
|
||||||
}
|
}
|
||||||
fmt.Printf("Virtual device created as %s.\n", name)
|
|
||||||
|
|
||||||
pDevice, err := evdev.Open("/dev/input/event12")
|
pDevice, err := evdev.Open("/dev/input/event12")
|
||||||
logger.FatalIfError(err, "Couldn't open physical device")
|
logger.FatalIfError(err, "Couldn't open physical device")
|
||||||
|
|
||||||
name, err = pDevice.Name()
|
name, err := pDevice.Name()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
name = "Unknown"
|
name = "Unknown"
|
||||||
}
|
}
|
||||||
fmt.Printf("Connected to physical device %s\n", name)
|
fmt.Printf("Connected to physical device %s\n", name)
|
||||||
|
|
||||||
var combo int32 = 0
|
var combo int32 = 0
|
||||||
|
buffer := vBuffers["test"]
|
||||||
for {
|
for {
|
||||||
last := combo
|
last := combo
|
||||||
|
|
||||||
|
@ -126,21 +99,4 @@ func main() {
|
||||||
|
|
||||||
time.Sleep(1 * time.Millisecond)
|
time.Sleep(1 * time.Millisecond)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func jsButtons() []evdev.EvCode {
|
|
||||||
buttons := make([]evdev.EvCode, 80)
|
|
||||||
i := 0
|
|
||||||
|
|
||||||
for code := 0x120; code <= 0x12f; code++ {
|
|
||||||
buttons[i] = evdev.EvCode(code)
|
|
||||||
i++
|
|
||||||
}
|
|
||||||
|
|
||||||
for code := 0x2c0; code <= 0x2ff; code++ {
|
|
||||||
buttons[i] = evdev.EvCode(code)
|
|
||||||
i++
|
|
||||||
}
|
|
||||||
|
|
||||||
return buttons
|
|
||||||
}
|
|
|
@ -8,6 +8,7 @@ import (
|
||||||
|
|
||||||
"git.annabunches.net/annabunches/joyful/internal/logger"
|
"git.annabunches.net/annabunches/joyful/internal/logger"
|
||||||
"github.com/goccy/go-yaml"
|
"github.com/goccy/go-yaml"
|
||||||
|
"github.com/holoplot/go-evdev"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ConfigParser struct {
|
type ConfigParser struct {
|
||||||
|
@ -19,7 +20,10 @@ type ConfigParser struct {
|
||||||
func (parser *ConfigParser) Parse(directory string) {
|
func (parser *ConfigParser) Parse(directory string) {
|
||||||
// Find the config files in the directory
|
// Find the config files in the directory
|
||||||
dirEntries, err := os.ReadDir(directory)
|
dirEntries, err := os.ReadDir(directory)
|
||||||
logger.FatalIfError(err, "Failed to read config directory")
|
if err != nil {
|
||||||
|
err = os.Mkdir(directory, 0755)
|
||||||
|
logger.FatalIfError(err, "Failed to create config directory at "+directory)
|
||||||
|
}
|
||||||
|
|
||||||
for _, file := range dirEntries {
|
for _, file := range dirEntries {
|
||||||
name := file.Name()
|
name := file.Name()
|
||||||
|
@ -54,9 +58,76 @@ func (parser *ConfigParser) parseConfigFiles() []byte {
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(rawData) == 0 {
|
if len(rawData) == 0 {
|
||||||
logger.Log("No config data found")
|
logger.Log("No config data found. Write .yml config files in ~/.config/joyful")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return rawData
|
return rawData
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (parser *ConfigParser) CreateVirtualDevices() map[string]*evdev.InputDevice {
|
||||||
|
deviceMap := make(map[string]*evdev.InputDevice)
|
||||||
|
|
||||||
|
for _, deviceConfig := range parser.config.Devices.Virtual {
|
||||||
|
vDevice, err := evdev.CreateDevice(
|
||||||
|
fmt.Sprintf("joyful-%s", deviceConfig.Name),
|
||||||
|
// TODO: who knows what these should actually be
|
||||||
|
evdev.InputID{
|
||||||
|
BusType: 0x03,
|
||||||
|
Vendor: 0x4711,
|
||||||
|
Product: 0x0816,
|
||||||
|
Version: 1,
|
||||||
|
},
|
||||||
|
map[evdev.EvType][]evdev.EvCode{
|
||||||
|
evdev.EV_KEY: makeButtons(int(deviceConfig.Buttons)),
|
||||||
|
evdev.EV_ABS: makeAxes(int(deviceConfig.Axes)),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
logger.LogIfError(err, "Failed to create virtual device")
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
deviceMap[deviceConfig.Name] = vDevice
|
||||||
|
}
|
||||||
|
|
||||||
|
return deviceMap
|
||||||
|
}
|
||||||
|
|
||||||
|
func makeButtons(numButtons int) []evdev.EvCode {
|
||||||
|
if numButtons > 56 {
|
||||||
|
numButtons = 56
|
||||||
|
logger.Log("Limiting virtual device buttons to 56")
|
||||||
|
}
|
||||||
|
|
||||||
|
buttons := make([]evdev.EvCode, numButtons)
|
||||||
|
|
||||||
|
startCode := 0x120
|
||||||
|
for i := 0; i < numButtons && i < 16; i++ {
|
||||||
|
buttons[i] = evdev.EvCode(startCode + i)
|
||||||
|
}
|
||||||
|
|
||||||
|
if numButtons > 16 {
|
||||||
|
startCode = 0x2c0
|
||||||
|
for i := 0; i < numButtons - 16; i++ {
|
||||||
|
buttons[16+i] = evdev.EvCode(startCode+i)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return buttons
|
||||||
|
}
|
||||||
|
|
||||||
|
func makeAxes(numAxes int) []evdev.EvCode {
|
||||||
|
if numAxes > 8 {
|
||||||
|
numAxes = 8
|
||||||
|
logger.Log("Limiting virtual device axes to 8")
|
||||||
|
}
|
||||||
|
|
||||||
|
axes := make([]evdev.EvCode, numAxes)
|
||||||
|
for i := 0; i < numAxes; i++ {
|
||||||
|
axes[i] = evdev.EvCode(i)
|
||||||
|
}
|
||||||
|
|
||||||
|
return axes
|
||||||
|
}
|
|
@ -5,66 +5,58 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
EvCodeMap = map[string]evdev.EvCode{
|
ButtonFromIndex = []evdev.EvCode{
|
||||||
"ABS_X": evdev.ABS_X,
|
evdev.BTN_TRIGGER,
|
||||||
"ABS_Y": evdev.ABS_Y,
|
evdev.BTN_THUMB,
|
||||||
"ABS_Z": evdev.ABS_Z,
|
evdev.BTN_THUMB2,
|
||||||
"ABS_RX": evdev.ABS_RX,
|
evdev.BTN_TOP,
|
||||||
"ABS_RY": evdev.ABS_RY,
|
evdev.BTN_TOP2,
|
||||||
"ABS_RZ": evdev.ABS_RZ,
|
evdev.BTN_PINKIE,
|
||||||
"ABS_THROTTLE": evdev.ABS_THROTTLE,
|
evdev.BTN_BASE,
|
||||||
"ABS_WHEEL": evdev.ABS_WHEEL,
|
evdev.BTN_BASE2,
|
||||||
"BTN_TRIGGER": evdev.BTN_TRIGGER,
|
evdev.BTN_BASE3,
|
||||||
"BTN_THUMB": evdev.BTN_THUMB,
|
evdev.BTN_BASE4,
|
||||||
"BTN_THUMB2": evdev.BTN_THUMB2,
|
evdev.BTN_BASE5,
|
||||||
"BTN_TOP": evdev.BTN_TOP,
|
evdev.BTN_BASE6,
|
||||||
"BTN_TOP2": evdev.BTN_TOP2,
|
evdev.BTN_TRIGGER_HAPPY1,
|
||||||
"BTN_PINKIE": evdev.BTN_PINKIE,
|
evdev.BTN_TRIGGER_HAPPY2,
|
||||||
"BTN_BASE": evdev.BTN_BASE,
|
evdev.BTN_TRIGGER_HAPPY3,
|
||||||
"BTN_BASE2": evdev.BTN_BASE2,
|
evdev.BTN_TRIGGER_HAPPY4,
|
||||||
"BTN_BASE3": evdev.BTN_BASE3,
|
evdev.BTN_TRIGGER_HAPPY5,
|
||||||
"BTN_BASE4": evdev.BTN_BASE4,
|
evdev.BTN_TRIGGER_HAPPY6,
|
||||||
"BTN_BASE5": evdev.BTN_BASE5,
|
evdev.BTN_TRIGGER_HAPPY7,
|
||||||
"BTN_BASE6": evdev.BTN_BASE6,
|
evdev.BTN_TRIGGER_HAPPY8,
|
||||||
"BTN_TRIGGER_HAPPY1": evdev.BTN_TRIGGER_HAPPY1,
|
evdev.BTN_TRIGGER_HAPPY9,
|
||||||
"BTN_TRIGGER_HAPPY2": evdev.BTN_TRIGGER_HAPPY2,
|
evdev.BTN_TRIGGER_HAPPY10,
|
||||||
"BTN_TRIGGER_HAPPY3": evdev.BTN_TRIGGER_HAPPY3,
|
evdev.BTN_TRIGGER_HAPPY11,
|
||||||
"BTN_TRIGGER_HAPPY4": evdev.BTN_TRIGGER_HAPPY4,
|
evdev.BTN_TRIGGER_HAPPY12,
|
||||||
"BTN_TRIGGER_HAPPY5": evdev.BTN_TRIGGER_HAPPY5,
|
evdev.BTN_TRIGGER_HAPPY13,
|
||||||
"BTN_TRIGGER_HAPPY6": evdev.BTN_TRIGGER_HAPPY6,
|
evdev.BTN_TRIGGER_HAPPY14,
|
||||||
"BTN_TRIGGER_HAPPY7": evdev.BTN_TRIGGER_HAPPY7,
|
evdev.BTN_TRIGGER_HAPPY15,
|
||||||
"BTN_TRIGGER_HAPPY8": evdev.BTN_TRIGGER_HAPPY8,
|
evdev.BTN_TRIGGER_HAPPY16,
|
||||||
"BTN_TRIGGER_HAPPY9": evdev.BTN_TRIGGER_HAPPY9,
|
evdev.BTN_TRIGGER_HAPPY17,
|
||||||
"BTN_TRIGGER_HAPPY10": evdev.BTN_TRIGGER_HAPPY10,
|
evdev.BTN_TRIGGER_HAPPY18,
|
||||||
"BTN_TRIGGER_HAPPY11": evdev.BTN_TRIGGER_HAPPY11,
|
evdev.BTN_TRIGGER_HAPPY19,
|
||||||
"BTN_TRIGGER_HAPPY12": evdev.BTN_TRIGGER_HAPPY12,
|
evdev.BTN_TRIGGER_HAPPY20,
|
||||||
"BTN_TRIGGER_HAPPY13": evdev.BTN_TRIGGER_HAPPY13,
|
evdev.BTN_TRIGGER_HAPPY21,
|
||||||
"BTN_TRIGGER_HAPPY14": evdev.BTN_TRIGGER_HAPPY14,
|
evdev.BTN_TRIGGER_HAPPY22,
|
||||||
"BTN_TRIGGER_HAPPY15": evdev.BTN_TRIGGER_HAPPY15,
|
evdev.BTN_TRIGGER_HAPPY23,
|
||||||
"BTN_TRIGGER_HAPPY16": evdev.BTN_TRIGGER_HAPPY16,
|
evdev.BTN_TRIGGER_HAPPY24,
|
||||||
"BTN_TRIGGER_HAPPY17": evdev.BTN_TRIGGER_HAPPY17,
|
evdev.BTN_TRIGGER_HAPPY25,
|
||||||
"BTN_TRIGGER_HAPPY18": evdev.BTN_TRIGGER_HAPPY18,
|
evdev.BTN_TRIGGER_HAPPY26,
|
||||||
"BTN_TRIGGER_HAPPY19": evdev.BTN_TRIGGER_HAPPY19,
|
evdev.BTN_TRIGGER_HAPPY27,
|
||||||
"BTN_TRIGGER_HAPPY20": evdev.BTN_TRIGGER_HAPPY20,
|
evdev.BTN_TRIGGER_HAPPY28,
|
||||||
"BTN_TRIGGER_HAPPY21": evdev.BTN_TRIGGER_HAPPY21,
|
evdev.BTN_TRIGGER_HAPPY29,
|
||||||
"BTN_TRIGGER_HAPPY22": evdev.BTN_TRIGGER_HAPPY22,
|
evdev.BTN_TRIGGER_HAPPY30,
|
||||||
"BTN_TRIGGER_HAPPY23": evdev.BTN_TRIGGER_HAPPY23,
|
evdev.BTN_TRIGGER_HAPPY31,
|
||||||
"BTN_TRIGGER_HAPPY24": evdev.BTN_TRIGGER_HAPPY24,
|
evdev.BTN_TRIGGER_HAPPY32,
|
||||||
"BTN_TRIGGER_HAPPY25": evdev.BTN_TRIGGER_HAPPY25,
|
evdev.BTN_TRIGGER_HAPPY33,
|
||||||
"BTN_TRIGGER_HAPPY26": evdev.BTN_TRIGGER_HAPPY26,
|
evdev.BTN_TRIGGER_HAPPY34,
|
||||||
"BTN_TRIGGER_HAPPY27": evdev.BTN_TRIGGER_HAPPY27,
|
evdev.BTN_TRIGGER_HAPPY35,
|
||||||
"BTN_TRIGGER_HAPPY28": evdev.BTN_TRIGGER_HAPPY28,
|
evdev.BTN_TRIGGER_HAPPY36,
|
||||||
"BTN_TRIGGER_HAPPY29": evdev.BTN_TRIGGER_HAPPY29,
|
evdev.BTN_TRIGGER_HAPPY37,
|
||||||
"BTN_TRIGGER_HAPPY30": evdev.BTN_TRIGGER_HAPPY30,
|
evdev.BTN_TRIGGER_HAPPY38,
|
||||||
"BTN_TRIGGER_HAPPY31": evdev.BTN_TRIGGER_HAPPY31,
|
evdev.BTN_TRIGGER_HAPPY39,
|
||||||
"BTN_TRIGGER_HAPPY32": evdev.BTN_TRIGGER_HAPPY32,
|
evdev.BTN_TRIGGER_HAPPY40,
|
||||||
"BTN_TRIGGER_HAPPY33": evdev.BTN_TRIGGER_HAPPY33,
|
|
||||||
"BTN_TRIGGER_HAPPY34": evdev.BTN_TRIGGER_HAPPY34,
|
|
||||||
"BTN_TRIGGER_HAPPY35": evdev.BTN_TRIGGER_HAPPY35,
|
|
||||||
"BTN_TRIGGER_HAPPY36": evdev.BTN_TRIGGER_HAPPY36,
|
|
||||||
"BTN_TRIGGER_HAPPY37": evdev.BTN_TRIGGER_HAPPY37,
|
|
||||||
"BTN_TRIGGER_HAPPY38": evdev.BTN_TRIGGER_HAPPY38,
|
|
||||||
"BTN_TRIGGER_HAPPY39": evdev.BTN_TRIGGER_HAPPY39,
|
|
||||||
"BTN_TRIGGER_HAPPY40": evdev.BTN_TRIGGER_HAPPY40,
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
|
@ -16,8 +16,9 @@ type PhysicalDeviceConfig struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type VirtualDeviceConfig struct {
|
type VirtualDeviceConfig struct {
|
||||||
NumButtons int `yaml:"num_buttons"`
|
Name string `yaml:"name"`
|
||||||
NumAxes int `yaml:"num_axes"`
|
Buttons int `yaml:"buttons"`
|
||||||
|
Axes int `yaml:"axes"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type RuleConfig struct {
|
type RuleConfig struct {
|
||||||
|
|
|
@ -10,13 +10,13 @@ import (
|
||||||
|
|
||||||
type EventBuffer struct {
|
type EventBuffer struct {
|
||||||
events []*evdev.InputEvent
|
events []*evdev.InputEvent
|
||||||
device *evdev.InputDevice
|
Device *evdev.InputDevice
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewEventBuffer(device *evdev.InputDevice) *EventBuffer {
|
func NewEventBuffer(device *evdev.InputDevice) *EventBuffer {
|
||||||
return &EventBuffer{
|
return &EventBuffer{
|
||||||
events: make([]*evdev.InputEvent, 0),
|
events: make([]*evdev.InputEvent, 0),
|
||||||
device: device,
|
Device: device,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,10 +29,10 @@ func (buffer *EventBuffer) SendEvents() {
|
||||||
|
|
||||||
for i := 0; i < len(buffer.events); i++ {
|
for i := 0; i < len(buffer.events); i++ {
|
||||||
buffer.events[i].Time = eventTime
|
buffer.events[i].Time = eventTime
|
||||||
buffer.device.WriteOne(buffer.events[i])
|
buffer.Device.WriteOne(buffer.events[i])
|
||||||
}
|
}
|
||||||
|
|
||||||
buffer.device.WriteOne(&evdev.InputEvent{
|
buffer.Device.WriteOne(&evdev.InputEvent{
|
||||||
Time: eventTime,
|
Time: eventTime,
|
||||||
Type: evdev.EV_SYN,
|
Type: evdev.EV_SYN,
|
||||||
Code: evdev.SYN_REPORT,
|
Code: evdev.SYN_REPORT,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue