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}