2016-04-24 22:32:24 -04:00
|
|
|
use std::path::Path;
|
|
|
|
use std::{mem, slice};
|
|
|
|
use std::ffi::CString;
|
|
|
|
use libc::c_int;
|
2020-07-11 02:05:25 -04:00
|
|
|
use nix::{self, fcntl, unistd, errno::Errno, ioctl_write_ptr, ioctl_none};
|
2016-04-24 22:32:24 -04:00
|
|
|
use nix::sys::stat;
|
2020-07-11 02:05:25 -04:00
|
|
|
//use uinput_sys::*;
|
2019-09-29 23:49:23 -04:00
|
|
|
use crate::{Result as Res, Device};
|
2017-09-08 01:16:34 -04:00
|
|
|
use std::collections::hash_map::Values;
|
2020-07-11 02:05:25 -04:00
|
|
|
use std::os::raw::c_char;
|
|
|
|
|
|
|
|
use crate::linux::device::codes::*;
|
|
|
|
|
|
|
|
/*
|
|
|
|
uin!(write ui_set_evbit with b'U', 100; c_int);
|
|
|
|
uin!(write ui_set_keybit with b'U', 101; c_int);
|
|
|
|
|
|
|
|
ioctl!(none ui_dev_create with b'U', 1);
|
|
|
|
|
|
|
|
ioctl!(none ui_dev_destroy with b'U', 2);
|
|
|
|
*/
|
|
|
|
|
|
|
|
ioctl_write_ptr!(ui_set_evbit, b'U', 100, c_int);
|
|
|
|
ioctl_write_ptr!(ui_set_keybit, b'U', 101, c_int);
|
|
|
|
ioctl_none!(ui_dev_create, b'U', 1);
|
|
|
|
|
|
|
|
pub const UINPUT_MAX_NAME_SIZE: c_int = 80;
|
|
|
|
pub const ABS_MAX: c_int = 0x3f;
|
|
|
|
pub const ABS_CNT: c_int = ABS_MAX + 1;
|
|
|
|
|
|
|
|
#[derive(Clone, Copy)]
|
|
|
|
#[repr(C)]
|
|
|
|
pub struct input_id {
|
|
|
|
pub bustype: u16,
|
|
|
|
pub vendor: u16,
|
|
|
|
pub product: u16,
|
|
|
|
pub version: u16,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[repr(C)]
|
|
|
|
pub struct uinput_user_dev {
|
|
|
|
pub name: [c_char; UINPUT_MAX_NAME_SIZE as usize],
|
|
|
|
pub id: input_id,
|
|
|
|
|
|
|
|
pub ff_effects_max: u32,
|
|
|
|
pub absmax: [i32; ABS_CNT as usize],
|
|
|
|
pub absmin: [i32; ABS_CNT as usize],
|
|
|
|
pub absfuzz: [i32; ABS_CNT as usize],
|
|
|
|
pub absflat: [i32; ABS_CNT as usize],
|
|
|
|
}
|
2016-04-24 22:32:24 -04:00
|
|
|
|
2016-04-25 11:57:45 -04:00
|
|
|
/// Device builder.
|
2016-04-24 22:32:24 -04:00
|
|
|
pub struct Builder {
|
2016-04-25 11:57:45 -04:00
|
|
|
fd: c_int,
|
|
|
|
def: uinput_user_dev,
|
|
|
|
abs: Option<c_int>,
|
2016-04-24 22:32:24 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
impl Builder {
|
2016-04-25 11:57:45 -04:00
|
|
|
/// Create a builder from the specified path.
|
2016-04-24 22:32:24 -04:00
|
|
|
pub fn open<P: AsRef<Path>>(path: P) -> Res<Self> {
|
|
|
|
Ok(Builder {
|
2019-09-29 23:49:23 -04:00
|
|
|
fd: fcntl::open(path.as_ref(), fcntl::OFlag::O_WRONLY | fcntl::OFlag::O_NONBLOCK, stat::Mode::empty())?,
|
2016-04-25 11:57:45 -04:00
|
|
|
def: unsafe { mem::zeroed() },
|
|
|
|
abs: None,
|
2016-04-24 22:32:24 -04:00
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2016-04-25 11:57:45 -04:00
|
|
|
/// Create a builder from `/dev/uinput`.
|
2016-04-24 22:32:24 -04:00
|
|
|
pub fn default() -> Res<Self> {
|
|
|
|
Builder::open("/dev/uinput")
|
|
|
|
}
|
|
|
|
|
2016-04-25 11:57:45 -04:00
|
|
|
/// Set the name.
|
2016-04-24 22:32:24 -04:00
|
|
|
pub fn name<T: AsRef<str>>(mut self, value: T) -> Res<Self> {
|
2019-09-29 23:49:23 -04:00
|
|
|
let string = CString::new(value.as_ref())?;
|
2016-04-24 22:32:24 -04:00
|
|
|
let bytes = string.as_bytes_with_nul();
|
|
|
|
|
|
|
|
if bytes.len() > UINPUT_MAX_NAME_SIZE as usize {
|
2019-09-29 23:49:23 -04:00
|
|
|
Err(nix::Error::from_errno(Errno::EINVAL))?;
|
2016-04-24 22:32:24 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
(&mut self.def.name)[..bytes.len()]
|
|
|
|
.clone_from_slice(unsafe { mem::transmute(bytes) });
|
|
|
|
|
|
|
|
Ok(self)
|
|
|
|
}
|
|
|
|
|
2016-04-25 11:57:45 -04:00
|
|
|
/// Set the bus type.
|
2016-04-24 22:32:24 -04:00
|
|
|
pub fn bus(mut self, value: u16) -> Self {
|
|
|
|
self.def.id.bustype = value;
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2016-04-25 11:57:45 -04:00
|
|
|
/// Set the vendor ID.
|
2016-04-24 22:32:24 -04:00
|
|
|
pub fn vendor(mut self, value: u16) -> Self {
|
|
|
|
self.def.id.vendor = value;
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2016-04-25 11:57:45 -04:00
|
|
|
/// Set the product ID.
|
2016-04-24 22:32:24 -04:00
|
|
|
pub fn product(mut self, value: u16) -> Self {
|
|
|
|
self.def.id.product = value;
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2016-04-25 11:57:45 -04:00
|
|
|
/// Set the version.
|
2016-04-24 22:32:24 -04:00
|
|
|
pub fn version(mut self, value: u16) -> Self {
|
|
|
|
self.def.id.version = value;
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2019-10-06 13:51:01 -04:00
|
|
|
pub fn event(mut self, key_codes: Values<&str, u16>) -> Res<Self> {
|
2017-09-01 00:24:35 -04:00
|
|
|
self.abs = None;
|
2017-09-08 01:16:34 -04:00
|
|
|
//let test_ev_key : c_int = EV_KEY as c_int;
|
2017-09-01 00:24:35 -04:00
|
|
|
unsafe {
|
|
|
|
//try!(Errno::result(ui_set_evbit(self.fd, EV_KEY)));
|
|
|
|
//try!(Errno::result(ui_set_keybit(self.fd, KEY_H)));
|
2020-07-11 02:05:25 -04:00
|
|
|
|
|
|
|
//Errno::result(ui_set_evbit(self.fd, EV_KEY as *const c_int))?;
|
|
|
|
|
|
|
|
ui_set_evbit(self.fd, EV_KEY as *const c_int)?;
|
|
|
|
|
2017-09-08 01:16:34 -04:00
|
|
|
//ui_set_keybit(self.fd, KEY_H as *const c_int)?;
|
|
|
|
for key_code in key_codes {
|
2020-07-11 02:05:25 -04:00
|
|
|
ui_set_keybit(self.fd, *key_code as *const c_int)?;
|
2017-09-08 01:16:34 -04:00
|
|
|
}
|
2017-09-01 00:24:35 -04:00
|
|
|
//try!(ui_set_keybit(self.fd, &KEY_H));
|
|
|
|
}
|
|
|
|
Ok(self)
|
|
|
|
}
|
|
|
|
/*
|
2016-04-25 11:57:45 -04:00
|
|
|
/// Enable the given event.
|
2016-04-24 22:32:24 -04:00
|
|
|
pub fn event<T: Into<Event>>(mut self, value: T) -> Res<Self> {
|
2016-04-25 11:57:45 -04:00
|
|
|
self.abs = None;
|
|
|
|
|
2016-04-24 22:32:24 -04:00
|
|
|
match value.into() {
|
|
|
|
Event::All => {
|
2016-04-25 11:12:39 -04:00
|
|
|
try!(self.event(Event::Keyboard(event::Keyboard::All)))
|
|
|
|
.event(Event::Controller(event::Controller::All))
|
2016-04-24 22:32:24 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
Event::Keyboard(value) => {
|
|
|
|
match value {
|
|
|
|
event::Keyboard::All => {
|
|
|
|
let mut builder = self;
|
|
|
|
|
|
|
|
for item in event::keyboard::Key::iter_variants() {
|
|
|
|
builder = try!(builder.event(item));
|
|
|
|
}
|
|
|
|
|
|
|
|
for item in event::keyboard::KeyPad::iter_variants() {
|
|
|
|
builder = try!(builder.event(item));
|
|
|
|
}
|
|
|
|
|
|
|
|
for item in event::keyboard::Misc::iter_variants() {
|
|
|
|
builder = try!(builder.event(item));
|
|
|
|
}
|
|
|
|
|
|
|
|
for item in event::keyboard::InputAssist::iter_variants() {
|
|
|
|
builder = try!(builder.event(item));
|
|
|
|
}
|
|
|
|
|
|
|
|
for item in event::keyboard::Function::iter_variants() {
|
|
|
|
builder = try!(builder.event(item));
|
|
|
|
}
|
|
|
|
|
|
|
|
for item in event::keyboard::Braille::iter_variants() {
|
|
|
|
builder = try!(builder.event(item));
|
|
|
|
}
|
|
|
|
|
|
|
|
for item in event::keyboard::Numeric::iter_variants() {
|
|
|
|
builder = try!(builder.event(item));
|
|
|
|
}
|
|
|
|
|
|
|
|
for item in event::keyboard::TouchPad::iter_variants() {
|
|
|
|
builder = try!(builder.event(item));
|
|
|
|
}
|
|
|
|
|
|
|
|
for item in event::keyboard::Camera::iter_variants() {
|
|
|
|
builder = try!(builder.event(item));
|
|
|
|
}
|
|
|
|
|
|
|
|
for item in event::keyboard::Attendant::iter_variants() {
|
|
|
|
builder = try!(builder.event(item));
|
|
|
|
}
|
|
|
|
|
|
|
|
Ok(builder)
|
|
|
|
}
|
|
|
|
|
|
|
|
value => {
|
|
|
|
unsafe {
|
|
|
|
try!(Errno::result(ui_set_evbit(self.fd, value.kind())));
|
|
|
|
try!(Errno::result(ui_set_keybit(self.fd, value.code())));
|
|
|
|
}
|
|
|
|
|
|
|
|
Ok(self)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Event::Controller(value) => {
|
|
|
|
match value {
|
|
|
|
event::Controller::All => {
|
|
|
|
let mut builder = self;
|
|
|
|
|
|
|
|
for item in event::controller::Misc::iter_variants() {
|
|
|
|
builder = try!(builder.event(item));
|
|
|
|
}
|
|
|
|
|
|
|
|
for item in event::controller::Mouse::iter_variants() {
|
|
|
|
builder = try!(builder.event(item));
|
|
|
|
}
|
|
|
|
|
|
|
|
for item in event::controller::JoyStick::iter_variants() {
|
|
|
|
builder = try!(builder.event(item));
|
|
|
|
}
|
|
|
|
|
|
|
|
for item in event::controller::GamePad::iter_variants() {
|
|
|
|
builder = try!(builder.event(item));
|
|
|
|
}
|
|
|
|
|
|
|
|
for item in event::controller::Digi::iter_variants() {
|
|
|
|
builder = try!(builder.event(item));
|
|
|
|
}
|
|
|
|
|
|
|
|
for item in event::controller::Wheel::iter_variants() {
|
|
|
|
builder = try!(builder.event(item));
|
|
|
|
}
|
|
|
|
|
|
|
|
for item in event::controller::DPad::iter_variants() {
|
|
|
|
builder = try!(builder.event(item));
|
|
|
|
}
|
|
|
|
|
|
|
|
for item in event::controller::TriggerHappy::iter_variants() {
|
|
|
|
builder = try!(builder.event(item));
|
|
|
|
}
|
|
|
|
|
|
|
|
Ok(builder)
|
|
|
|
}
|
|
|
|
|
|
|
|
value => {
|
|
|
|
unsafe {
|
|
|
|
try!(Errno::result(ui_set_evbit(self.fd, value.kind())));
|
|
|
|
try!(Errno::result(ui_set_keybit(self.fd, value.code())));
|
|
|
|
}
|
|
|
|
|
|
|
|
Ok(self)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Event::Relative(value) => {
|
2016-04-25 11:12:39 -04:00
|
|
|
unsafe {
|
|
|
|
try!(Errno::result(ui_set_evbit(self.fd, value.kind())));
|
|
|
|
try!(Errno::result(ui_set_relbit(self.fd, value.code())));
|
2016-04-24 22:32:24 -04:00
|
|
|
}
|
2016-04-25 11:12:39 -04:00
|
|
|
|
|
|
|
Ok(self)
|
2016-04-24 22:32:24 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
Event::Absolute(value) => {
|
2016-04-25 11:12:39 -04:00
|
|
|
unsafe {
|
|
|
|
try!(Errno::result(ui_set_evbit(self.fd, value.kind())));
|
|
|
|
try!(Errno::result(ui_set_absbit(self.fd, value.code())));
|
|
|
|
}
|
2016-04-24 22:32:24 -04:00
|
|
|
|
2016-04-25 11:57:45 -04:00
|
|
|
self.abs = Some(value.code());
|
2016-04-24 22:32:24 -04:00
|
|
|
|
2016-04-25 11:12:39 -04:00
|
|
|
Ok(self)
|
2016-04-24 22:32:24 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2017-09-01 00:24:35 -04:00
|
|
|
*/
|
2016-04-25 11:57:45 -04:00
|
|
|
/// Set the maximum value for the previously enabled absolute event.
|
2016-04-24 22:32:24 -04:00
|
|
|
pub fn max(mut self, value: i32) -> Self {
|
2016-04-25 11:57:45 -04:00
|
|
|
self.def.absmax[self.abs.unwrap() as usize] = value;
|
2016-04-24 22:32:24 -04:00
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2016-04-25 11:57:45 -04:00
|
|
|
/// Set the minimum value for the previously enabled absolute event.
|
2016-04-24 22:32:24 -04:00
|
|
|
pub fn min(mut self, value: i32) -> Self {
|
2016-04-25 11:57:45 -04:00
|
|
|
self.def.absmin[self.abs.unwrap() as usize] = value;
|
2016-04-24 22:32:24 -04:00
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2016-04-25 11:57:45 -04:00
|
|
|
/// Set the fuzz value for the previously enabled absolute event.
|
2016-04-24 22:32:24 -04:00
|
|
|
pub fn fuzz(mut self, value: i32) -> Self {
|
2016-04-25 11:57:45 -04:00
|
|
|
self.def.absfuzz[self.abs.unwrap() as usize] = value;
|
2016-04-24 22:32:24 -04:00
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2016-04-25 11:57:45 -04:00
|
|
|
/// Set the flat value for the previously enabled absolute event.
|
2016-04-24 22:32:24 -04:00
|
|
|
pub fn flat(mut self, value: i32) -> Self {
|
2016-04-25 11:57:45 -04:00
|
|
|
self.def.absflat[self.abs.unwrap() as usize] = value;
|
2016-04-24 22:32:24 -04:00
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2016-04-25 11:57:45 -04:00
|
|
|
/// Create the defined device.
|
2016-04-24 22:32:24 -04:00
|
|
|
pub fn create(self) -> Res<Device> {
|
|
|
|
unsafe {
|
|
|
|
let ptr = &self.def as *const _ as *const u8;
|
|
|
|
let size = mem::size_of_val(&self.def);
|
|
|
|
|
2019-09-29 23:49:23 -04:00
|
|
|
unistd::write(self.fd, slice::from_raw_parts(ptr, size))?;
|
2017-09-01 00:24:35 -04:00
|
|
|
//todo: try!(Errno::result(ui_dev_create(self.fd)));
|
|
|
|
// try1: Errno::result(ui_dev_create(self.fd)).unwrap();
|
2020-07-11 02:05:25 -04:00
|
|
|
ui_dev_create(self.fd)?;
|
2016-04-24 22:32:24 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
Ok(Device::new(self.fd))
|
|
|
|
}
|
|
|
|
}
|