*: add docs

This commit is contained in:
meh 2016-04-25 17:57:45 +02:00
parent 7d3f868cac
commit 0d4db8fe13
6 changed files with 99 additions and 11 deletions

39
README.md Normal file
View File

@ -0,0 +1,39 @@
uinput
======
`/dev/uinput` high level wrapper.
Example
-------
The following example writes `hello world`.
```rust
extern crate uinput;
use uinput::event::keyboard;
use std::thread;
use std::time::Duration;
fn main() {
let mut device = uinput::default().unwrap()
.name("test").unwrap()
.event(uinput::event::Keyboard::All).unwrap()
.create().unwrap();
thread::sleep(Duration::from_secs(1));
device.click(&keyboard::Key::H).unwrap();
device.click(&keyboard::Key::E).unwrap();
device.click(&keyboard::Key::L).unwrap();
device.click(&keyboard::Key::L).unwrap();
device.click(&keyboard::Key::O).unwrap();
device.click(&keyboard::Key::Space).unwrap();
device.click(&keyboard::Key::W).unwrap();
device.click(&keyboard::Key::O).unwrap();
device.click(&keyboard::Key::R).unwrap();
device.click(&keyboard::Key::L).unwrap();
device.click(&keyboard::Key::D).unwrap();
device.click(&keyboard::Key::Enter).unwrap();
device.synchronize().unwrap();
}
```

View File

