package main import ( "flag" udev "github.com/farjump/go-libudev" "keyboard-reader/evdev" "log" "os" "time" ) const bufferLength = 32 func main() { device := flag.String("dev", "", "Keyboard device") vendor := flag.String("vendor", "", "Device vendor") model := flag.String("model", "", "Device id model") list := flag.Bool("list", false, "List input devices") nospace := flag.Bool("nospace", false, "Ignore spaces") connectorId := flag.Uint("connector", 0, "Connector id") wait := flag.Int("timeout", 5, "Http timeout, sec") url := flag.String("url", "http://localhost:8914/state/idTag", "Endpoint url") flag.Parse() if *list { if devs, err := getUdevEnumerate().Devices(); err != nil { log.Printf("Can't list devicies: %e", err) } else { for _, dev := range devs { log.Println(dev.Properties()) } } } if len(*vendor) == 0 && len(*device) == 0 && len(*model) == 0 && !*list { flag.Usage() } if len(*vendor) > 0 { device = getDevByProperty(*vendor, "ID_VENDOR") } if len(*model) > 0 { device = getDevByProperty(*model, "ID_MODEL") } if device == nil || len(*device) == 0 { log.Println("Keyboard device not selected") os.Exit(1) } var dev *evdev.InputDevice var events []evdev.InputEvent var err error // Open our argv as a device and a file, so we can get the file descriptor. if dev, err = evdev.Open(*device, bufferLength); err != nil { // If the device can't be opened, spit out an error and exit. log.Printf("Unable to open input device: %s\n", *device) os.Exit(1) } defer dev.Close() if err = dev.Grab(); err != nil { log.Printf("Can't grab input from device: %s, error: %e\n", *device, err) os.Exit(2) } defer dev.Release() client := NewRest(*connectorId, *url, time.Duration(*wait)*time.Second, *nospace) // Run an infinite loop. for { // Read the device events. if events, err = dev.Read(); err != nil { log.Printf("Can't read input from device: %s, error: %e\n", *device, err) os.Exit(3) } // Iterate through the events. for _, event := range events { if r, ok := event.GetKey(); ok { client.Send(r) } } } } func getDevByProperty(value string, property string) *string { e := getUdevEnumerate() e.AddMatchProperty(property, value) if devices, err := e.Devices(); err == nil { for _, item := range devices { if name, found := item.Properties()["DEVNAME"]; found { log.Printf("Found device by %s: %s\n", property, name) return &name } } } return nil } func getUdevEnumerate() *udev.Enumerate { // Create Udev and Enumerate u := udev.Udev{} e := u.NewEnumerate() e.AddMatchSysname("event*") return e }