1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
extern crate ffi_support;
pub extern crate wooting_analog_common;
use ffi_support::FfiStr;
use std::collections::HashMap;
use std::hash::Hasher;
use std::os::raw::{c_float, c_ushort};
use wooting_analog_common::*;
#[no_mangle]
pub static ANALOG_SDK_PLUGIN_ABI_VERSION: u32 = 1;
#[no_mangle]
pub static ANALOG_SDK_PLUGIN_VERSION: &str = env!("CARGO_PKG_VERSION");
pub trait Plugin {
fn name(&mut self) -> SDKResult<&'static str>;
fn initialise(&mut self, callback: extern "C" fn(DeviceEventType, DeviceInfoPointer)) -> SDKResult<u32>;
fn is_initialised(&mut self) -> bool;
fn device_info(&mut self) -> SDKResult<Vec<DeviceInfoPointer>>;
fn unload(&mut self) {}
fn read_analog(&mut self, code: u16, device: DeviceID) -> SDKResult<f32>;
fn read_full_buffer(
&mut self,
max_length: usize,
device: DeviceID,
) -> SDKResult<HashMap<c_ushort, c_float>>;
}
#[macro_export]
macro_rules! declare_plugin {
($plugin_type:ty, $constructor:path) => {
#[no_mangle]
pub extern "C" fn _plugin_create() -> *mut $crate::Plugin {
let constructor: fn() -> $plugin_type = $constructor;
let object = constructor();
let boxed: Box<$crate::Plugin> = Box::new(object);
Box::into_raw(boxed)
}
#[no_mangle]
pub extern "C" fn plugin_version() -> &'static str {
ANALOG_SDK_PLUGIN_VERSION
}
};
}
pub fn generate_device_id(serial_number: &str, vendor_id: u16, product_id: u16) -> DeviceID {
use std::collections::hash_map::DefaultHasher;
let mut s = DefaultHasher::new();
s.write_u16(vendor_id);
s.write_u16(product_id);
s.write(serial_number.as_bytes());
s.finish()
}
mod ffi {
use super::*;
#[no_mangle]
pub extern "C" fn generate_device_id(
serial_number: FfiStr,
vendor_id: u16,
product_id: u16,
) -> DeviceID {
let serial = {
if let Some(str) = serial_number.into_opt_string() {
str
} else {
return 0;
}
};
super::generate_device_id(&serial, vendor_id, product_id)
}
}