github.com/holoplot/go-evdev@v0.0.0-20220721205823-d31c64b9d636/cmd/evtest/main.go (about) 1 package main 2 3 import ( 4 "fmt" 5 "io/ioutil" 6 "os" 7 8 "github.com/holoplot/go-evdev" 9 ) 10 11 func listDevices() { 12 basePath := "/dev/input" 13 14 files, err := ioutil.ReadDir(basePath) 15 if err != nil { 16 fmt.Printf("Cannot read /dev/input: %v\n", err) 17 return 18 } 19 20 for _, fileName := range files { 21 if fileName.IsDir() { 22 continue 23 } 24 25 full := fmt.Sprintf("%s/%s", basePath, fileName.Name()) 26 d, err := evdev.Open(full) 27 if err == nil { 28 name, _ := d.Name() 29 30 if err == nil { 31 fmt.Printf("%s:\t%s\n", d.Path(), name) 32 } 33 } 34 } 35 } 36 37 func main() { 38 if len(os.Args) < 2 { 39 fmt.Printf("Usage: %s <input device>\n\n", os.Args[0]) 40 fmt.Printf("Available devices:\n") 41 42 listDevices() 43 return 44 } 45 46 d, err := evdev.Open(os.Args[1]) 47 if err != nil { 48 fmt.Printf("Cannot read %s: %v\n", os.Args[1], err) 49 return 50 } 51 52 vMajor, vMinor, vMicro := d.DriverVersion() 53 fmt.Printf("Input driver version is %d.%d.%d\n", vMajor, vMinor, vMicro) 54 55 inputID, err := d.InputID() 56 if err == nil { 57 fmt.Printf("Input device ID: bus 0x%x vendor 0x%x product 0x%x version 0x%x\n", 58 inputID.BusType, inputID.Vendor, inputID.Product, inputID.Version) 59 } 60 61 name, err := d.Name() 62 if err == nil { 63 fmt.Printf("Input device name: \"%s\"\n", name) 64 } 65 66 phys, err := d.PhysicalLocation() 67 if err == nil { 68 fmt.Printf("Input device physical location: %s\n", phys) 69 } 70 71 uniq, err := d.UniqueID() 72 if err == nil { 73 fmt.Printf("Input device unique ID: %s\n", uniq) 74 } 75 76 fmt.Printf("Supported events:\n") 77 78 for _, t := range d.CapableTypes() { 79 fmt.Printf(" Event type %d (%s)\n", t, evdev.TypeName(t)) 80 81 state, err := d.State(t) 82 if err == nil { 83 for code, value := range state { 84 fmt.Printf(" Event code %d (%s) state %v\n", code, evdev.CodeName(t, code), value) 85 } 86 } 87 88 if t != evdev.EV_ABS { 89 continue 90 } 91 92 absInfos, err := d.AbsInfos() 93 if err != nil { 94 continue 95 } 96 97 for code, absInfo := range absInfos { 98 fmt.Printf(" Event code %d (%s)\n", code, evdev.CodeName(t, code)) 99 fmt.Printf(" Value: %d\n", absInfo.Value) 100 fmt.Printf(" Min: %d\n", absInfo.Minimum) 101 fmt.Printf(" Max: %d\n", absInfo.Maximum) 102 103 if absInfo.Fuzz != 0 { 104 fmt.Printf(" Fuzz: %d\n", absInfo.Fuzz) 105 } 106 if absInfo.Flat != 0 { 107 fmt.Printf(" Flat: %d\n", absInfo.Flat) 108 } 109 if absInfo.Resolution != 0 { 110 fmt.Printf(" Resolution: %d\n", absInfo.Resolution) 111 } 112 } 113 } 114 115 fmt.Printf("Properties:\n") 116 117 props := d.Properties() 118 119 for _, p := range props { 120 fmt.Printf(" Property type %d (%s)\n", p, evdev.PropName(p)) 121 } 122 123 fmt.Printf("Testing ... (interrupt to exit)\n") 124 125 for { 126 e, err := d.ReadOne() 127 if err != nil { 128 fmt.Printf("Error reading from device: %v\n", err) 129 return 130 } 131 132 ts := fmt.Sprintf("Event: time %d.%06d", e.Time.Sec, e.Time.Usec) 133 134 switch e.Type { 135 case evdev.EV_SYN: 136 switch e.Code { 137 case evdev.SYN_MT_REPORT: 138 fmt.Printf("%s, ++++++++++++++ %s ++++++++++++\n", ts, e.CodeName()) 139 case evdev.SYN_DROPPED: 140 fmt.Printf("%s, >>>>>>>>>>>>>> %s <<<<<<<<<<<<\n", ts, e.CodeName()) 141 default: 142 fmt.Printf("%s, -------------- %s ------------\n", ts, e.CodeName()) 143 } 144 default: 145 fmt.Printf("%s, %s\n", ts, e.String()) 146 } 147 } 148 }