Fixes https://codeberg.org/annabunches/joyful/issues/2 Reviewed-on: #15 Co-authored-by: Anna Rose Wiggins <annabunches@gmail.com> Co-committed-by: Anna Rose Wiggins <annabunches@gmail.com>
130 lines
3.2 KiB
Go
130 lines
3.2 KiB
Go
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"slices"
|
|
|
|
// TODO: using config here feels like bad coupling... ButtonFromIndex might need a refactor / move
|
|
"git.annabunches.net/annabunches/joyful/internal/config"
|
|
"git.annabunches.net/annabunches/joyful/internal/logger"
|
|
"github.com/holoplot/go-evdev"
|
|
flag "github.com/spf13/pflag"
|
|
)
|
|
|
|
func isJoystickLike(device *evdev.InputDevice) bool {
|
|
types := device.CapableTypes()
|
|
if slices.Contains(types, evdev.EV_ABS) {
|
|
return true
|
|
}
|
|
|
|
if slices.Contains(types, evdev.EV_KEY) {
|
|
buttons := device.CapableEvents(evdev.EV_KEY)
|
|
|
|
for _, code := range config.ButtonFromIndex {
|
|
if slices.Contains(buttons, code) {
|
|
return true
|
|
}
|
|
}
|
|
}
|
|
|
|
return false
|
|
}
|
|
|
|
func printDevice(devPath evdev.InputPath) {
|
|
// Get the device
|
|
device, err := evdev.Open(devPath.Path)
|
|
if err != nil {
|
|
fmt.Printf("ERROR: Couldn't get data for device '%s'\n", devPath.Name)
|
|
return
|
|
}
|
|
|
|
// If the device doesn't support any joystick-shaped inputs, don't print it.
|
|
if !isJoystickLike(device) {
|
|
return
|
|
}
|
|
|
|
// Get metadata
|
|
// metadata := struct {
|
|
// uuid string
|
|
// vendor string
|
|
// product string
|
|
// version string
|
|
// }{}
|
|
|
|
// uuid, err := device.UniqueID()
|
|
// if err != nil {
|
|
// metadata.uuid = "unknown"
|
|
// } else {
|
|
// metadata.uuid = uuid
|
|
// }
|
|
|
|
// inputId, err := device.InputID()
|
|
// if err != nil {
|
|
// metadata.vendor = "unknown"
|
|
// metadata.product = "unknown"
|
|
// metadata.version = "unknown"
|
|
// } else {
|
|
// metadata.vendor = "0x" + strconv.FormatUint(uint64(inputId.Vendor), 16)
|
|
// metadata.product = "0x" + strconv.FormatUint(uint64(inputId.Product), 16)
|
|
// metadata.version = strconv.FormatUint(uint64(inputId.Version), 10)
|
|
// }
|
|
|
|
// Get axis info
|
|
var axisOutputs []string
|
|
absInfos, err := device.AbsInfos()
|
|
if err != nil {
|
|
axisOutputs = []string{"ERROR: Failed to get axis data"}
|
|
} else {
|
|
axisOutputs = make([]string, 0, len(absInfos))
|
|
for axisCode, info := range absInfos {
|
|
absStr := fmt.Sprintf("%s: %d - %d", evdev.ABSNames[axisCode], info.Minimum, info.Maximum)
|
|
axisOutputs = append(axisOutputs, absStr)
|
|
}
|
|
}
|
|
|
|
// Print everything
|
|
fmt.Printf("%s:\n", devPath.Path)
|
|
fmt.Printf("\tName:\t\t'%s'\n", devPath.Name)
|
|
// fmt.Printf("\tUUID:\t\t'%s'\n", metadata.uuid)
|
|
// fmt.Printf("\tVendor:\t\t'%s'\n", metadata.vendor)
|
|
// fmt.Printf("\tProduct:\t'%s'\n", metadata.product)
|
|
// fmt.Printf("\tVersion:\t'%s'\n", metadata.version)
|
|
if len(axisOutputs) > 0 {
|
|
fmt.Println("\tAxes:")
|
|
for _, str := range axisOutputs {
|
|
fmt.Printf("\t\t%s\n", str)
|
|
}
|
|
}
|
|
}
|
|
|
|
func printDeviceQuiet(devPath evdev.InputPath) {
|
|
// If it's not at least minimally joystick-shaped, skip.
|
|
// If we can't open the device, err on the side of printing it
|
|
// anyway
|
|
device, err := evdev.Open(devPath.Path)
|
|
if err != nil ||
|
|
!isJoystickLike(device) {
|
|
return
|
|
}
|
|
|
|
fmt.Printf("'%s': '%s'\n", devPath.Path, devPath.Name)
|
|
}
|
|
|
|
// TODO: it would be nice to be able to specify a device by name or device file and get axis info
|
|
// just for that device
|
|
func main() {
|
|
var quietFlag bool
|
|
flag.BoolVarP(&quietFlag, "quiet", "q", false, "Only print device names")
|
|
flag.Parse()
|
|
|
|
devices, err := evdev.ListDevicePaths()
|
|
logger.FatalIfError(err, "")
|
|
|
|
for _, device := range devices {
|
|
if quietFlag {
|
|
printDeviceQuiet(device)
|
|
} else {
|
|
printDevice(device)
|
|
}
|
|
}
|
|
}
|