Skip to content

Commit

Permalink
Merge branch 'ghthor-remove-invalid-file-descriptor-states'
Browse files Browse the repository at this point in the history
  • Loading branch information
Benjamin committed Oct 18, 2016
2 parents 1ab6dec + c70a206 commit 8d719cf
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 49 deletions.
67 changes: 29 additions & 38 deletions uinput.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,11 @@ example).
In order to use the virtual keyboard, you will need to follow these three steps:
1. Initialize the device
Example: vk := VKeyboard{}
err := vk.Create("/dev/uinput")
Example: vk, err := CreateKeyboard("/dev/uinput", "Virtual Keyboard")
2. Send Button events to the device
Example: err = vk.SendKeyPress(uinput.KEY_D)
err = vk.SendKeyRelease(uinput.KEY_D)
3. Close the device
Example: err = vk.Close()
Expand All @@ -25,58 +24,50 @@ package uinput
import "C"
import (
"errors"
"io"
"unsafe"
)

// VKeyboard represents a virtual keyboard device. There are several
// methods available to work with this virtual device. Devices can be
// created, receive events, and closed.
type VKeyboard struct {
// The Name of the uinput device. Will be trimmed to a Max Length of 80 bytes.
// If left blank the device will have a default name.
Name string
// A Keyboard is an key event output device. It is used to
// enable a program to simulate HID keyboard input events.
type Keyboard interface {
// SendKeyPress will send a keypress event to an existing keyboard device.
// The key can be any of the predefined keycodes from uinputdefs.
SendKeyPress(key int) error

id int
}
// SendKeyRelease will send a keyrelease event to an existing keyboard device.
// The key can be any of the predefined keycodes from uinputdefs.
SendKeyRelease(key int) error

// Create creates a new virtual keyboard device.
// Make sure to pass the correct path to the current system's
// uinput device (usually either "/dev/uinput" or "/dev/input/uinput".
func (vk *VKeyboard) Create(path string) (err error) {
vk.id = -1
var ret error
io.Closer
}

vk.id, ret = createVKeyboardDevice(path, vk.Name)
return ret
type vKeyboard struct {
name string
fd int
}

// SendKeyPress will send a keypress event to an existing keyboard device.
// The key can be any of the predefined keycodes from uinputdefs.
func (vk *VKeyboard) SendKeyPress(key int) (err error) {
if vk.id < 0 {
return errors.New("Keyboard not initialized. Sending keypress event failed.")
func CreateKeyboard(path, name string) (Keyboard, error) {
fd, err := createVKeyboardDevice(path, name)
if err != nil {
return nil, err
}

return sendBtnEvent(vk.id, key, 1)
return vKeyboard{name, fd}, nil
}

// SendKeyRelease will send a keyrelease event to an existing keyboard device.
// The key can be any of the predefined keycodes from uinputdefs.
func (vk *VKeyboard) SendKeyRelease(key int) (err error) {
if vk.id < 0 {
return errors.New("Keyboard not initialized. Sending keyrelease event failed.")
}
func (vk vKeyboard) SendKeyPress(key int) error {
return sendBtnEvent(vk.fd, key, 1)
}

return sendBtnEvent(vk.id, key, 0)
func (vk vKeyboard) SendKeyRelease(key int) error {
return sendBtnEvent(vk.fd, key, 0)
}

// Close will close the device and free resources.
// It's usually a good idea to use defer to call this function.
func (vk *VKeyboard) Close() (err error) {
if vk.id < 0 {
return errors.New("Keyboard not initialized. Closing device failed.")
}
return closeDevice(vk.id)
func (vk vKeyboard) Close() error {
return closeDevice(vk.fd)
}

func createVKeyboardDevice(path, name string) (deviceId int, err error) {
Expand Down
15 changes: 4 additions & 11 deletions uinput_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,8 @@ import (
)

// This test will create a basic VKeyboard, send a key command and then close the keyboard device
func TestBasicVKeyboard(t *testing.T) {
vk := VKeyboard{}
err := vk.Create("/dev/uinput")

func TestBasicKeyboard(t *testing.T) {
vk, err := CreateKeyboard("/dev/uinput", "Test Basic Keyboard")
if err != nil {
t.Fatalf("Failed to create the virtual keyboard. Last error was: %s\n", err)
}
Expand All @@ -35,9 +33,7 @@ func TestBasicVKeyboard(t *testing.T) {
// This test will confirm that a proper error code is returned if an invalid uinput path is
// passed to the library
func TestInvalidDevicePath(t *testing.T) {
vk := VKeyboard{}
err := vk.Create("/invalid/path")

vk, err := CreateKeyboard("/invalid/path", "Invalid Device Path")
if err == nil {
// this usually shouldn't happen, but if the device is created, we need to close it
vk.Close()
Expand All @@ -48,15 +44,12 @@ func TestInvalidDevicePath(t *testing.T) {
// This test will confirm that a proper error code is returned if an invalid keycode is
// passed to the library
func TestInvalidKeycode(t *testing.T) {
vk := VKeyboard{}
err := vk.Create("/dev/uinput")

vk, err := CreateKeyboard("/dev/uinput", "Test Keyboard")
if err != nil {
t.Fatalf("Failed to create the virtual keyboard. Last error was: %s\n", err)
}

err = vk.SendKeyPress(4711)

if err == nil {
t.Fatalf("Sending an invalid keycode did not trigger an error. Got: %d.\n")
}
Expand Down

0 comments on commit 8d719cf

Please sign in to comment.