@ -11,22 +11,25 @@ use event::{self, Kind, Code};
#[cfg(feature = "udev")] #[cfg(feature = "udev")]
use udev; use udev;
/// Device builder.
pub struct Builder { pub struct Builder {
fd: c_int, fd: c_int,
def: uinput_user_dev, def: uinput_user_dev,
code: c_int, abs: Option<c_int>,
} }
impl Builder { impl Builder {
/// Create a builder from the specified path.
pub fn open<P: AsRef<Path>>(path: P) -> Res<Self> { pub fn open<P: AsRef<Path>>(path: P) -> Res<Self> {
Ok(Builder { Ok(Builder {
fd: try!(fcntl::open(path.as_ref(), fcntl::O_WRONLY | fcntl::O_NONBLOCK, stat::Mode::empty())), fd: try!(fcntl::open(path.as_ref(), fcntl::O_WRONLY | fcntl::O_NONBLOCK, stat::Mode::empty())),
def: unsafe { mem::zeroed() }, def: unsafe { mem::zeroed() },
code: 0, abs: None,
}) })
} }
#[cfg(feature = "udev")] #[cfg(feature = "udev")]
/// Create a builder from the default path taken from udev.
pub fn default() -> Res<Self> { pub fn default() -> Res<Self> {
let context = try!(udev::Context::new()); let context = try!(udev::Context::new());
let mut enumerator = try!(udev::Enumerator::new(&context)); let mut enumerator = try!(udev::Enumerator::new(&context));
@ -41,10 +44,12 @@ impl Builder {
} }
#[cfg(not(feature = "udev"))] #[cfg(not(feature = "udev"))]
/// Create a builder from `/dev/uinput`.
pub fn default() -> Res<Self> { pub fn default() -> Res<Self> {
Builder::open("/dev/uinput") Builder::open("/dev/uinput")
} }
/// Set the name.
pub fn name<T: AsRef<str>>(mut self, value: T) -> Res<Self> { pub fn name<T: AsRef<str>>(mut self, value: T) -> Res<Self> {
let string = try!(CString::new(value.as_ref())); let string = try!(CString::new(value.as_ref()));
let bytes = string.as_bytes_with_nul(); let bytes = string.as_bytes_with_nul();
@ -59,27 +64,34 @@ impl Builder {
Ok(self) Ok(self)
} }
/// Set the bus type.
pub fn bus(mut self, value: u16) -> Self { pub fn bus(mut self, value: u16) -> Self {
self.def.id.bustype = value; self.def.id.bustype = value;
self self
} }
/// Set the vendor ID.
pub fn vendor(mut self, value: u16) -> Self { pub fn vendor(mut self, value: u16) -> Self {
self.def.id.vendor = value; self.def.id.vendor = value;
self self
} }
/// Set the product ID.
pub fn product(mut self, value: u16) -> Self { pub fn product(mut self, value: u16) -> Self {
self.def.id.product = value; self.def.id.product = value;
self self
} }
/// Set the version.
pub fn version(mut self, value: u16) -> Self { pub fn version(mut self, value: u16) -> Self {
self.def.id.version = value; self.def.id.version = value;
self self
} }
/// Enable the given event.
pub fn event<T: Into<Event>>(mut self, value: T) -> Res<Self> { pub fn event<T: Into<Event>>(mut self, value: T) -> Res<Self> {
self.abs = None;
match value.into() { match value.into() {
Event::All => { Event::All => {
try!(self.event(Event::Keyboard(event::Keyboard::All))) try!(self.event(Event::Keyboard(event::Keyboard::All)))
@ -211,33 +223,38 @@ impl Builder {
try!(Errno::result(ui_set_absbit(self.fd, value.code()))); try!(Errno::result(ui_set_absbit(self.fd, value.code())));
} }
self.code = value.code(); self.abs = Some(value.code());
Ok(self) Ok(self)
} }
} }
} }
/// Set the maximum value for the previously enabled absolute event.
pub fn max(mut self, value: i32) -> Self { pub fn max(mut self, value: i32) -> Self {
self.def.absmax[self.code as usize] = value; self.def.absmax[self.abs.unwrap() as usize] = value;
self self
} }
/// Set the minimum value for the previously enabled absolute event.
pub fn min(mut self, value: i32) -> Self { pub fn min(mut self, value: i32) -> Self {
self.def.absmin[self.code as usize] = value; self.def.absmin[self.abs.unwrap() as usize] = value;
self self
} }
/// Set the fuzz value for the previously enabled absolute event.
pub fn fuzz(mut self, value: i32) -> Self { pub fn fuzz(mut self, value: i32) -> Self {
self.def.absfuzz[self.code as usize] = value; self.def.absfuzz[self.abs.unwrap() as usize] = value;
self self
} }
/// Set the flat value for the previously enabled absolute event.
pub fn flat(mut self, value: i32) -> Self { pub fn flat(mut self, value: i32) -> Self {
self.def.absflat[self.code as usize] = value; self.def.absflat[self.abs.unwrap() as usize] = value;
self self
} }
/// Create the defined device.
pub fn create(self) -> Res<Device> { pub fn create(self) -> Res<Device> {
unsafe { unsafe {
let ptr = &self.def as *const _ as *const u8; let ptr = &self.def as *const _ as *const u8;

View File

@ -5,11 +5,13 @@ use nix::unistd;
use ffi::*; use ffi::*;
use {Result as Res, Error, Event, event}; use {Result as Res, Error, Event, event};
/// The virtual device.
pub struct Device { pub struct Device {
fd: c_int, fd: c_int,
} }
impl Device { impl Device {
/// Wrap a file descriptor in a `Device`.
pub fn new(fd: c_int) -> Self { pub fn new(fd: c_int) -> Self {
Device { Device {
fd: fd fd: fd
@ -36,18 +38,22 @@ impl Device {
Ok(()) Ok(())
} }
/// Synchronize the device.
pub fn synchronize(&mut self) -> Res<()> { pub fn synchronize(&mut self) -> Res<()> {
self.write(EV_SYN, SYN_REPORT, 0) self.write(EV_SYN, SYN_REPORT, 0)
} }
/// Send a press event.
pub fn press<T: event::Press>(&mut self, event: &T) -> Res<()> { pub fn press<T: event::Press>(&mut self, event: &T) -> Res<()> {
self.write(event.kind(), event.code(), 1) self.write(event.kind(), event.code(), 1)
} }
/// Send a release event.
pub fn release<T: event::Release>(&mut self, event: &T) -> Res<()> { pub fn release<T: event::Release>(&mut self, event: &T) -> Res<()> {
self.write(event.kind(), event.code(), 0) self.write(event.kind(), event.code(), 0)
} }
/// Send a press and release event.
pub fn click<T: event::Press + event::Release>(&mut self, event: &T) -> Res<()> { pub fn click<T: event::Press + event::Release>(&mut self, event: &T) -> Res<()> {
try!(self.press(event)); try!(self.press(event));
try!(self.release(event)); try!(self.release(event));
@ -55,6 +61,7 @@ impl Device {
Ok(()) Ok(())
} }
/// Send a relative or absolute positioning event.
pub fn position<T: event::Position>(&mut self, event: &T, value: i32) -> Res<()> { pub fn position<T: event::Position>(&mut self, event: &T, value: i32) -> Res<()> {
self.write(event.kind(), event.code(), value) self.write(event.kind(), event.code(), value)
} }

View File

@ -4,14 +4,20 @@ use nix;
#[cfg(feature = "udev")] #[cfg(feature = "udev")]
use udev; use udev;
/// UInput error.
#[derive(Debug)] #[derive(Debug)]
pub enum Error { pub enum Error {
/// System errors.
Nix(nix::Error), Nix(nix::Error),
/// Errors with internal nulls in names.
Nul(ffi::NulError), Nul(ffi::NulError),
#[cfg(feature = "udev")] #[cfg(feature = "udev")]
/// Errors coming from udev.
Udev(udev::Error), Udev(udev::Error),
/// The uinput file could not be found.
NotFound, NotFound,
} }

View File

@ -1,24 +1,41 @@
use libc::c_int; use libc::c_int;
/// Trait for event type.
pub trait Kind { pub trait Kind {
/// Get the event type.
fn kind(&self) -> c_int; fn kind(&self) -> c_int;
} }
/// Trait for event code.
pub trait Code { pub trait Code {
/// Get the event code.
fn code(&self) -> c_int; fn code(&self) -> c_int;
} }
/// Trait for events that support pressing (namely keys).
pub trait Press: Kind + Code { } pub trait Press: Kind + Code { }
/// Trait for events that support releasing (namely keys).
pub trait Release: Kind + Code { } pub trait Release: Kind + Code { }
/// Trait for events that support absolute or relative positioning.
pub trait Position: Kind + Code { } pub trait Position: Kind + Code { }
/// All supported events.
#[derive(Clone, Copy, PartialEq, Eq, Debug)] #[derive(Clone, Copy, PartialEq, Eq, Debug)]
pub enum Event { pub enum Event {
All, All,
/// Keyboard event.
Keyboard(Keyboard), Keyboard(Keyboard),
/// Controller event.
Controller(Controller), Controller(Controller),
/// Relative movement event.
Relative(Relative), Relative(Relative),
/// Absolute movement event.
Absolute(Absolute), Absolute(Absolute),
} }

View File

@ -29,10 +29,12 @@ pub use event::Event;
pub mod device; pub mod device;
pub use device::Device; pub use device::Device;
/// Open the default uinput device.
pub fn default() -> Result<device::Builder> { pub fn default() -> Result<device::Builder> {
device::Builder::default() device::Builder::default()
} }
/// Open the specified uinput device.
pub fn open<P: AsRef<Path>>(path: P) -> Result<device::Builder> { pub fn open<P: AsRef<Path>>(path: P) -> Result<device::Builder> {
device::Builder::open(path) device::Builder::open(path)
} }