diff options
Diffstat (limited to 'hid/src')
-rw-r--r-- | hid/src/device.rs | 122 | ||||
-rw-r--r-- | hid/src/devices.rs | 51 | ||||
-rw-r--r-- | hid/src/error.rs | 62 | ||||
-rw-r--r-- | hid/src/handle.rs | 224 | ||||
-rw-r--r-- | hid/src/lib.rs | 17 | ||||
-rw-r--r-- | hid/src/manager.rs | 56 |
6 files changed, 0 insertions, 532 deletions
diff --git a/hid/src/device.rs b/hid/src/device.rs deleted file mode 100644 index dc718c7..0000000 --- a/hid/src/device.rs +++ /dev/null @@ -1,122 +0,0 @@ -use std::marker::PhantomData; -use std::path::Path; -use std::ffi::CStr; - -use sys::*; -use libc::{size_t, wchar_t, wcstombs}; -use handle::Handle; -use error::{self, Error}; - -/// The HID device. -pub struct Device<'a> { - ptr: *const hid_device_info, - - _marker: PhantomData<&'a ()>, -} - -impl<'a> Device<'a> { - #[doc(hidden)] - pub unsafe fn new<'b>(ptr: *const hid_device_info) -> Device<'b> { - Device { - ptr: ptr, - - _marker: PhantomData, - } - } - - /// The path representation. - pub fn path(&self) -> &Path { - unsafe { - Path::new(CStr::from_ptr((*self.ptr).path).to_str().unwrap()) - } - } - - /// The vendor ID. - pub fn vendor_id(&self) -> u16 { - unsafe { - (*self.ptr).vendor_id - } - } - - /// The product ID. - pub fn product_id(&self) -> u16 { - unsafe { - (*self.ptr).product_id - } - } - - /// The serial number. - pub fn serial_number(&self) -> Option<String> { - unsafe { - (*self.ptr).serial_number.as_ref().and_then(|p| to_string(p)) - } - } - - /// The manufacturer string. - pub fn manufacturer_string(&self) -> Option<String> { - unsafe { - (*self.ptr).manufacturer_string.as_ref().and_then(|p| to_string(p)) - } - } - - /// The product string. - pub fn product_string(&self) -> Option<String> { - unsafe { - (*self.ptr).product_string.as_ref().and_then(|p| to_string(p)) - } - } - - /// The release number. - pub fn release_number(&self) -> u16 { - unsafe { - (*self.ptr).release_number - } - } - - /// The usage page. - pub fn usage_page(&self) -> u16 { - unsafe { - (*self.ptr).usage_page - } - } - - /// The usage number. - pub fn usage(&self) -> u16 { - unsafe { - (*self.ptr).usage - } - } - - /// The interface number. - pub fn interface_number(&self) -> isize { - unsafe { - (*self.ptr).interface_number as isize - } - } - - /// Opens the device to use it. - pub fn open(&self) -> error::Result<Handle> { - unsafe { - let handle = hid_open((*self.ptr).vendor_id, (*self.ptr).product_id, (*self.ptr).serial_number); - - if handle.is_null() { - return Err(Error::NotFound); - } - - Ok(Handle::new(handle)) - } - } -} - -#[inline] -unsafe fn to_string(value: *const wchar_t) -> Option<String> { - // USB descriptors are limited to 255 bytes. - let mut buffer = [0u8; 256]; - let length = wcstombs(buffer.as_mut_ptr() as *mut _, value, buffer.len()); - - if length == size_t::max_value() { - return None; - } - - Some(String::from_utf8_lossy(&buffer[0.. length as usize]).into_owned()) -} diff --git a/hid/src/devices.rs b/hid/src/devices.rs deleted file mode 100644 index 002ffa9..0000000 --- a/hid/src/devices.rs +++ /dev/null @@ -1,51 +0,0 @@ -use std::marker::PhantomData; - -use sys::*; -use Device; - -/// An iterator over the available devices. -pub struct Devices<'a> { - ptr: *mut hid_device_info, - cur: *mut hid_device_info, - - _marker: PhantomData<&'a ()>, -} - -impl<'a> Devices<'a> { - #[doc(hidden)] - pub unsafe fn new(vendor: Option<u16>, product: Option<u16>) -> Self { - let list = hid_enumerate(vendor.unwrap_or(0), product.unwrap_or(0)); - - Devices { - ptr: list, - cur: list, - - _marker: PhantomData, - } - } -} - -impl<'a> Iterator for Devices<'a> { - type Item = Device<'a>; - - fn next(&mut self) -> Option<Self::Item> { - if self.cur.is_null() { - return None; - } - - unsafe { - let info = Device::new(self.cur); - self.cur = (*self.cur).next; - - Some(info) - } - } -} - -impl<'a> Drop for Devices<'a> { - fn drop(&mut self) { - unsafe { - hid_free_enumeration(self.ptr); - } - } -} diff --git a/hid/src/error.rs b/hid/src/error.rs deleted file mode 100644 index 367f47f..0000000 --- a/hid/src/error.rs +++ /dev/null @@ -1,62 +0,0 @@ -use std::ffi::CStr; -use libc::c_int; -use sys::*; -use std::{error, fmt}; - -#[derive(Clone, PartialEq, Eq, Debug)] -pub enum Error { - Initialized, - NotFound, - General, - Write, - Read, - String(String), -} - -pub type Result<T> = ::std::result::Result<T, Error>; - -impl From<c_int> for Error { - fn from(value: c_int) -> Error { - match value { - _ => Error::General - } - } -} - -impl From<*mut hid_device> for Error { - fn from(value: *mut hid_device) -> Error { - unsafe { - Error::String(CStr::from_ptr(hid_error(value) as *const _).to_str().unwrap().to_owned()) - } - } -} - -impl fmt::Display for Error { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - f.write_str(error::Error::description(self)) - } -} - -impl error::Error for Error { - fn description(&self) -> &str { - match *self { - Error::Initialized => - "Already initialized.", - - Error::NotFound => - "Device not found.", - - Error::General => - "General error.", - - Error::Write => - "Write error.", - - Error::Read => - "Read error.", - - Error::String(ref err) => - err, - } - } -} diff --git a/hid/src/handle.rs b/hid/src/handle.rs deleted file mode 100644 index d0eb090..0000000 --- a/hid/src/handle.rs +++ /dev/null @@ -1,224 +0,0 @@ -use std::time::Duration; - -use libc::c_int; -use sys::*; -use error::{self, Error}; - -/// A device handle. -pub struct Handle { - ptr: *mut hid_device, -} - -impl Handle { - #[doc(hidden)] - pub unsafe fn new(ptr: *mut hid_device) -> Self { - Handle { - ptr: ptr, - } - } - - #[doc(hidden)] - pub unsafe fn as_ptr(&self) -> *const hid_device { - self.ptr as *const _ - } - - #[doc(hidden)] - pub unsafe fn as_mut_ptr(&mut self) -> *mut hid_device { - self.ptr - } -} - -impl Handle { - /// Set the handle in blocking or non-blocking mode. - pub fn blocking(&mut self, value: bool) -> error::Result<&mut Self> { - unsafe { - match hid_set_nonblocking(self.as_mut_ptr(), if value { 1 } else { 0 }) { - 0 => - Ok(self), - - _ => - Err(Error::General) - } - } - } - - /// The data accessor. - pub fn data(&mut self) -> Data { - unsafe { - Data::new(self) - } - } - - /// The feature accessor. - pub fn feature(&mut self) -> Feature { - unsafe { - Feature::new(self) - } - } -} - -/// The data accessor. -pub struct Data<'a> { - handle: &'a mut Handle, -} - -impl<'a> Data<'a> { - #[doc(hidden)] - pub unsafe fn new(handle: &mut Handle) -> Data { - Data { handle: handle } - } - - /// Write data to the device. - /// - /// The first byte must be the report ID. - pub fn write<T: AsRef<[u8]>>(&mut self, data: T) -> error::Result<usize> { - let data = data.as_ref(); - - unsafe { - match hid_write(self.handle.as_mut_ptr(), data.as_ptr(), data.len()) { - -1 => - Err(Error::Write), - - length => - Ok(length as usize) - } - } - } - - /// Write data to the device with the given report ID. - pub fn write_to<T: AsRef<[u8]>>(&mut self, id: u8, data: T) -> error::Result<usize> { - let data = data.as_ref(); - let mut buffer = vec![0u8; data.len() + 1]; - - buffer[0] = id; - (&mut buffer[1 ..]).copy_from_slice(data); - - self.write(&buffer) - } - - /// Read data from the device. - /// - /// If the device supports reports the first byte will contain the report ID. - /// - /// Returns the amount of read bytes or `None` if there was a timeout. - pub fn read<T: AsMut<[u8]>>(&mut self, mut data: T, timeout: Duration) -> error::Result<Option<usize>> { - let data = data.as_mut(); - let result = if timeout.as_secs() == 0 && timeout.subsec_nanos() == 0 { - unsafe { - hid_read(self.handle.as_mut_ptr(), data.as_mut_ptr(), data.len()) - } - } - else { - unsafe { - // Timeout is in milliseconds. - hid_read_timeout(self.handle.as_mut_ptr(), data.as_mut_ptr(), data.len(), - timeout.as_secs() as c_int * 1_000 + timeout.subsec_nanos() as c_int / 1_000_000) - } - }; - - match result { - -1 => - Err(Error::Read), - - 0 => - Ok(None), - - v => - Ok(Some(v as usize)) - } - } - - /// Read data from the device. - /// - /// Returns the report ID and the amount of read bytes or `None` if there was a timeout. - pub fn read_from<T: AsMut<[u8]>>(&mut self, mut data: T, timeout: Duration) -> error::Result<Option<(u8, usize)>> { - let data = data.as_mut(); - let mut buffer = Vec::with_capacity(data.len() + 1); - - if let Some(length) = self.read(&mut buffer, timeout)? { - data[0..length - 1].copy_from_slice(&buffer[1..length]); - - Ok(Some((buffer[0], length - 1))) - } - else { - Ok(None) - } - } -} - -/// The feature accessor. -pub struct Feature<'a> { - handle: &'a mut Handle, -} - -impl<'a> Feature<'a> { - #[doc(hidden)] - pub unsafe fn new(handle: &mut Handle) -> Feature { - Feature { handle: handle } - } - - /// Send a feature request. - /// - /// The first byte must be the report ID. - pub fn send<T: AsRef<[u8]>>(&mut self, data: T) -> error::Result<usize> { - let data = data.as_ref(); - - unsafe { - match hid_send_feature_report(self.handle.as_mut_ptr(), data.as_ptr(), data.len()) { - -1 => - Err(Error::Write), - - length => - Ok(length as usize) - } - } - } - - /// Send a feature request to the given report ID. - pub fn send_to<T: AsRef<[u8]>>(&mut self, id: u8, data: T) -> error::Result<usize> { - let data = data.as_ref(); - let mut buffer = Vec::with_capacity(data.len() + 1); - - buffer.push(id); - buffer.extend(data); - - self.send(&buffer).map(|v| v - 1) - } - - /// Get a feature request. - /// - /// The first byte must be the report ID. - pub fn get<T: AsMut<[u8]>>(&mut self, mut data: T) -> error::Result<usize> { - let data = data.as_mut(); - - unsafe { - match hid_get_feature_report(self.handle.as_mut_ptr(), data.as_mut_ptr(), data.len()) { - -1 => - Err(Error::Read), - - length => - Ok(length as usize) - } - } - } - - /// Get a feature request from the given report ID. - pub fn get_from<T: AsMut<[u8]>>(&mut self, id: u8, mut data: T) -> error::Result<usize> { - let data = data.as_mut(); - let mut buffer = vec![0u8; data.len() + 1]; - buffer[0] = id; - - let length = self.get(&mut buffer)?; - data[0..length - 1].copy_from_slice(&buffer[1..length]); - - Ok(length - 1) - } -} - -impl Drop for Handle { - fn drop(&mut self) { - unsafe { - hid_close(self.as_mut_ptr()); - } - } -} diff --git a/hid/src/lib.rs b/hid/src/lib.rs deleted file mode 100644 index fb2ccf8..0000000 --- a/hid/src/lib.rs +++ /dev/null @@ -1,17 +0,0 @@ -extern crate hidapi_sys as sys; -extern crate libc; - -mod error; -pub use error::{Error, Result}; - -mod manager; -pub use manager::{Manager, init}; - -mod devices; -pub use devices::Devices; - -mod device; -pub use device::Device; - -pub mod handle; -pub use handle::Handle; diff --git a/hid/src/manager.rs b/hid/src/manager.rs deleted file mode 100644 index 4c2eb23..0000000 --- a/hid/src/manager.rs +++ /dev/null @@ -1,56 +0,0 @@ -use std::sync::atomic::{AtomicBool, ATOMIC_BOOL_INIT, Ordering}; - -use sys::*; -use error::{self, Error}; -use devices::Devices; - -static INITIALIZED: AtomicBool = ATOMIC_BOOL_INIT; - -/// The device manager. -pub struct Manager; - -unsafe impl Send for Manager { } - -/// Create the manager. -pub fn init() -> error::Result<Manager> { - if INITIALIZED.load(Ordering::Relaxed) { - return Err(Error::Initialized); - } - - let status = unsafe { hid_init() }; - - if status != 0 { - return Err(Error::from(status)); - } - - INITIALIZED.store(true, Ordering::Relaxed); - - Ok(Manager) -} - -impl Drop for Manager { - fn drop(&mut self) { - let status = unsafe { hid_exit() }; - - if status != 0 { - panic!("hid_exit() failed"); - } - - INITIALIZED.store(false, Ordering::Relaxed); - } -} - -impl Manager { - /// Find the wanted device, `vendor` or `product` are given it will - /// returns only the matches devices. - pub fn find(&self, vendor: Option<u16>, product: Option<u16>) -> Devices { - unsafe { - Devices::new(vendor, product) - } - } - - /// Return all devices. - pub fn devices(&self) -> Devices { - self.find(None, None) - } -} |