Update nix to 0.9, support FreeBSD
nix 0.9's ioctl macro works with buffers now.
This commit is contained in:
parent
04761b788f
commit
e5e7332952
4 changed files with 53 additions and 56 deletions
|
@ -12,7 +12,7 @@ bitflags = "0.8.2"
|
|||
libc = "0.2.22"
|
||||
fixedbitset = "0.1.6"
|
||||
num = "0.1.37"
|
||||
nix = "0.8.1"
|
||||
nix = "0.9.0"
|
||||
|
||||
[features]
|
||||
unstable = []
|
||||
|
|
12
README.md
12
README.md
|
@ -11,16 +11,18 @@ Nice(r) access to `evdev` devices.
|
|||
What is `evdev`?
|
||||
===================
|
||||
|
||||
`evdev` is the Linux kernel's generic input interface. This crate exposes
|
||||
access to these sorts of input devices. There is some trickery involved, so
|
||||
please read the crate documentation.
|
||||
`evdev` is the Linux kernel's generic input interface, also implemented by other
|
||||
kernels such as FreeBSD.
|
||||
|
||||
This crate exposes access to these sorts of input devices. There is some trickery
|
||||
involved, so please read the crate documentation.
|
||||
|
||||
What does this library support?
|
||||
===============================
|
||||
|
||||
This library exposes raw evdev events, but uses the Rust `Iterator` trait to
|
||||
do so, and will handle `SYN_DROPPED` events properly for the client. I try to
|
||||
match [libevdev](http://www.freedesktop.org/software/libevdev/doc/latest/)
|
||||
match [libevdev](https://www.freedesktop.org/software/libevdev/doc/latest/)
|
||||
closely, where possible.
|
||||
|
||||
Writing to devices is not yet supported (eg, turning LEDs on).
|
||||
|
@ -33,5 +35,5 @@ Example
|
|||
=======
|
||||
|
||||
See <examples/evtest.rs> for an example of using this library (which roughly
|
||||
corresponds to the userspace [evtest](http://cgit.freedesktop.org/evtest/)
|
||||
corresponds to the userspace [evtest](https://cgit.freedesktop.org/evtest/)
|
||||
tool.
|
||||
|
|
57
src/lib.rs
57
src/lib.rs
|
@ -31,7 +31,7 @@
|
|||
//! It is recommended that you dedicate a thread to processing input events, or use epoll with the
|
||||
//! fd returned by `Device::fd` to process events when they are ready.
|
||||
|
||||
#![cfg(any(target_os = "linux", target_os = "android"))]
|
||||
#![cfg(any(unix, target_os = "android"))]
|
||||
#![allow(non_camel_case_types)]
|
||||
|
||||
#[macro_use]
|
||||
|
@ -47,8 +47,8 @@ pub mod raw;
|
|||
use std::os::unix::io::*;
|
||||
use std::os::unix::ffi::*;
|
||||
use std::path::Path;
|
||||
use std::ffi::CString;
|
||||
use std::mem::size_of;
|
||||
use std::ffi::{CString, CStr};
|
||||
use std::mem::{size_of, transmute};
|
||||
use fixedbitset::FixedBitSet;
|
||||
use num::traits::WrappingSub;
|
||||
|
||||
|
@ -71,6 +71,21 @@ macro_rules! do_ioctl {
|
|||
}}
|
||||
}
|
||||
|
||||
macro_rules! do_ioctl_buf {
|
||||
($buf:ident, $name:ident, $fd:expr) => {
|
||||
unsafe {
|
||||
let blen = $buf.len();
|
||||
match ::raw::$name($fd, &mut $buf[..]) {
|
||||
Ok(len) if len >= 0 => {
|
||||
$buf[blen - 1] = 0;
|
||||
Some(CStr::from_ptr(&mut $buf[0] as *mut u8 as *mut _).to_owned())
|
||||
},
|
||||
_ => None
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bitflags! {
|
||||
/// Event types supported by the device.
|
||||
pub flags Types: u32 {
|
||||
|
@ -707,34 +722,14 @@ impl Device {
|
|||
|
||||
let mut bits: u32 = 0;
|
||||
let mut bits64: u64 = 0;
|
||||
let mut vec = Vec::with_capacity(256);
|
||||
let mut buf = [0u8; 256];
|
||||
|
||||
do_ioctl!(eviocgbit(fd, 0, 4, &mut bits as *mut u32 as *mut u8));
|
||||
dev.ty = Types::from_bits(bits).expect("evdev: unexpected type bits! report a bug");
|
||||
|
||||
let dev_len = do_ioctl!(eviocgname(fd, vec.as_mut_ptr(), 255));
|
||||
unsafe { vec.set_len(dev_len as usize - 1) };
|
||||
dev.name = CString::new(vec.clone()).unwrap();
|
||||
|
||||
match unsafe { eviocgphys(fd, vec.as_mut_ptr(), 255) } {
|
||||
Ok(phys_len) => {
|
||||
if phys_len > 0 {
|
||||
unsafe { vec.set_len(phys_len as usize - 1) };
|
||||
dev.phys = Some(CString::new(vec.clone()).unwrap());
|
||||
}
|
||||
},
|
||||
Err(_) => { /* not essential */ }
|
||||
}
|
||||
|
||||
match unsafe { eviocguniq(fd, vec.as_mut_ptr(), 255) } {
|
||||
Ok(uniq_len) => {
|
||||
if uniq_len > 0 {
|
||||
unsafe { vec.set_len(uniq_len as usize - 1) };
|
||||
dev.uniq = Some(CString::new(vec.clone()).unwrap());
|
||||
}
|
||||
},
|
||||
Err(_) => { /* not essential */ }
|
||||
}
|
||||
dev.name = do_ioctl_buf!(buf, eviocgname, fd).unwrap_or(CString::default());
|
||||
dev.phys = do_ioctl_buf!(buf, eviocgphys, fd);
|
||||
dev.uniq = do_ioctl_buf!(buf, eviocguniq, fd);
|
||||
|
||||
do_ioctl!(eviocgid(fd, &mut dev.id));
|
||||
let mut driver_version: i32 = 0;
|
||||
|
@ -744,7 +739,7 @@ impl Device {
|
|||
((driver_version >> 8) & 0xff) as u8,
|
||||
(driver_version & 0xff) as u8);
|
||||
|
||||
do_ioctl!(eviocgprop(fd, &mut bits as *mut u32 as *mut u8, 0x1f)); // FIXME: handle old kernel
|
||||
do_ioctl!(eviocgprop(fd, std::slice::from_raw_parts_mut(&mut bits as *mut u32 as *mut u8, 0x1f))); // FIXME: handle old kernel
|
||||
dev.props = Props::from_bits(bits).expect("evdev: unexpected prop bits! report a bug");
|
||||
|
||||
if dev.ty.contains(KEY) {
|
||||
|
@ -794,7 +789,7 @@ impl Device {
|
|||
/// If there is an error at any point, the state will not be synchronized completely.
|
||||
pub fn sync_state(&mut self) -> Result<(), Error> {
|
||||
if self.ty.contains(KEY) {
|
||||
do_ioctl!(eviocgkey(self.fd, self.state.key_vals.as_mut_slice().as_mut_ptr() as *mut u32 as *mut u8, self.state.key_vals.len()));
|
||||
do_ioctl!(eviocgkey(self.fd, transmute::<&mut [u32], &mut [u8]>(self.state.key_vals.as_mut_slice())));
|
||||
}
|
||||
if self.ty.contains(ABSOLUTE) {
|
||||
for idx in 0..0x28 {
|
||||
|
@ -806,10 +801,10 @@ impl Device {
|
|||
}
|
||||
}
|
||||
if self.ty.contains(SWITCH) {
|
||||
do_ioctl!(eviocgsw(self.fd, self.state.switch_vals.as_mut_slice().as_mut_ptr() as *mut u32 as *mut u8, self.state.switch_vals.len()));
|
||||
do_ioctl!(eviocgsw(self.fd, transmute::<&mut [u32], &mut [u8]>(self.state.switch_vals.as_mut_slice())));
|
||||
}
|
||||
if self.ty.contains(LED) {
|
||||
do_ioctl!(eviocgled(self.fd, self.state.led_vals.as_mut_slice().as_mut_ptr() as *mut u32 as *mut u8, self.state.led_vals.len()));
|
||||
do_ioctl!(eviocgled(self.fd, transmute::<&mut [u32], &mut [u8]>(self.state.led_vals.as_mut_slice())));
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
|
38
src/raw.rs
38
src/raw.rs
|
@ -3,12 +3,12 @@ ioctl!(read eviocgid with b'E', 0x02; /*struct*/ input_id);
|
|||
ioctl!(read eviocgkeycode with b'E', 0x04; [::libc::c_uint; 2]);
|
||||
ioctl!(read eviocgrep with b'E', 0x03; [::libc::c_uint; 2]);
|
||||
ioctl!(read eviocgversion with b'E', 0x01; ::libc::c_int);
|
||||
ioctl!(write eviocrmff with b'E', 0x81; ::libc::c_int);
|
||||
ioctl!(write_int eviocrmff with b'E', 0x81);
|
||||
// ioctl!(read eviocgkeycode_v2 with b'E', 0x04; /*struct*/ input_keymap_entry);
|
||||
// TODO #define EVIOCSFF _IOC ( _IOC_WRITE , 'E' , 0x80 , sizeof ( struct ff_effect ) )
|
||||
ioctl!(write eviocskeycode with b'E', 0x04; [::libc::c_uint; 2]);
|
||||
// ioctl!(write eviocskeycode_v2 with b'E', 0x04; /*struct*/ input_keymap_entry);
|
||||
ioctl!(write eviocsrep with b'E', 0x03; [::libc::c_uint; 2]);
|
||||
ioctl!(write_ptr eviocskeycode with b'E', 0x04; [::libc::c_uint; 2]);
|
||||
// ioctl!(write_int eviocskeycode_v2 with b'E', 0x04; /*struct*/ input_keymap_entry);
|
||||
ioctl!(write_ptr eviocsrep with b'E', 0x03; [::libc::c_uint; 2]);
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Copy, Clone)]
|
||||
|
@ -192,26 +192,26 @@ impl ::std::default::Default for ff_rumble_effect {
|
|||
fn default() -> Self { unsafe { ::std::mem::zeroed() } }
|
||||
}
|
||||
|
||||
ioctl!(read buf eviocgname with b'E', 0x06; u8);
|
||||
ioctl!(read buf eviocgphys with b'E', 0x07; u8);
|
||||
ioctl!(read buf eviocguniq with b'E', 0x08; u8);
|
||||
ioctl!(read buf eviocgprop with b'E', 0x09; u8);
|
||||
ioctl!(read buf eviocgmtslots with b'E', 0x0a; u8);
|
||||
ioctl!(read buf eviocgkey with b'E', 0x18; u8);
|
||||
ioctl!(read buf eviocgled with b'E', 0x19; u8);
|
||||
ioctl!(read buf eviocgsnd with b'E', 0x1a; u8);
|
||||
ioctl!(read buf eviocgsw with b'E', 0x1b; u8);
|
||||
ioctl!(read_buf eviocgname with b'E', 0x06; u8);
|
||||
ioctl!(read_buf eviocgphys with b'E', 0x07; u8);
|
||||
ioctl!(read_buf eviocguniq with b'E', 0x08; u8);
|
||||
ioctl!(read_buf eviocgprop with b'E', 0x09; u8);
|
||||
ioctl!(read_buf eviocgmtslots with b'E', 0x0a; u8);
|
||||
ioctl!(read_buf eviocgkey with b'E', 0x18; u8);
|
||||
ioctl!(read_buf eviocgled with b'E', 0x19; u8);
|
||||
ioctl!(read_buf eviocgsnd with b'E', 0x1a; u8);
|
||||
ioctl!(read_buf eviocgsw with b'E', 0x1b; u8);
|
||||
|
||||
ioctl!(write eviocsff with b'E', 0x80; ff_effect);
|
||||
ioctl!(write eviocgrab with b'E', 0x90; ::libc::c_int);
|
||||
ioctl!(write eviocrevoke with b'E', 0x91; ::libc::c_int);
|
||||
ioctl!(write eviocsclockid with b'E', 0xa0; ::libc::c_int);
|
||||
ioctl!(write_ptr eviocsff with b'E', 0x80; ff_effect);
|
||||
ioctl!(write_int eviocgrab with b'E', 0x90);
|
||||
ioctl!(write_int eviocrevoke with b'E', 0x91);
|
||||
ioctl!(write_int eviocsclockid with b'E', 0xa0);
|
||||
|
||||
pub unsafe fn eviocgbit(fd: ::libc::c_int, ev: u32, len: ::libc::c_int, buf: *mut u8) -> ::nix::Result<i32> {
|
||||
convert_ioctl_res!(::nix::sys::ioctl::ioctl(fd, ior!(b'E', 0x20 + ev, len) as ::libc::c_ulong, buf))
|
||||
convert_ioctl_res!(::nix::libc::ioctl(fd, ior!(b'E', 0x20 + ev, len) as ::libc::c_ulong, buf))
|
||||
}
|
||||
|
||||
pub unsafe fn eviocgabs(fd: ::libc::c_int, abs: u32, buf: *mut input_absinfo) -> ::nix::Result<i32> {
|
||||
convert_ioctl_res!(::nix::sys::ioctl::ioctl(fd, ior!(b'E', 0x40 + abs, ::std::mem::size_of::<input_absinfo>()) as ::libc::c_ulong, buf))
|
||||
convert_ioctl_res!(::nix::libc::ioctl(fd, ior!(b'E', 0x40 + abs, ::std::mem::size_of::<input_absinfo>()) as ::libc::c_ulong, buf))
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue