diff options
-rw-r--r-- | hidapi-sys/.gitignore | 2 | ||||
-rw-r--r-- | hidapi-sys/Cargo.toml | 24 | ||||
-rw-r--r-- | hidapi-sys/build.rs | 81 | ||||
-rw-r--r-- | hidapi-sys/src/lib.rs | 68 |
4 files changed, 175 insertions, 0 deletions
diff --git a/hidapi-sys/.gitignore b/hidapi-sys/.gitignore new file mode 100644 index 0000000..a9d37c5 --- /dev/null +++ b/hidapi-sys/.gitignore @@ -0,0 +1,2 @@ +target +Cargo.lock diff --git a/hidapi-sys/Cargo.toml b/hidapi-sys/Cargo.toml new file mode 100644 index 0000000..15b4e9e --- /dev/null +++ b/hidapi-sys/Cargo.toml @@ -0,0 +1,24 @@ +[package] +name = "hidapi-sys" +version = "0.1.2" +build = "build.rs" +links = "hidapi" + +authors = ["meh. <meh@schizofreni.co>"] +license = "WTFPL" + +description = "FFI bindings to hidapi" +repository = "https://github.com/meh/rust-hidapi-sys" +keywords = ["hid"] +categories = ["external-ffi-bindings", "hardware-support", "os"] + +[features] +static = [] +build = ["static"] + +[dependencies] +libc = "0.2" + +[build-dependencies] +gcc = "0.3" +pkg-config = "0.3" diff --git a/hidapi-sys/build.rs b/hidapi-sys/build.rs new file mode 100644 index 0000000..6ad9197 --- /dev/null +++ b/hidapi-sys/build.rs @@ -0,0 +1,81 @@ +extern crate gcc; +extern crate pkg_config; + +use std::env; +use std::io; +use std::path::PathBuf; +use std::process::Command; + +fn main() { + if env::var("CARGO_FEATURE_BUILD").is_err() { + return; + } + + fetch().unwrap(); + build().unwrap(); + + println!("cargo:rustc-link-search=native={}", output().to_string_lossy()); +} + +fn output() -> PathBuf { + PathBuf::from(env::var("OUT_DIR").unwrap()) +} + +fn source() -> PathBuf { + output().join("hidapi") +} + +fn fetch() -> io::Result<()> { + Command::new("git") + .current_dir(&output()) + .arg("clone") + .arg("https://github.com/signal11/hidapi.git") + .arg("hidapi") + .status()?; + + Ok(()) +} + +#[cfg(target_os = "linux")] +fn build() -> io::Result<()> { + let mut config = gcc::Config::new(); + + config.file(source().join("libusb/hid.c")); + config.include(source().join("hidapi")); + + for path in pkg_config::find_library("libusb-1.0").unwrap().include_paths { + config.include(path.to_str().unwrap()); + } + + config.compile("libhidapi-libusb.a"); + + Ok(()) +} + +#[cfg(target_os = "macos")] +fn build() -> io::Result<()> { + let mut config = gcc::Config::new(); + + config.file(source().join("libusb/hid.c")); + config.include(source().join("hidapi")); + + for path in pkg_config::find_library("libusb-1.0").unwrap().include_paths { + config.include(path.to_str().unwrap()); + } + + config.compile("libhidapi.a"); + + Ok(()) +} + +#[cfg(target_os = "windows")] +fn build() -> io::Result<()> { + let mut config = gcc::Config::new(); + + config.file(source().join("windows/hid.c")); + config.include(source().join("hidapi")); + + config.compile("libhidapi.a"); + + Ok(()) +} diff --git a/hidapi-sys/src/lib.rs b/hidapi-sys/src/lib.rs new file mode 100644 index 0000000..656bd47 --- /dev/null +++ b/hidapi-sys/src/lib.rs @@ -0,0 +1,68 @@ +#![allow(non_camel_case_types, non_snake_case, non_upper_case_globals)] + +extern crate libc; + +use libc::{c_void, c_ushort, wchar_t, c_int, c_uchar, size_t, c_char}; + +pub type hid_device = c_void; + +#[repr(C)] +pub struct hid_device_info { + pub path: *mut c_char, + + pub vendor_id: c_ushort, + pub product_id: c_ushort, + + pub serial_number: *mut wchar_t, + pub release_number: c_ushort, + + pub manufacturer_string: *mut wchar_t, + pub product_string: *mut wchar_t, + + pub usage_page: c_ushort, + pub usage: c_ushort, + + pub interface_number: c_int, + + pub next: *mut hid_device_info, +} + +#[cfg_attr(target_os = "linux", link(name = "udev"))] +extern "C" { } + +#[cfg_attr(target_os = "windows", link(name = "setupapi"))] +extern "C" { } + +#[cfg_attr(all(feature = "static", target_os = "linux"), link(name = "hidapi-libusb", kind = "static"))] +#[cfg_attr(all(not(feature = "static"), target_os = "linux"), link(name = "hidapi-libusb"))] +#[cfg_attr(all(feature = "static", not(target_os = "linux")), link(name = "hidapi", kind = "static"))] +#[cfg_attr(all(not(feature = "static"), not(target_os = "linux")), link(name = "hidapi"))] +extern "C" { + pub fn hid_init() -> c_int; + pub fn hid_exit() -> c_int; + + pub fn hid_enumerate(vendor_id: c_ushort, product_id: c_ushort) -> *mut hid_device_info; + pub fn hid_free_enumeration(devs: *mut hid_device_info); + + pub fn hid_open(vendor_id: c_ushort, product_id: c_ushort, serial_number: *const wchar_t) -> *mut hid_device; + pub fn hid_open_path(path: *const c_char) -> *mut hid_device; + + pub fn hid_write(device: *mut hid_device, data: *const c_uchar, length: size_t) -> c_int; + + pub fn hid_read_timeout(device: *mut hid_device, data: *mut c_uchar, length: size_t, milleseconds: c_int) -> c_int; + pub fn hid_read(device: *mut hid_device, data: *mut c_uchar, length: size_t) -> c_int; + + pub fn hid_set_nonblocking(device: *mut hid_device, nonblock: c_int) -> c_int; + + pub fn hid_send_feature_report(device: *mut hid_device, data: *const c_uchar, length: size_t) -> c_int; + pub fn hid_get_feature_report(device: *mut hid_device, data: *mut c_uchar, length: size_t) -> c_int; + + pub fn hid_close(device: *mut hid_device); + + pub fn hid_get_manufacturer_string(device: *mut hid_device, string: *mut wchar_t, maxlen: size_t) -> c_int; + pub fn hid_get_product_string(device: *mut hid_device, string: *mut wchar_t, maxlen: size_t) -> c_int; + pub fn hid_get_serial_number_string(device: *mut hid_device, string: *mut wchar_t, maxlen: size_t) -> c_int; + pub fn hid_get_indexed_string(device: *mut hid_device, string_index: c_int, string: *mut wchar_t, maxlen: size_t) -> c_int; + + pub fn hid_error(device: *mut hid_device) -> *const wchar_t; +} |