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
113
114
115
116
117
118
119
120
121
122
123
124
extern crate byteorder;
use byteorder::{LittleEndian, ByteOrder};
use std::os::unix::net::UnixStream;
use std::io::prelude::*;
use std::io;
#[derive(Debug)]
pub enum Event {
ButtonPress(i32),
ButtonRelease(i32),
Motion {
x: i32,
y: i32,
z: i32,
rx: i32,
ry: i32,
rz: i32,
period: i32,
},
}
const SOCKET: &'static str = "/var/run/spnav.sock";
pub struct SpaceNav {
stream: UnixStream,
}
impl SpaceNav {
pub fn new() -> io::Result<SpaceNav> {
let stream = match UnixStream::connect(SOCKET) {
Ok(s) => s,
Err(e) => return Err(e),
};
Ok(SpaceNav { stream: stream })
}
pub fn read(&mut self) -> Option<Event> {
let mut buffer = [0; 8 * 4];
match self.stream.read_exact(&mut buffer) {
Ok(()) => {}
Err(_) => return None,
}
const MOTION: i32 = 0;
const BUTTON_PRESS: i32 = 1;
const BUTTON_RELEASE: i32 = 2;
let event_type = LittleEndian::read_i32(&buffer);
match event_type {
MOTION => {
Some(Event::Motion {
x: LittleEndian::read_i32(&buffer[4..8]),
y: LittleEndian::read_i32(&buffer[8..12]),
z: LittleEndian::read_i32(&buffer[12..16]),
rx: LittleEndian::read_i32(&buffer[16..20]),
ry: LittleEndian::read_i32(&buffer[20..24]),
rz: LittleEndian::read_i32(&buffer[24..28]),
period: LittleEndian::read_i32(&buffer[28..32]),
})
}
BUTTON_PRESS => Some(Event::ButtonPress(LittleEndian::read_i32(&buffer[4..8]))),
BUTTON_RELEASE => Some(Event::ButtonRelease(LittleEndian::read_i32(&buffer[4..8]))),
_ => None,
}
}
pub fn set_nonblocking(&mut self, nonblocking: bool) -> io::Result<()> {
self.stream.set_nonblocking(nonblocking)
}
}