From 99be8e712bc87254e2232556b926523a536a3b46 Mon Sep 17 00:00:00 2001 From: Benjamin Dahlmanns Date: Thu, 29 Mar 2018 20:39:18 +0200 Subject: [PATCH] Add key press and key release functions for the mouse device Move todos to README --- README.md | 26 ++++++++++++------- TODO.md | 10 -------- uinput.go | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++ uinput_test.go | 20 +++++++++++++++ 4 files changed, 105 insertions(+), 19 deletions(-) delete mode 100644 TODO.md diff --git a/README.md b/README.md index 3657dc0..dfc640e 100644 --- a/README.md +++ b/README.md @@ -4,10 +4,13 @@ Uinput [![Build Status](https://travis-ci.org/bendahl/uinput.svg?branch=master)] This package provides pure go wrapper functions for the LINUX uinput device, which allows to create virtual input devices in userspace. At the moment this package offers a virtual keyboard implementation as well as a virtual mouse device and a touch pad device. + +\ The keyboard can be used to either send single key presses or hold down a specified key and release it later (useful for building game controllers). The mouse device issues relative positional change events to the x and y axis -of the mouse pointer and may also fire click events (left and right click). More functionality will be added in future -version. +of the mouse pointer and may also fire click events (left and right click). For implementing things like region selects +via a virtual mouse pointer, press and release functions for the mouse device are also included. + The touch pad, on the other hand can be used to move the mouse cursor to the specified position on the screen and to issue left and right clicks. Note that you'll need to specify the region size of your screen first though (happens during device creation). @@ -31,11 +34,16 @@ License -------- The package falls under the MIT license. Please see the "LICENSE" file for details. -ToDos ------------------- -All testing has been done on Ubunu 14.04 and 16.04 x86\_64. -Testing for other platforms will need to be done. -To get an idea of the things that are on the current todo list, check out the file "TODO.md". -As always, helpful comments and ideas are always welcome. -Feel free to do some testing on your own if you're up to it. +TODO +---- +Most functionality is implemented. However, more testing (including testing on different target +platforms) is definitely an area for improvement. + +- [x] Create Tests for the uinput package +- [x] Migrate code from C to GO +- [x] Implement relative input +- [x] Implement absolute input +- [ ] Test on different platforms (besides x86_64) +- [x] Implement functions to allow mouse button up and down events (for region selects) +- [ ] Extend test cases diff --git a/TODO.md b/TODO.md deleted file mode 100644 index b0f8544..0000000 --- a/TODO.md +++ /dev/null @@ -1,10 +0,0 @@ -TODO -==== - -1. ~~Create Tests for the uinput package~~ -2. ~~Migrate code from C to GO~~ -3. ~~Implement relative input~~ -4. ~~Implement absolute input~~ -5. Test on different platforms (besides x86_64) -6. Implement functions to allow mouse button up and down events (for region selects) -7. Extend test cases \ No newline at end of file diff --git a/uinput.go b/uinput.go index ae6d181..17574b4 100644 --- a/uinput.go +++ b/uinput.go @@ -127,6 +127,20 @@ type Mouse interface { // RightClick will issue a right click. RightClick() error + // LeftPress will simulate a press of the left mouse button. Note that the button will not be released until + // LeftRelease is invoked. + LeftPress() error + + // LeftRelease will simulate the release of the left mouse button. + LeftRelease() error + + // RightPress will simulate the press of the right mouse button. Note that the button will not be released until + // RightRelease is invoked. + RightPress() error + + // RightRelease will simulate the release of the right mouse button. + RightRelease() error + io.Closer } @@ -294,6 +308,60 @@ func (vRel vMouse) RightClick() error { return nil } +// LeftPress will simulate a press of the left mouse button. Note that the button will not be released until +// LeftRelease is invoked. +func (vRel vMouse) LeftPress() error { + err := sendBtnEvent(vRel.deviceFile, evBtnLeft, btnStatePressed) + if err != nil { + return fmt.Errorf("Failed press the left mouse button: %v", err) + } + err = syncEvents(vRel.deviceFile) + if err != nil { + return fmt.Errorf("sync to device file failed: %v", err) + } + return nil +} + +// LeftRelease will simulate the release of the left mouse button. +func (vRel vMouse) LeftRelease() error { + err := sendBtnEvent(vRel.deviceFile, evBtnLeft, btnStateReleased) + if err != nil { + return fmt.Errorf("Failed to release the left mouse button: %v", err) + } + err = syncEvents(vRel.deviceFile) + if err != nil { + return fmt.Errorf("sync to device file failed: %v", err) + } + return nil +} + +// RightPress will simulate the press of the right mouse button. Note that the button will not be released until +// RightRelease is invoked. +func (vRel vMouse) RightPress() error { + err := sendBtnEvent(vRel.deviceFile, evBtnRight, btnStatePressed) + if err != nil { + return fmt.Errorf("Failed to press the right mouse button: %v", err) + } + err = syncEvents(vRel.deviceFile) + if err != nil { + return fmt.Errorf("sync to device file failed: %v", err) + } + return nil +} + +// RightRelease will simulate the release of the right mouse button. +func (vRel vMouse) RightRelease() error { + err := sendBtnEvent(vRel.deviceFile, evBtnRight, btnStateReleased) + if err != nil { + return fmt.Errorf("Failed to release the right mouse button: %v", err) + } + err = syncEvents(vRel.deviceFile) + if err != nil { + return fmt.Errorf("sync to device file failed: %v", err) + } + return nil +} + // Close closes the device and releases the device. func (vRel vMouse) Close() error { return closeDevice(vRel.deviceFile) diff --git a/uinput_test.go b/uinput_test.go index 7817a92..de37d9e 100644 --- a/uinput_test.go +++ b/uinput_test.go @@ -81,6 +81,26 @@ func TestBasicMouseMoves(t *testing.T) { t.Fatalf("Failed to perform right click. Last error was: %s\n", err) } + err = relDev.LeftPress() + if err != nil { + t.Fatalf("Failed to perform left key press. Last error was: %s\n", err) + } + + err = relDev.LeftRelease() + if err != nil { + t.Fatalf("Failed to perform left key release. Last error was: %s\n", err) + } + + err = relDev.RightPress() + if err != nil { + t.Fatalf("Failed to perform right key press. Last error was: %s\n", err) + } + + err = relDev.RightRelease() + if err != nil { + t.Fatalf("Failed to perform right key release. Last error was: %s\n", err) + } + err = relDev.Close() if err != nil { t.Fatalf("Failed to close device. Last error was: %s\n", err)