tobii_sys/
helpers.rs

1use super::*;
2use std::os::raw;
3use std::thread;
4use std::time;
5use std::ffi::CStr;
6use std::ptr;
7
8pub struct PtrWrapper<T> {
9    ptr: *mut T,
10    destroy_fn: unsafe extern "C" fn(ptr: *mut T) -> Status,
11}
12
13impl<T> PtrWrapper<T> {
14    pub unsafe fn new(ptr: *mut T, destroy_fn: unsafe extern "C" fn(ptr: *mut T) -> Status) -> PtrWrapper<T> {
15        PtrWrapper { ptr, destroy_fn }
16    }
17
18    pub fn ptr(&self) -> *mut T {
19        self.ptr
20    }
21}
22
23impl<T> Drop for PtrWrapper<T> {
24    fn drop(&mut self) {
25        let destroy_fn = self.destroy_fn;
26        let status = unsafe { destroy_fn(self.ptr) };
27        assert_eq!(status, TOBII_ERROR_NO_ERROR);
28    }
29}
30
31#[derive(Debug,Clone,Copy)]
32pub enum TobiiError {
33    Internal,
34    InsufficientLicense,
35    NotSupported,
36    NotAvailable,
37    ConnectionFailed,
38    TimedOut,
39    AllocationFailed,
40    InvalidParameter,
41    CalibrationAlreadyStarted,
42    CalibrationNotStarted,
43    AlreadySubscribed,
44    NotSubscribed,
45    OperationFailed,
46    ConflictingApiInstances,
47    CalibrationBusy,
48    CallbackInProgress,
49    Unknown(Status),
50}
51
52pub fn status_to_result(status: Status) -> Result<(),TobiiError> {
53    match status {
54        TOBII_ERROR_NO_ERROR => Ok(()),
55        TOBII_ERROR_INTERNAL => Err(TobiiError::Internal),
56        TOBII_ERROR_INSUFFICIENT_LICENSE => Err(TobiiError::InsufficientLicense),
57        TOBII_ERROR_NOT_SUPPORTED => Err(TobiiError::NotSupported),
58        TOBII_ERROR_NOT_AVAILABLE => Err(TobiiError::NotAvailable),
59        TOBII_ERROR_CONNECTION_FAILED => Err(TobiiError::ConnectionFailed),
60        TOBII_ERROR_TIMED_OUT => Err(TobiiError::TimedOut),
61        TOBII_ERROR_ALLOCATION_FAILED => Err(TobiiError::AllocationFailed),
62        TOBII_ERROR_INVALID_PARAMETER => Err(TobiiError::InvalidParameter),
63        TOBII_ERROR_CALIBRATION_ALREADY_STARTED => Err(TobiiError::CalibrationAlreadyStarted),
64        TOBII_ERROR_CALIBRATION_NOT_STARTED => Err(TobiiError::CalibrationNotStarted),
65        TOBII_ERROR_ALREADY_SUBSCRIBED => Err(TobiiError::AlreadySubscribed),
66        TOBII_ERROR_NOT_SUBSCRIBED => Err(TobiiError::NotSubscribed),
67        TOBII_ERROR_OPERATION_FAILED => Err(TobiiError::OperationFailed),
68        TOBII_ERROR_CONFLICTING_API_INSTANCES => Err(TobiiError::ConflictingApiInstances),
69        TOBII_ERROR_CALIBRATION_BUSY => Err(TobiiError::CalibrationBusy),
70        TOBII_ERROR_CALLBACK_IN_PROGRESS => Err(TobiiError::CallbackInProgress),
71        _ => Err(TobiiError::Unknown(status))
72    }
73}
74
75pub unsafe fn list_devices(api: *mut Api) -> Result<Vec<String>, TobiiError> {
76    unsafe extern "C" fn callback(url: *const raw::c_char, user_data: *mut raw::c_void) {
77        let list = &mut *(user_data as *mut Vec<String>);
78        let s = CStr::from_ptr(url);
79        list.push(s.to_str().unwrap().to_string());
80    }
81
82    let mut list: Vec<String> = Vec::new();
83    let list_ptr = &mut list as *mut Vec<String>;
84    let status = tobii_enumerate_local_device_urls(api, Some(callback), list_ptr as *mut raw::c_void);
85    status_to_result(status)?;
86    Ok(list)
87}
88
89pub unsafe fn reconnect(device: *mut Device) -> Status {
90    for _i in 0..40 {
91        let status = tobii_device_reconnect(device);
92        if status != TOBII_ERROR_CONNECTION_FAILED { return status; }
93        thread::sleep(time::Duration::from_millis(250));
94    }
95    return TOBII_ERROR_CONNECTION_FAILED;
96}
97
98pub unsafe fn wait_for_device_callbacks(device: *mut Device) -> Status {
99    let ptr_ptr_dev: *const *mut Device = (&device) as *const *mut Device;
100    tobii_wait_for_callbacks(ptr::null_mut(), 1, ptr_ptr_dev)
101}