hid_api_rs/gadgets/
mouse.rs1use std::fs::{File, OpenOptions};
2use std::io::{BufWriter, Error, ErrorKind, Read, Write};
3use std::path::Path;
4use std::thread;
5use std::time::Duration;
6
7use once_cell::sync::Lazy;
8
9use crate::{hid, HidMouse};
10
11pub struct Mouse {
12 pub mouse_data_buffer: Vec<MouseRaw>,
13 mouse_state: MouseState,
14 mouse_device_file: File,
15
16 pub mouse_settings: MouseSettings,
17 pub mouse_path: String,
18
19 side_buttons: bool
20}
21
22impl Mouse {
23 pub fn get_state(&self) -> &MouseState {
24 &self.mouse_state
25 }
26}
27
28#[derive(Copy, Clone, Default)]
29pub struct MouseState {
30 pub left_button: bool,
31 pub right_button: bool,
32 pub middle_button: bool,
33 pub four_button: bool,
34 pub five_button: bool,
35}
36
37pub struct MouseSettings {
38 pub invert_x: bool,
39 pub invert_y: bool,
40 pub invert_wheel: bool,
41
42 pub sensitivity_multiplier: i16,
43}
44
45impl Default for MouseSettings {
46 fn default() -> Self {
47 MouseSettings {
48 invert_x: false,
49 invert_y: false,
50 invert_wheel: false,
51 sensitivity_multiplier: 1,
52 }
53 }
54}
55
56#[derive(Default)]
57pub struct MouseRaw {
58 pub left_button: bool,
59 pub right_button: bool,
60 pub middle_button: bool,
61 pub four_button: bool,
62 pub five_button: bool,
63
64 pub relative_x: i16,
65 pub relative_y: i16,
66 pub relative_wheel: i16,
67}
68
69pub fn attempt_read(mouse: &mut Mouse, gadget_writer: &mut BufWriter<&mut File>) -> Result<(), Error> {
70 const BUFFER_LENGTH: usize = 4;
71 let mut mouse_buffer = [0u8; BUFFER_LENGTH];
72
73 let mouse_read_length = mouse.mouse_device_file.read(&mut mouse_buffer)?;
74
75 if mouse_read_length >= BUFFER_LENGTH {
76 let left_button = mouse_buffer[0] & 0x1 > 0;
77 let right_button = mouse_buffer[0] & 0x2 > 0;
78 let middle_button = mouse_buffer[0] & 0x4 > 0;
79
80 let mut mouse_four = false;
81 let mut mouse_five = false;
82
83 if mouse.side_buttons {
85 mouse_four = mouse_buffer[3] & 0x10 > 0;
86 mouse_five = mouse_buffer[3] & 0x20 > 0;
87 }
88
89 let mut relative_y = -i8::from_be_bytes(mouse_buffer[2].to_be_bytes()) as i16;
90 let mut relative_x = i8::from_be_bytes(mouse_buffer[1].to_be_bytes()) as i16;
91
92 let mut relative_wheel = match mouse.side_buttons {
93 true => {
94 let mut z = ((mouse_buffer[3] & 0x8) | (mouse_buffer[3] & 0x4) | (mouse_buffer[3] & 0x2) | (mouse_buffer[3] & 0x1)) as i8;
95
96 if mouse_buffer[3] & 0x8 > 0 {
97 z = (z << 4) >> 4
98 }
99
100 -i8::from_be_bytes(z.to_be_bytes()) as i16
101 },
102 false => -i8::from_be_bytes(mouse_buffer[3].to_be_bytes()) as i16
103 };
104
105 if mouse.mouse_settings.invert_x {
106 relative_x *= -1;
107 }
108
109 if mouse.mouse_settings.invert_y {
110 relative_y *= -1;
111 }
112
113 if mouse.mouse_settings.invert_wheel {
114 relative_wheel *= -1;
115 }
116
117 relative_x *= mouse.mouse_settings.sensitivity_multiplier;
118 relative_y *= mouse.mouse_settings.sensitivity_multiplier;
119
120 let raw_mouse = MouseRaw {
121 left_button,
122 right_button,
123 middle_button,
124 four_button: mouse_four,
125 five_button: mouse_five,
126 relative_x,
127 relative_y,
128 relative_wheel,
129 };
130
131 return push_mouse_event(raw_mouse, Some(mouse), gadget_writer);
132 }
133
134 Ok(())
135}
136
137pub fn push_mouse_event(raw_data: MouseRaw, mouse: Option<&mut Mouse>, gadget_writer: &mut BufWriter<&mut File>) -> Result<(), Error> {
138 if let Some(mouse) = mouse {
139 let new_state = MouseState {
140 left_button: raw_data.left_button,
141 right_button: raw_data.right_button,
142 middle_button: raw_data.middle_button,
143 four_button: raw_data.four_button,
144 five_button: raw_data.five_button,
145 };
146 mouse.mouse_state = new_state;
147 }
148
149 hid::write_mouse(&raw_data, gadget_writer)
150}
151
152pub fn check_mouses(mouse_inputs: &Vec<HidMouse>, mouse_interfaces: &'static mut Lazy<Vec<Mouse>>) {
153 for mouse_input in mouse_inputs {
154 if mouse_interfaces.iter().any(|mouse| mouse.mouse_path == mouse_input.mouse_path) {
155 thread::sleep(Duration::from_millis(1));
156 continue;
157 }
158
159 let mouse_path = Path::new(&mouse_input.mouse_path);
160 if Path::exists(mouse_path) {
161 let mouse = match OpenOptions::new()
162 .write(true)
163 .read(true)
164 .open(mouse_path)
165 {
166 Ok(result) => result,
167 Err(_) => continue,
168 };
169
170 let mut mouse_interface = Mouse {
171 mouse_data_buffer: Vec::new(),
172 mouse_state: MouseState::default(),
173 mouse_device_file: mouse,
174 mouse_settings: MouseSettings::default(),
175 mouse_path: mouse_input.mouse_path.clone(),
176 side_buttons: mouse_input.mouse_side_buttons
177 };
178
179 let mut mouse_feature: [u8; 6] = [0xf3, 200, 0xf3, 100, 0xf3, 80];
181 if mouse_input.mouse_side_buttons {
182 mouse_feature = [0xf3, 200, 0xf3, 200, 0xf3, 80];
183 }
184
185 _ = write_feature(&mut mouse_interface, mouse_feature);
186
187 if let Some(poll_rate) = mouse_input.mouse_poll_rate {
188 _ = write_poll_rate(&mut mouse_interface, poll_rate);
189 }
190
191 mouse_interfaces.push(mouse_interface);
192 }
193 }
194}
195
196pub fn write_feature(mouse: &mut Mouse, feature: [u8; 6]) -> Result<(), Error> {
197 if mouse.mouse_device_file.write_all(&feature).is_err() {
198 return Err(Error::new(
199 ErrorKind::Other,
200 String::from("Failed write magic scroll feature to mouse!"),
201 ));
202 }
203
204 Ok(())
205}
206
207pub fn write_poll_rate(mouse: &mut Mouse, poll_rate: i32) -> Result<(), Error> {
208 let mut poll_rate_packet: Vec<u8> = Vec::new();
209 poll_rate_packet.push(0xf3);
210 poll_rate_packet.append(&mut poll_rate.to_be_bytes().to_vec());
211
212 if mouse.mouse_device_file.write_all(&poll_rate_packet).is_err() {
213 return Err(Error::new(
214 ErrorKind::Other,
215 String::from("Failed to set poll rate to mouse! (Defaulting to 125 hz or last mouse profile)"),
216 ));
217 }
218
219 Ok(())
220}