diff --git a/keyboard.go b/keyboard.go index 98adb9a..9e45082 100644 --- a/keyboard.go +++ b/keyboard.go @@ -21,6 +21,9 @@ type Keyboard interface { // The key can be any of the predefined keycodes from keycodes.go. KeyUp(key int) error + // FetchSysPath will return the syspath to the device file. + FetchSyspath() (string, error) + io.Closer } @@ -123,3 +126,7 @@ func createVKeyboardDevice(path string, name []byte) (fd *os.File, err error) { func keyCodeInRange(key int) bool { return key >= keyReserved && key <= keyMax } + +func (vk vKeyboard) FetchSyspath() (string, error) { + return fetchSyspath(vk.deviceFile) +} diff --git a/keyboard_test.go b/keyboard_test.go index bf22605..8ad6c7f 100644 --- a/keyboard_test.go +++ b/keyboard_test.go @@ -188,3 +188,20 @@ func TestKeyDownFailsIfDeviceIsClosed(t *testing.T) { t.Fatalf("Expected KeyPress to fail, but no error was returned.") } } + +func TestKeyboardSyspath(t *testing.T) { + vk, err := CreateKeyboard("/dev/uinput", []byte("Test Basic Keyboard")) + if err != nil { + t.Fatalf("Failed to create the virtual keyboard. Last error was: %s\n", err) + } + + sysPath, err := vk.FetchSyspath() + if err != nil { + t.Fatalf("Failed to fetch syspath. Last error was: %s\n", err) + } + + if sysPath[:32] != "/sys/devices/virtual/input/input" { + t.Fatalf("Expected syspath to start with /sys/devices/virtual/input/input, but got %s", sysPath) + } + t.Logf("Syspath: %s", sysPath) +} diff --git a/mouse.go b/mouse.go index ec18485..846c37e 100644 --- a/mouse.go +++ b/mouse.go @@ -60,6 +60,9 @@ type Mouse interface { // Wheel will simulate a wheel movement. Wheel(horizontal bool, delta int32) error + // FetchSysPath will return the syspath to the device file. + FetchSyspath() (string, error) + io.Closer } @@ -282,3 +285,7 @@ func assertNotNegative(val int32) error { } return nil } + +func (vRel vMouse) FetchSyspath() (string, error) { + return fetchSyspath(vRel.deviceFile) +} diff --git a/mouse_test.go b/mouse_test.go index ff22871..24e3693 100644 --- a/mouse_test.go +++ b/mouse_test.go @@ -382,3 +382,20 @@ func TestMouseWheelFailsIfDeviceIsClosed(t *testing.T) { t.Fatalf("Expected error due to closed device, but no error was returned.") } } + +func TestMouseSyspath(t *testing.T) { + relDev, err := CreateMouse("/dev/uinput", []byte("Test Basic Mouse")) + if err != nil { + t.Fatalf("Failed to create the virtual mouse. Last error was: %s\n", err) + } + + sysPath, err := relDev.FetchSyspath() + if err != nil { + t.Fatalf("Failed to fetch syspath. Last error was: %s\n", err) + } + + if sysPath[:32] != "/sys/devices/virtual/input/input" { + t.Fatalf("Expected syspath to start with /sys/devices/virtual/input/input, but got %s", sysPath) + } + t.Logf("Syspath: %s", sysPath) +} diff --git a/touchpad.go b/touchpad.go index d60e186..4959233 100644 --- a/touchpad.go +++ b/touchpad.go @@ -39,6 +39,9 @@ type TouchPad interface { // TouchUp will end or ,more precisely, unset the touch event issued by TouchDown TouchUp() error + // FetchSysPath will return the syspath to the device file. + FetchSyspath() (string, error) + io.Closer } @@ -210,3 +213,7 @@ func sendAbsEvent(deviceFile *os.File, xPos int32, yPos int32) error { return syncEvents(deviceFile) } + +func (vTouch vTouchPad) FetchSyspath() (string, error) { + return fetchSyspath(vTouch.deviceFile) +} diff --git a/touchpad_test.go b/touchpad_test.go index e09d936..24b8012 100644 --- a/touchpad_test.go +++ b/touchpad_test.go @@ -234,3 +234,21 @@ func TestSingleTouchEvent(t *testing.T) { } } + +func TestTouchPadSyspath(t *testing.T) { + dev, err := CreateTouchPad("/dev/uinput", []byte("TouchPad"), 0, 1024, 0, 768) + if err != nil { + t.Fatalf("Failed to create the virtual touch pad. Last error was: %s\n", err) + } + + sysPath, err := dev.FetchSyspath() + if err != nil { + t.Fatalf("Failed to fetch syspath. Last error was: %s\n", err) + } + + if sysPath[:32] != "/sys/devices/virtual/input/input" { + t.Fatalf("Expected syspath to start with /sys/devices/virtual/input/input, but got %s", sysPath) + } + + t.Logf("Syspath: %s", sysPath) +} diff --git a/uinput.go b/uinput.go index a58d3d6..ec83a18 100644 --- a/uinput.go +++ b/uinput.go @@ -84,6 +84,7 @@ import ( "os" "syscall" "time" + "unsafe" ) func validateDevicePath(path string) error { @@ -168,6 +169,16 @@ func releaseDevice(deviceFile *os.File) (err error) { return ioctl(deviceFile, uiDevDestroy, uintptr(0)) } +func fetchSyspath(deviceFile *os.File) (string, error) { + sysInputDir := "/sys/devices/virtual/input/" + // 64 for name + 1 for null byte + path := make([]byte, 65) + err := ioctl(deviceFile, uiGetSysname, uintptr(unsafe.Pointer(&path[0]))) + + sysInputDir = sysInputDir + string(path) + return sysInputDir, err +} + // Note that mice and touch pads do have buttons as well. Therefore, this function is used // by all currently available devices and resides in the main source file. func sendBtnEvent(deviceFile *os.File, keys []int, btnState int) (err error) { diff --git a/uinputdefs.go b/uinputdefs.go index 3a8027a..686588c 100644 --- a/uinputdefs.go +++ b/uinputdefs.go @@ -7,11 +7,15 @@ const ( uinputMaxNameSize = 80 uiDevCreate = 0x5501 uiDevDestroy = 0x5502 - uiSetEvBit = 0x40045564 - uiSetKeyBit = 0x40045565 - uiSetRelBit = 0x40045566 - uiSetAbsBit = 0x40045567 - busUsb = 0x03 + // this is for 64 length buffer to store name + // for another length generate using : (len << 16) | 0x8000552C + uiGetSysname = 0x8041552c + uiSetEvBit = 0x40045564 + uiSetKeyBit = 0x40045565 + + uiSetRelBit = 0x40045566 + uiSetAbsBit = 0x40045567 + busUsb = 0x03 ) // input event codes as specified in input-event-codes.h