Update nix to 0.9, support FreeBSD

nix 0.9's ioctl macro works with buffers now.
This commit is contained in:
Greg V 2017-12-01 22:44:06 +03:00
parent 04761b788f
commit e5e7332952
4 changed files with 53 additions and 56 deletions

View file

@ -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 = []

View file

@ -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.

View file

@ -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(())

View file

@ -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))
}