diff --git a/uinput.go b/uinput.go index d9f33ec..6546241 100644 --- a/uinput.go +++ b/uinput.go @@ -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() @@ -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) { diff --git a/uinput_test.go b/uinput_test.go index 8ba4165..3cc6229 100644 --- a/uinput_test.go +++ b/uinput_test.go @@ -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) } @@ -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() @@ -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") }