diff --git a/go.mod b/go.mod index 6582f6b..f7c13dd 100644 --- a/go.mod +++ b/go.mod @@ -2,4 +2,7 @@ module git.annabunches.net/annabunches/joyful go 1.24.4 -require github.com/holoplot/go-evdev v0.0.0-20240306072622-217e18f17db1 +require ( + github.com/goccy/go-yaml v1.18.0 + github.com/holoplot/go-evdev v0.0.0-20240306072622-217e18f17db1 +) diff --git a/go.sum b/go.sum index 33d2d90..69c3bf7 100644 --- a/go.sum +++ b/go.sum @@ -1,2 +1,4 @@ +github.com/goccy/go-yaml v1.18.0 h1:8W7wMFS12Pcas7KU+VVkaiCng+kG8QiFeFwzFb+rwuw= +github.com/goccy/go-yaml v1.18.0/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA= github.com/holoplot/go-evdev v0.0.0-20240306072622-217e18f17db1 h1:92OsBIf5KB1Tatx+uUGOhah73jyNUrt7DmfDRXXJ5Xo= github.com/holoplot/go-evdev v0.0.0-20240306072622-217e18f17db1/go.mod h1:iHAf8OIncO2gcQ8XOjS7CMJ2aPbX2Bs0wl5pZyanEqk= diff --git a/internal/config/configparser.go b/internal/config/configparser.go new file mode 100644 index 0000000..7ad5388 --- /dev/null +++ b/internal/config/configparser.go @@ -0,0 +1,62 @@ +package config + +import ( + "fmt" + "os" + "path/filepath" + "strings" + + "git.annabunches.net/annabunches/joyful/internal/logger" + "github.com/goccy/go-yaml" +) + +type ConfigParser struct { + config Config + configFiles []string +} + +// Parse all the config files and store the config data for further use +func (parser *ConfigParser) Parse(directory string) { + // Find the config files in the directory + dirEntries, err := os.ReadDir(directory) + logger.FatalIfError(err, "Failed to read config directory") + + for _, file := range dirEntries { + name := file.Name() + if file.IsDir() || !(strings.HasSuffix(name, ".yaml") || strings.HasSuffix(name, ".yml")) { + continue + } + + filePath := filepath.Join(directory, name) + if strings.HasSuffix(filePath, ".yaml") || strings.HasSuffix(filePath, ".yml") { + parser.configFiles = append(parser.configFiles, filePath) + } + } + + rawData := parser.parseConfigFiles() + err = yaml.Unmarshal(rawData, &parser.config) + logger.FatalIfError(err, "Failed to parse config") +} + +// Open each config file and concatenate their contents +func (parser *ConfigParser) parseConfigFiles() []byte { + var rawData []byte + + for _, filePath := range parser.configFiles { + data, err := os.ReadFile(filePath) + if err != nil { + logger.LogIfError(err, fmt.Sprintf("Failed to read config file '%s'", filePath)) + continue + } + + rawData = append(rawData, data...) + rawData = append(rawData, '\n') + } + + if len(rawData) == 0 { + logger.Log("No config data found") + return nil + } + + return rawData +} diff --git a/internal/config/maps.go b/internal/config/maps.go new file mode 100644 index 0000000..962e631 --- /dev/null +++ b/internal/config/maps.go @@ -0,0 +1,70 @@ +package config + +import ( + "github.com/holoplot/go-evdev" +) + +var ( + EvCodeMap = map[string]evdev.EvCode{ + "ABS_X": evdev.ABS_X, + "ABS_Y": evdev.ABS_Y, + "ABS_Z": evdev.ABS_Z, + "ABS_RX": evdev.ABS_RX, + "ABS_RY": evdev.ABS_RY, + "ABS_RZ": evdev.ABS_RZ, + "ABS_THROTTLE": evdev.ABS_THROTTLE, + "ABS_WHEEL": evdev.ABS_WHEEL, + "BTN_TRIGGER": evdev.BTN_TRIGGER, + "BTN_THUMB": evdev.BTN_THUMB, + "BTN_THUMB2": evdev.BTN_THUMB2, + "BTN_TOP": evdev.BTN_TOP, + "BTN_TOP2": evdev.BTN_TOP2, + "BTN_PINKIE": evdev.BTN_PINKIE, + "BTN_BASE": evdev.BTN_BASE, + "BTN_BASE2": evdev.BTN_BASE2, + "BTN_BASE3": evdev.BTN_BASE3, + "BTN_BASE4": evdev.BTN_BASE4, + "BTN_BASE5": evdev.BTN_BASE5, + "BTN_BASE6": evdev.BTN_BASE6, + "BTN_TRIGGER_HAPPY1": evdev.BTN_TRIGGER_HAPPY1, + "BTN_TRIGGER_HAPPY2": evdev.BTN_TRIGGER_HAPPY2, + "BTN_TRIGGER_HAPPY3": evdev.BTN_TRIGGER_HAPPY3, + "BTN_TRIGGER_HAPPY4": evdev.BTN_TRIGGER_HAPPY4, + "BTN_TRIGGER_HAPPY5": evdev.BTN_TRIGGER_HAPPY5, + "BTN_TRIGGER_HAPPY6": evdev.BTN_TRIGGER_HAPPY6, + "BTN_TRIGGER_HAPPY7": evdev.BTN_TRIGGER_HAPPY7, + "BTN_TRIGGER_HAPPY8": evdev.BTN_TRIGGER_HAPPY8, + "BTN_TRIGGER_HAPPY9": evdev.BTN_TRIGGER_HAPPY9, + "BTN_TRIGGER_HAPPY10": evdev.BTN_TRIGGER_HAPPY10, + "BTN_TRIGGER_HAPPY11": evdev.BTN_TRIGGER_HAPPY11, + "BTN_TRIGGER_HAPPY12": evdev.BTN_TRIGGER_HAPPY12, + "BTN_TRIGGER_HAPPY13": evdev.BTN_TRIGGER_HAPPY13, + "BTN_TRIGGER_HAPPY14": evdev.BTN_TRIGGER_HAPPY14, + "BTN_TRIGGER_HAPPY15": evdev.BTN_TRIGGER_HAPPY15, + "BTN_TRIGGER_HAPPY16": evdev.BTN_TRIGGER_HAPPY16, + "BTN_TRIGGER_HAPPY17": evdev.BTN_TRIGGER_HAPPY17, + "BTN_TRIGGER_HAPPY18": evdev.BTN_TRIGGER_HAPPY18, + "BTN_TRIGGER_HAPPY19": evdev.BTN_TRIGGER_HAPPY19, + "BTN_TRIGGER_HAPPY20": evdev.BTN_TRIGGER_HAPPY20, + "BTN_TRIGGER_HAPPY21": evdev.BTN_TRIGGER_HAPPY21, + "BTN_TRIGGER_HAPPY22": evdev.BTN_TRIGGER_HAPPY22, + "BTN_TRIGGER_HAPPY23": evdev.BTN_TRIGGER_HAPPY23, + "BTN_TRIGGER_HAPPY24": evdev.BTN_TRIGGER_HAPPY24, + "BTN_TRIGGER_HAPPY25": evdev.BTN_TRIGGER_HAPPY25, + "BTN_TRIGGER_HAPPY26": evdev.BTN_TRIGGER_HAPPY26, + "BTN_TRIGGER_HAPPY27": evdev.BTN_TRIGGER_HAPPY27, + "BTN_TRIGGER_HAPPY28": evdev.BTN_TRIGGER_HAPPY28, + "BTN_TRIGGER_HAPPY29": evdev.BTN_TRIGGER_HAPPY29, + "BTN_TRIGGER_HAPPY30": evdev.BTN_TRIGGER_HAPPY30, + "BTN_TRIGGER_HAPPY31": evdev.BTN_TRIGGER_HAPPY31, + "BTN_TRIGGER_HAPPY32": evdev.BTN_TRIGGER_HAPPY32, + "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, + } +) diff --git a/internal/config/types.go b/internal/config/types.go new file mode 100644 index 0000000..b54c593 --- /dev/null +++ b/internal/config/types.go @@ -0,0 +1,41 @@ +package config + +type Config struct { + Devices DevicesConfig `yaml:"devices"` + Rules []RuleConfig `yaml:"rules"` +} + +type DevicesConfig struct { + Physical []PhysicalDeviceConfig `yaml:"physical"` + Virtual []VirtualDeviceConfig `yaml:"virtual"` +} + +type PhysicalDeviceConfig struct { + Name string `yaml:"name"` + Uuid string `yaml:"uuid"` +} + +type VirtualDeviceConfig struct { + NumButtons int `yaml:"num_buttons"` + NumAxes int `yaml:"num_axes"` +} + +type RuleConfig struct { + Type string `yaml:"type"` + Input RuleInputConfig `yaml:"input"` + Output RuleOutputConfig `yaml:"output"` +} + +type RuleInputConfig struct { + Device string `yaml:"device"` + Button string `yaml:"button,omitempty"` + Buttons []string `yaml:"buttons,omitempty"` + Axis string `yaml:"axis,omitempty"` + Inverted bool `yaml:"inverted,omitempty"` +} + +type RuleOutputConfig struct { + Device string `yaml:"device"` + Button string `yaml:"button,omitempty"` + Axis string `yaml:"axis,omitempty"` +}