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  }