Skip to content

Commit

Permalink
feat: added basic Rust bindings
Browse files Browse the repository at this point in the history
  • Loading branch information
ABeltramo committed Mar 24, 2024
1 parent 438d564 commit a0cb3e6
Show file tree
Hide file tree
Showing 7 changed files with 132 additions and 2 deletions.
File renamed without changes.
3 changes: 1 addition & 2 deletions python/CMakeLists.txt → bindings/python/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,14 @@ set_property(SOURCE inputtino.i PROPERTY SWIG_MODULE_NAME py_inputtino)
swig_add_library(py_inputtino
TYPE MODULE
LANGUAGE python
OUTPUT_DIR ${CMAKE_SOURCE_DIR}/python/out/py_inputtino
OUTPUT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/out/py_inputtino
SOURCES inputtino.i)
add_library(inputtino::py_inputtino ALIAS py_inputtino)

find_package(Python3 REQUIRED COMPONENTS Interpreter Development.Module)

target_include_directories(py_inputtino
PRIVATE
../include
${Python3_INCLUDE_DIRS}
)
set_property(TARGET py_inputtino PROPERTY SWIG_USE_TARGET_INCLUDE_DIRECTORIES ON)
Expand Down
File renamed without changes.
15 changes: 15 additions & 0 deletions bindings/rust/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
[package]
name = "inputtino"
version = "0.1.0"
edition = "2021"
license = "MIT"
rust-version = "1.72"
links = "libinputtino"

[lib]
name = "inputtino_rs"
path = "src/lib.rs"

[build-dependencies]
bindgen = "0.69.4"
cmake = "0.1"
65 changes: 65 additions & 0 deletions bindings/rust/build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
extern crate bindgen;

use std::env;
use std::path::PathBuf;

use cmake::Config;

fn main() {
let build_static = false;

// This is the directory where the `c` library is located.
let libdir_path = PathBuf::from("../../")
// Canonicalize the path as `rustc-link-search` requires an absolute
// path.
.canonicalize()
.expect("cannot canonicalize path");

// Compile the library using CMake
let dst = Config::new(libdir_path)
.target("libinputtino")
.define("BUILD_SHARED_LIBS", if build_static { "OFF" } else { "ON" })
.define("LIBINPUTTINO_INSTALL", "ON")
.define("BUILD_TESTING", "OFF")
.define("BUILD_SERVER", "OFF")
.define("BUILD_C_BINDINGS", "ON")
.profile("Release")
.define("CMAKE_CONFIGURATION_TYPES", "Release")
.build();

// Dependencies
if !build_static {
println!("cargo:rustc-link-lib=evdev");
println!("cargo:rustc-link-lib=udev");
println!("cargo:rustc-link-lib=stdc++");
}

//libinputtino
println!("cargo:rustc-link-search=native={}/lib", dst.display());
println!("cargo:rustc-link-lib={}libinputtino", if build_static { "static=" } else { "" });

// The bindgen::Builder is the main entry point
// to bindgen, and lets you build up options for
// the resulting bindings.
let bindings = bindgen::Builder::default()
.use_core()
.default_enum_style(bindgen::EnumVariation::Rust {
non_exhaustive: false,
})
// Add the include directory
.clang_arg(format!("-I{}/include/", dst.display()))
// Set the INPUTTINO_STATIC_DEFINE macro
.clang_arg(if build_static {"-D INPUTTINO_STATIC_DEFINE=1"} else {""})
// The input header we would like to generate bindings for.
.header("wrapper.hpp")
// Finish the builder and generate the bindings.
.generate()
// Unwrap the Result and panic on failure.
.expect("Unable to generate bindings");

// Write the bindings to the $OUT_DIR/bindings.rs file.
let out_path = PathBuf::from(env::var("OUT_DIR").unwrap()).join("bindings.rs");
bindings
.write_to_file(out_path)
.expect("Couldn't write bindings!");
}
50 changes: 50 additions & 0 deletions bindings/rust/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
#![allow(non_upper_case_globals)]
#![allow(non_camel_case_types)]
#![allow(non_snake_case)]

include!(concat!(env!("OUT_DIR"), "/bindings.rs"));

#[cfg(test)]
mod tests{

use std::ffi::{CStr, CString};
use super::*;

#[test]
fn test_inputtino_mouse(){
let device_name = CString::new("Rusty Mouse").unwrap();
let device_phys = CString::new("Rusty Mouse Phys").unwrap();
let device_uniq = CString::new("Rusty Mouse Uniq").unwrap();
let def = InputtinoDeviceDefinition {
name: device_name.as_ptr(),
vendor_id: 0,
product_id: 0,
version: 0,
device_phys: device_phys.as_ptr(),
device_uniq: device_uniq.as_ptr(),
};
let _error_handler_fn = | error_message: *const ::core::ffi::c_char, user_data: *mut ::core::ffi::c_void | {
unsafe{ println!("Error: {:?}", CStr::from_ptr(error_message).to_str().unwrap()); }
};
let error_handler = InputtinoErrorHandler {
eh: None, // TODO: InputtinoErrorHandlerFn::new(error_handler_fn) ???
user_data: std::ptr::null_mut(),
};

unsafe{
let mouse = inputtino_mouse_create(&def, &error_handler);
assert!(!mouse.is_null());

let mut nodes_count: core::ffi::c_int = 0;
let nodes = inputtino_mouse_get_nodes(mouse, & mut nodes_count);
assert!(nodes_count == 2);
assert!(!nodes.is_null());
// Check that the nodes start with /dev/input/event
assert!(CString::from_raw(*nodes.offset(0)).to_str().unwrap().starts_with("/dev/input/event"));
assert!(CString::from_raw(*nodes.offset(1)).to_str().unwrap().starts_with("/dev/input/event"));

inputtino_mouse_destroy(mouse);
}
}

}
1 change: 1 addition & 0 deletions bindings/rust/wrapper.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
#include <inputtino/input.h>

0 comments on commit a0cb3e6

Please sign in to comment.