use std::io;
use std::mem::{uninitialized, size_of};
use std::slice::from_raw_parts_mut;
use std::os::unix::io::{RawFd, AsRawFd};
use nix;
use sys;
use ::{InputId, EventKind, AbsoluteAxis, AbsoluteInfo};
use macros::convert_error;
use bitmask::Bitmask;
pub use sys::EV_VERSION;
pub struct EvdevHandle(RawFd);
impl EvdevHandle {
pub fn new<F: AsRawFd>(fd: &F) -> Self {
EvdevHandle(fd.as_raw_fd())
}
pub fn from_fd(fd: RawFd) -> Self {
EvdevHandle(fd)
}
pub fn read(&self, events: &mut [sys::input_event]) -> io::Result<usize> {
let events = unsafe { from_raw_parts_mut(events.as_mut_ptr() as *mut u8, size_of::<sys::input_event>() * events.len()) };
nix::unistd::read(self.0, events)
.map(|len| len / size_of::<sys::input_event>()).map_err(convert_error)
}
ioctl_impl! {
{
@get driver_version = ev_get_version -> i32
}
{
@get device_id = ev_get_id -> InputId
}
{
@get repeat_settings = ev_get_rep -> sys::repeat_settings
}
{
@set set_repeat_settings(&sys::repeat_settings) = ev_set_rep
}
{
@get keycode_legacy = ev_get_keycode -> [u32; 2]
}
{
@get keycode = ev_get_keycode_v2 -> sys::input_keymap_entry
}
{
@set set_keycode_legacy(&[u32; 2]) = ev_set_keycode
}
{
@set set_keycode(&sys::input_keymap_entry) = ev_set_keycode_v2
}
{
@get_str device_name, device_name_buf = ev_get_name
}
{
@get_str physical_location, physical_location_buf = ev_get_phys
}
{
@get_str unique_id, unique_id_buf = ev_get_uniq
}
{
@get_buf device_properties_raw(u8) = ev_get_prop
}
{
@get_buf key_state(u8) = ev_get_key
}
{
@get_buf led_state(u8) = ev_get_led
}
{
@get_buf sounds_state(u8) = ev_get_snd
}
{
@get_buf switch_state(u8) = ev_get_sw
}
{
@set send_force_feedback(&mut sys::ff_effect) = ev_send_ff
}
{
@set erase_force_feedback(i16) = ev_erase_ff
}
{
@get effects_count = ev_get_effects -> i32
}
}
pub fn device_properties(&self) -> io::Result<Bitmask<::InputProperty>> {
let mut bitmask = Bitmask::default();
self.device_properties_raw(&mut bitmask).map(|_| bitmask)
}
pub fn multi_touch_slots(&self, code: AbsoluteAxis, values: &mut [i32]) -> io::Result<()> {
let input_len = values.len() + 1;
let mut buf = Vec::<i32>::with_capacity(input_len);
unsafe {
buf.set_len(input_len);
buf[0] = code as _;
let ptr = from_raw_parts_mut(buf.as_mut_ptr(), values.len()) as *mut _;
sys::ev_get_mtslots(self.0, ptr as *mut sys::input_mt_request_layout<[i32]>)
.map_err(convert_error)?;
}
values.copy_from_slice(&buf[1..]);
Ok(())
}
impl_bitmasks! { EventKind, EventKind::Synchronize,
event_mask_events, set_event_mask_events,
event_bits
}
impl_bitmasks! { ::Key, EventKind::Key,
key_mask, set_key_mask,
key_bits
}
impl_bitmasks! { ::RelativeAxis, EventKind::Relative,
relative_mask, set_relative_mask,
relative_bits
}
impl_bitmasks! { ::AbsoluteAxis, EventKind::Absolute,
absolute_mask, set_absolute_mask,
absolute_bits
}
impl_bitmasks! { ::MiscKind, EventKind::Misc,
misc_mask, set_misc_mask,
misc_bits
}
impl_bitmasks! { ::SwitchKind, EventKind::Switch,
switch_mask, set_switch_mask,
switch_bits
}
impl_bitmasks! { ::LedKind, EventKind::Led,
led_mask, set_led_mask,
led_bits
}
impl_bitmasks! { ::SoundKind, EventKind::Sound,
sound_mask, set_sound_mask,
sound_bits
}
impl_bitmasks! { ::AutorepeatKind, EventKind::Autorepeat,
autorepeat_mask, set_autorepeat_mask,
autorepeat_bits
}
pub fn event_mask_raw(&self, kind: EventKind, buffer: &mut [u8]) -> io::Result<()> {
unsafe {
let mut mask = sys::input_mask {
type_: kind as _,
codes_size: buffer.len() as _,
codes_ptr: buffer.as_mut_ptr() as usize as _,
};
sys::ev_get_mask(self.0, &mut mask)
.map(drop)
.map_err(convert_error)
}
}
pub fn set_event_mask_raw(&self, kind: EventKind, buffer: &[u8]) -> io::Result<()> {
unsafe {
let mask = sys::input_mask {
type_: kind as _,
codes_size: buffer.len() as _,
codes_ptr: buffer.as_ptr() as usize as _,
};
sys::ev_set_mask(self.0, &mask)
.map(drop)
.map_err(convert_error)
}
}
pub fn event_bits_raw(&self, kind: EventKind, buffer: &mut [u8]) -> io::Result<usize> {
unsafe {
sys::ev_get_bit(self.0, kind as _, buffer)
.map(|i| i as _)
.map_err(convert_error)
}
}
pub fn absolute_info(&self, abs: AbsoluteAxis) -> io::Result<AbsoluteInfo> {
unsafe {
let mut info = uninitialized();
sys::ev_get_abs(self.0, abs as _, &mut info)
.map(|_| info.into())
.map_err(convert_error)
}
}
pub fn set_absolute_info(&self, abs: AbsoluteAxis, info: &AbsoluteInfo) -> io::Result<()> {
unsafe {
let info: &sys::input_absinfo = info.into();
sys::ev_set_abs(self.0, abs as _, info)
.map(drop)
.map_err(convert_error)
}
}
pub fn grab(&self, grab: bool) -> io::Result<()> {
unsafe {
sys::ev_grab(self.0, if grab { 1 } else { 0 })
.map(drop)
.map_err(convert_error)
}
}
pub fn revoke(&self) -> io::Result<()> {
unsafe {
sys::ev_revoke(self.0, 0)
.map(drop)
.map_err(convert_error)
}
}
pub fn set_clock_id(&self, value: i32) -> io::Result<()> {
unsafe {
sys::ev_set_clockid(self.0, &value)
.map(drop)
.map_err(convert_error)
}
}
}