github.com/holoplot/go-evdev@v0.0.0-20220721205823-d31c64b9d636/cmd/uinputtest/main.go (about) 1 package main 2 3 import ( 4 "fmt" 5 "io/ioutil" 6 "os" 7 "syscall" 8 "time" 9 10 "github.com/holoplot/go-evdev" 11 ) 12 13 func listDevices() { 14 basePath := "/dev/input" 15 16 files, err := ioutil.ReadDir(basePath) 17 if err != nil { 18 fmt.Printf("Cannot read /dev/input: %v\n", err) 19 return 20 } 21 22 for _, fileName := range files { 23 if fileName.IsDir() { 24 continue 25 } 26 27 full := fmt.Sprintf("%s/%s", basePath, fileName.Name()) 28 d, err := evdev.Open(full) 29 if err == nil { 30 name, _ := d.Name() 31 32 if err == nil { 33 fmt.Printf("%s:\t%s\n", d.Path(), name) 34 } 35 } 36 } 37 } 38 39 func cloneDevice(devicePath string) { 40 targetDev, err := evdev.Open(devicePath) 41 if err != nil { 42 fmt.Printf("failed to open target device for cloning: %s", err.Error()) 43 return 44 45 } 46 defer targetDev.Close() 47 48 clonedDev, err := evdev.CloneDevice("my-device-clone", targetDev) 49 if err != nil { 50 fmt.Printf("failed to clone device: %s", err.Error()) 51 return 52 } 53 defer clonedDev.Close() 54 55 moveMouse(clonedDev) 56 } 57 58 func createDevice() { 59 dev, err := evdev.CreateDevice( 60 "fake-device", 61 evdev.InputID{ 62 BusType: 0x03, 63 Vendor: 0x4711, 64 Product: 0x0816, 65 Version: 1, 66 }, 67 map[evdev.EvType][]evdev.EvCode{ 68 evdev.EV_KEY: { 69 evdev.BTN_LEFT, 70 evdev.BTN_RIGHT, 71 evdev.BTN_MIDDLE, 72 }, 73 evdev.EV_REL: { 74 evdev.REL_X, 75 evdev.REL_Y, 76 evdev.REL_WHEEL, 77 evdev.REL_HWHEEL, 78 }, 79 }, 80 ) 81 if err != nil { 82 fmt.Printf("failed to create device: %s", err.Error()) 83 return 84 } 85 // defer dev.Close() 86 87 moveMouse(dev) 88 } 89 90 func moveMouse(dev *evdev.InputDevice) { 91 fmt.Println("Moving the mouse...") 92 for i := 0; i < 400; i++ { 93 time.Sleep(10 * time.Millisecond) 94 95 evTime := syscall.NsecToTimeval(int64(time.Now().Nanosecond())) 96 97 if i < 100 { 98 dev.WriteOne(&evdev.InputEvent{ 99 Time: evTime, 100 Type: evdev.EV_REL, 101 Code: evdev.REL_X, 102 Value: 2, 103 }) 104 } else if i < 200 { 105 dev.WriteOne(&evdev.InputEvent{ 106 Time: evTime, 107 Type: evdev.EV_REL, 108 Code: evdev.REL_Y, 109 Value: 2, 110 }) 111 } else if i < 300 { 112 dev.WriteOne(&evdev.InputEvent{ 113 Time: evTime, 114 Type: evdev.EV_REL, 115 Code: evdev.REL_X, 116 Value: -2, 117 }) 118 } else { 119 dev.WriteOne(&evdev.InputEvent{ 120 Time: evTime, 121 Type: evdev.EV_REL, 122 Code: evdev.REL_Y, 123 Value: -2, 124 }) 125 } 126 127 dev.WriteOne(&evdev.InputEvent{ 128 Time: evTime, 129 Type: evdev.EV_SYN, 130 Code: evdev.SYN_REPORT, 131 Value: 0, 132 }) 133 } 134 135 fmt.Println("Done!") 136 } 137 138 func usage() { 139 fmt.Print("Create a new input device, or clone capabiliies from an existing one\n\n") 140 fmt.Printf("Usage: %s clone [input device]\n", os.Args[0]) 141 fmt.Printf(" %s create\n\n", os.Args[0]) 142 fmt.Printf("Available devices:\n") 143 144 listDevices() 145 } 146 147 func main() { 148 if len(os.Args) < 2 { 149 usage() 150 return 151 } 152 153 switch os.Args[1] { 154 case "clone": 155 if len(os.Args) < 3 { 156 usage() 157 return 158 } 159 160 cloneDevice(os.Args[2]) 161 162 case "create": 163 createDevice() 164 165 default: 166 usage() 167 } 168 }