use {AsRaw, Device, Event, FromRaw, Userdata, ffi};
use libc;
use std::{mem, ptr};
use std::ffi::CString;
use std::io::{Error as IoError, Result as IoResult};
use std::iter::Iterator;
use std::os::unix::io::RawFd;
pub type LibinputInterface = ffi::libinput_interface;
ffi_ref_struct!(
struct Libinput, ffi::libinput, ffi::libinput_ref, ffi::libinput_unref, ffi::libinput_get_user_data, ffi::libinput_set_user_data);
impl Iterator for Libinput {
type Item = Event;
fn next(&mut self) -> Option<Self::Item> {
let ptr = unsafe { ffi::libinput_get_event(self.as_raw_mut()) };
if ptr.is_null() {
None
} else {
unsafe { Some(Event::from_raw(ptr)) }
}
}
}
impl Libinput {
pub unsafe fn new_from_udev<T: 'static>(interface: LibinputInterface,
userdata: Option<T>,
udev_context: *mut libc::c_void)
-> Libinput {
let boxed_interface = Box::new(interface);
let mut boxed_userdata = Box::new(userdata);
let context = Libinput {
ffi: {
ffi::libinput_udev_create_context(&*boxed_interface as *const _,
match (*boxed_userdata).as_mut() {
Some(value) => value as *mut T as *mut libc::c_void,
None => ptr::null_mut(),
},
udev_context as *mut _)
},
};
mem::forget(boxed_interface);
mem::forget(boxed_userdata);
context
}
pub fn new_from_path<T: 'static>(interface: LibinputInterface, userdata: Option<T>) -> Libinput {
let boxed_interface = Box::new(interface);
let mut boxed_userdata = Box::new(userdata);
let context = Libinput {
ffi: unsafe {
ffi::libinput_path_create_context(&*boxed_interface as *const _,
match (*boxed_userdata).as_mut() {
Some(value) => value as *mut T as *mut libc::c_void,
None => ptr::null_mut(),
})
},
};
mem::forget(boxed_interface);
mem::forget(boxed_userdata);
context
}
pub fn path_add_device(&mut self, path: &str) -> Option<Device> {
let path = CString::new(path).expect("Device Path contained a null-byte");
unsafe {
let ptr = ffi::libinput_path_add_device(self.as_raw_mut(), path.as_ptr());
if ptr.is_null() {
None
} else {
Some(Device::from_raw(ptr))
}
}
}
pub fn path_remove_device(&mut self, device: Device) {
unsafe { ffi::libinput_path_remove_device(device.as_raw_mut()) }
}
pub fn udev_assign_seat(&mut self, seat_id: &str) -> Result<(), ()> {
let id = CString::new(seat_id).expect("Seat Id contained a null-byte");
unsafe {
match ffi::libinput_udev_assign_seat(self.as_raw_mut(), id.as_ptr()) {
0 => Ok(()),
-1 => Err(()),
_ => unreachable!(),
}
}
}
ffi_func!(
pub fn suspend, ffi::libinput_suspend, ());
pub fn resume(&mut self) -> Result<(), ()> {
unsafe {
match ffi::libinput_resume(self.as_raw_mut()) {
0 => Ok(()),
-1 => Err(()),
_ => unreachable!(),
}
}
}
pub fn dispatch(&mut self) -> IoResult<()> {
unsafe {
match ffi::libinput_dispatch(self.as_raw_mut()) {
0 => Ok(()),
x if x < 0 => Err(IoError::from_raw_os_error(x)),
_ => unreachable!(),
}
}
}
pub unsafe fn fd(&self) -> RawFd {
ffi::libinput_get_fd(self.as_raw_mut())
}
}