1use std::path::Path;
2use std::{fs, mem, ptr, slice, thread};
3use std::ffi::CString;
4use std::fs::File;
5use std::io::Write;
6use std::os::fd::AsRawFd;
7use std::thread::{JoinHandle, sleep};
8use std::time::{Duration, Instant, SystemTime};
9use nix::errno::Errno;
10use crossbeam_channel::{Sender, Receiver, bounded};
11use libc::gettimeofday;
12
13use crate::*;
14use crate::utils::GradualMove;
15
16pub type Result<T> = std::result::Result<T, Box<dyn std::error::Error>>;
17pub type EmptyResult = Result<()>;
18
19pub type Button = u16;
20pub type Coord = i32;
21
22pub type EventParams = (u16, u16, i32);
23pub type ChannelSender = Sender<EventParams>;
24type ChannelReceiver = Receiver<EventParams>;
25
26pub struct VirtualDevice {
27 writing_interval: Duration,
28 file: File,
29 def: uinput_user_dev,
30 pub sender: ChannelSender,
31 receiver: ChannelReceiver,
32}
33
34const FIXED_TIME: timeval = timeval { tv_sec: 0, tv_usec: 0 };
35const SYN_PARAMS: EventParams = (EV_SYN, SYN_REPORT, 0);
36
37const SLEEP_BEFORE_RELEASE: Duration = Duration::from_millis(5);
38
39
40#[inline(always)]
41fn convert_event_for_writing(kind: u16, code: u16, value: i32) -> Vec<u8> {
42 let mut input_event = input_event {
43 time: FIXED_TIME,
44 kind,
45 code,
46 value,
47 };
48
49 unsafe {
50 let ptr = &input_event as *const _ as *const u8;
53 let size = mem::size_of_val(&input_event);
54 let content = slice::from_raw_parts(ptr, size);
55 content.to_vec()
56 }
57}
58
59pub enum DeviceDefinitionType{
60 Separate,
61 MouseOnly,
62 KeyboardOnly,
63 None,
64}
65
66const UINPUT_NOT_LOADED_ERR: &str = "'uinput' module probably is not loaded. try: 'sudo modprobe uinput'";
67
68impl VirtualDevice {
69 pub fn default() -> Result<Self> {
70 VirtualDevice::new(
71 Duration::from_millis(1),
72 50,
73 DeviceDefinitionType::None,
74 )
75 }
76 fn new(writing_interval: Duration, channel_size: usize, definition_type: DeviceDefinitionType) -> Result<Self> {
84 let (s, r) = bounded(channel_size);
85
86 let path = Path::new("/dev/uinput");
87
88 #[cfg(feature = "auto-acquire-permissions")]
89 {
90 use std::os::unix::fs::PermissionsExt;
91 let metadata = fs::metadata(path).expect(UINPUT_NOT_LOADED_ERR);
92 let mut permissions = metadata.permissions();
93 permissions.set_mode(0o660);
94 }
95
96 use std::fs::OpenOptions;
97 use std::os::unix::fs::OpenOptionsExt;
98
99 let file = OpenOptions::new()
100 .write(true)
101 .custom_flags(libc::O_NONBLOCK)
102 .open(path)?;
103
104 let mut definition: uinput_user_dev = unsafe { mem::zeroed() };
110 let mut device_name: String;
111
112 match definition_type {
113 DeviceDefinitionType::Separate => {
114 return Err(Box::from("Not implemented"));
115 }
116 DeviceDefinitionType::MouseOnly => {
117 definition.id = input_id {
118 bustype: 0x0003,
119 vendor: 0x045e,
120 product: 0x07a5,
121 version: 0x0111,
122 };
123 device_name = String::from("virtual-mouse");
124 }
125 DeviceDefinitionType::KeyboardOnly => {
126 definition.id = input_id {
127 bustype: 0x0011,
128 vendor: 0x0001,
129 product: 0x0001,
130 version: 0xab83,
131 };
132 device_name = String::from("virtual-keyboard");
133 }
134 DeviceDefinitionType::None => {
135 device_name = String::from("virtual-device");
136 }
137 }
138
139 let mut virtual_device = VirtualDevice {
140 writing_interval,
141 file,
142 def: definition,
143 sender: s,
144 receiver: r,
145 };
146
147 virtual_device.set_name(device_name.as_str())?;
152
153 virtual_device.register_mouse()?;
154 virtual_device.register_keyboard()?;
155
156 virtual_device.create()?;
157
158 Ok(virtual_device)
159 }
160
161 fn set_name<T: AsRef<str>>(&mut self, value: T) -> EmptyResult {
162 let string = CString::new(value.as_ref())?;
163 let bytes = string.as_bytes_with_nul();
164
165 if bytes.len() > UINPUT_MAX_NAME_SIZE {
166 return Err(Box::from(
167 format!(
168 "Virtual device name is longer than maximum allowed size: {}.\nUse shorter name",
169 UINPUT_MAX_NAME_SIZE
170 )));
171 }
172
173 (&mut self.def.name)[..bytes.len()]
174 .clone_from_slice(unsafe { mem::transmute(bytes) });
175
176 Ok(())
177 }
178
179 fn create(&mut self) -> EmptyResult {
180 unsafe {
181 let ptr = &self.def as *const _ as *const u8;
182 let size = mem::size_of_val(&self.def);
183
184 self.file.write_all(slice::from_raw_parts(ptr, size))?;
185
186 Errno::result(ui_dev_create(self.file.as_raw_fd()))?;
187 }
188 Ok(())
189 }
190
191 fn register_keyboard(&self) -> EmptyResult {
192 for code in 1..255 {
193 self.register_key(code)?
194 }
195 Ok(())
196 }
197
198 fn register_mouse(&self) -> EmptyResult {
199 for code in [BTN_LEFT, BTN_RIGHT, BTN_MIDDLE] {
200 self.register_key(code)?
201 }
202
203 for code in [REL_X, REL_Y, REL_HWHEEL, REL_WHEEL] {
204 self.register_relative(code)?
205 }
206
207 Ok(())
208 }
209
210 fn register_key(&self, code: u16) -> EmptyResult {
211 unsafe {
212 Errno::result(ui_set_evbit(self.file.as_raw_fd(), EV_KEY as i32))?;
213 Errno::result(ui_set_keybit(self.file.as_raw_fd(), code as i32))?;
214 }
215 Ok(())
216 }
217
218 fn register_relative(&self, code: u16) -> EmptyResult {
219 unsafe {
220 Errno::result(ui_set_evbit(self.file.as_raw_fd(), EV_REL as i32))?;
221 Errno::result(ui_set_relbit(self.file.as_raw_fd(), code as i32))?;
222 }
223 Ok(())
224 }
225
226 #[inline]
227 pub fn send_to_channel(kind: u16, code: u16, value: i32, sender: &ChannelSender) -> EmptyResult {
228 sender.send((kind, code, value))?;
229 Ok(())
230 }
231
232 #[inline]
233 pub fn send_press(button: Button, sender: &ChannelSender) -> EmptyResult {
234 sender.send((EV_KEY, button, 1))?;
235 sender.send(SYN_PARAMS)?;
236 Ok(())
237 }
238
239 #[inline]
240 pub fn send_release(button: Button, sender: &ChannelSender) -> EmptyResult {
241 sender.send((EV_KEY, button, 0))?;
242 Ok(())
243 }
244
245 pub fn send_click(button: Button, sender: &ChannelSender) -> EmptyResult {
246 VirtualDevice::send_press(button, sender)?;
247 VirtualDevice::send_release(button, sender)
248 }
249
250 #[inline]
251 pub fn send_mouse_move_x(x: Coord, sender: &ChannelSender) -> EmptyResult {
252 sender.send((EV_REL, REL_X, x))?;
253 Ok(())
254 }
255
256 #[inline]
257 pub fn send_mouse_move_y(y: Coord, sender: &ChannelSender) -> EmptyResult {
258 sender.send((EV_REL, REL_Y, -y))?;
259 Ok(())
260 }
261
262 #[inline]
263 pub fn send_mouse_move(x: Coord, y: Coord, sender: &ChannelSender) -> EmptyResult {
264 sender.send((EV_REL, REL_X, x))?;
265 sender.send((EV_REL, REL_Y, -y))?;
266 Ok(())
267 }
268
269 #[inline]
270 pub fn send_scroll_x(value: Coord, sender: &ChannelSender) -> EmptyResult {
271 sender.send((EV_REL, REL_HWHEEL, value))?;
272 Ok(())
273 }
274
275 #[inline]
276 pub fn send_scroll_y(value: Coord, sender: &ChannelSender) -> EmptyResult {
277 sender.send((EV_REL, REL_WHEEL, value))?;
278 Ok(())
279 }
280
281 pub fn flush_channel_every_interval(mut self) -> JoinHandle<()> {
282 let writing_interval = self.writing_interval;
283
284 thread::spawn(move || {
285 loop {
286 let start = Instant::now();
287
288 self.write_events_from_channel().unwrap();
289
290 let runtime = start.elapsed();
291
292 if let Some(remaining) = writing_interval.checked_sub(runtime) {
293 sleep(remaining);
294 }
295 }
296 })
297
298 }
300
301 #[inline]
302 fn write_events_from_channel(&mut self) -> EmptyResult {
303 let mut converted = Vec::new();
304 self.sender.send(SYN_PARAMS)?;
305
306 for event in self.receiver.try_iter() {
307 let mut input_event = input_event {
311 time: FIXED_TIME,
312 kind: event.0,
313 code: event.1,
314 value: event.2,
315 };
316
317 unsafe {
318 let ptr = &input_event as *const _ as *const u8;
321 let size = mem::size_of_val(&input_event);
322 let content = slice::from_raw_parts(ptr, size);
323 converted.extend_from_slice(content);
324 }
325 }
326
327 self.file.write_all(converted.as_slice())?;
328 Ok(())
329 }
330
331 #[inline]
332 pub fn write_batch(&mut self, batch: &[EventParams]) -> EmptyResult{
333 let mut converted = Vec::new();
334
335 for event in batch{
336 let mut input_event = input_event {
337 time: FIXED_TIME,
338 kind: event.0,
339 code: event.1,
340 value: event.2,
341 };
342
343 unsafe {
344 let ptr = &input_event as *const _ as *const u8;
347 let size = mem::size_of_val(&input_event);
348 let content = slice::from_raw_parts(ptr, size);
349 converted.extend_from_slice(content);
350 }
351 }
352 self.file.write_all(converted.as_slice())?;
353 Ok(())
354 }
355
356 #[inline]
357 fn write(&mut self, kind: u16, code: u16, value: i32) -> EmptyResult {
358 let mut input_event = input_event {
362 time: FIXED_TIME,
363 kind,
364 code,
365 value,
366 };
367
368 unsafe {
369 let ptr = &input_event as *const _ as *const u8;
372 let size = mem::size_of_val(&input_event);
373 let content = slice::from_raw_parts(ptr, size);
374 self.file.write_all(content)?;
375 }
376
377 Ok(())
378 }
379
380 #[inline(always)]
381 pub fn synchronize(&mut self) -> EmptyResult {
382 self.write(EV_SYN, SYN_REPORT, 0)
383 }
384
385 #[inline]
386 pub fn move_mouse_raw_x(&mut self, x: Coord) -> EmptyResult {
387 self.write(EV_REL, REL_X, x)
388 }
389
390 #[inline]
391 pub fn move_mouse_raw_y(&mut self, y: Coord) -> EmptyResult {
392 self.write(EV_REL, REL_Y, -y)
393 }
394
395 #[inline]
396 pub fn move_mouse_raw(&mut self, x: Coord, y: Coord) -> EmptyResult {
397 self.write_batch(&[
398 (EV_REL, REL_X, x),
399 (EV_REL, REL_Y, -y),
400 ])
401 }
402
403 #[inline]
404 pub fn buffered_move_mouse_x(&mut self, x: Coord) -> Vec<EventParams> {
405 vec![
406 (EV_REL, REL_X, x),
407 SYN_PARAMS
408 ]
409 }
410
411 #[inline]
412 pub fn buffered_move_mouse_y(&mut self, y: Coord) -> Vec<EventParams> {
413 vec![
414 (EV_REL, REL_Y, -y),
415 SYN_PARAMS
416 ]
417 }
418
419 #[inline]
420 pub fn buffered_move_mouse(&mut self, x: Coord, y: Coord) -> Vec<EventParams> {
421 vec![
422 (EV_REL, REL_X, x),
423 (EV_REL, REL_Y, -y),
424 SYN_PARAMS
425 ]
426 }
427
428 #[inline]
429 pub fn gradual_move_mouse_raw(&mut self, x: Coord, y: Coord) -> Result<()> {
430 let gradual_move = GradualMove::calculate(x, y);
431
432 for _ in 0..gradual_move.both_move {
433 self.move_mouse_raw(gradual_move.x_direction, gradual_move.y_direction)?;
434 }
435 for _ in 0..gradual_move.move_only_x {
436 self.move_mouse_raw_x(gradual_move.x_direction)?;
437 }
438 for _ in 0..gradual_move.move_only_y {
439 self.move_mouse_raw_y(gradual_move.y_direction)?;
440 }
441 self.synchronize()?;
442
443 Ok(())
444 }
445
446 #[inline]
447 pub fn smooth_move_mouse(&mut self, x: Coord, y: Coord) -> Result<()> {
448 self.gradual_move_mouse_raw(x, y)
449 }
450
451 #[inline]
452 pub fn buffered_gradual_move_mouse(&mut self, x: Coord, y: Coord) -> Vec<EventParams> {
453 let mut write_buffer: Vec<EventParams> = vec![];
454 let gradual_move = GradualMove::calculate(x, y);
455
456 for _ in 0..gradual_move.both_move {
457 write_buffer.extend(self.buffered_move_mouse(gradual_move.x_direction, gradual_move.y_direction));
458 }
459 for _ in 0..gradual_move.move_only_x {
460 write_buffer.extend(self.buffered_move_mouse_x(gradual_move.x_direction));
461 }
462 for _ in 0..gradual_move.move_only_y {
463 write_buffer.extend(self.buffered_move_mouse_y(gradual_move.y_direction));
464 }
465
466 write_buffer
467 }
468
469 #[inline]
470 pub fn move_mouse_x(&mut self, x: Coord) -> EmptyResult {
471 self.write_batch(&[
472 (EV_REL, REL_X, x),
473 SYN_PARAMS
474 ])
475 }
476
477 #[inline]
478 pub fn move_mouse_y(&mut self, y: Coord) -> EmptyResult {
479 self.write_batch(&[
480 (EV_REL, REL_Y, -y),
481 SYN_PARAMS
482 ])
483 }
484
485 #[inline]
486 pub fn move_mouse(&mut self, x: Coord, y: Coord) -> EmptyResult {
487 self.write_batch(&[
488 (EV_REL, REL_X, x),
489 (EV_REL, REL_Y, -y),
490 SYN_PARAMS
491 ])
492 }
493
494 #[inline]
532 pub fn scroll_raw_x(&mut self, value: Coord) -> EmptyResult {
533 self.write(EV_REL, REL_HWHEEL, value)
534 }
535
536 #[inline]
537 pub fn scroll_raw_y(&mut self, value: Coord) -> EmptyResult {
538 self.write(EV_REL, REL_WHEEL, value)
539 }
540
541 #[inline]
542 pub fn buffered_scroll_x(&mut self, value: Coord) -> Vec<EventParams> {
543 vec![
544 (EV_REL, REL_HWHEEL, value),
545 SYN_PARAMS
546 ]
547 }
548
549 #[inline]
550 pub fn buffered_scroll_y(&mut self, value: Coord) -> Vec<EventParams> {
551 vec![
552 (EV_REL, REL_WHEEL, value),
553 SYN_PARAMS
554 ]
555 }
556
557 #[inline]
558 pub fn scroll_x(&mut self, value: Coord) -> EmptyResult {
559 self.write_batch(&[
560 (EV_REL, REL_HWHEEL, value),
561 SYN_PARAMS
562 ])
563 }
564
565 #[inline]
566 pub fn gradual_scroll_raw(&mut self, x: Coord, y: Coord) -> Result<()> {
567 let gradual_move = GradualMove::calculate(x, y);
568
569 for _ in 0..gradual_move.both_move {
570 self.scroll_raw_x(gradual_move.x_direction)?;
571 self.scroll_raw_y(gradual_move.y_direction)?;
572 }
573 for _ in 0..gradual_move.move_only_x {
574 self.scroll_raw_x(gradual_move.x_direction)?;
575 }
576 for _ in 0..gradual_move.move_only_y {
577 self.scroll_raw_y(gradual_move.y_direction)?;
578 }
579 self.synchronize()?;
580
581 Ok(())
582 }
583
584 #[inline]
585 pub fn smooth_scroll(&mut self, x: Coord, y: Coord) -> Result<()> {
586 self.gradual_scroll_raw(x, y)
587 }
588
589 #[inline]
590 pub fn buffered_gradual_scroll(&mut self, x: Coord, y: Coord) -> Vec<EventParams> {
591 let mut write_buffer: Vec<EventParams> = vec![];
592 let gradual_move = GradualMove::calculate(x, y);
593
594 for _ in 0..gradual_move.both_move {
595 write_buffer.extend(self.buffered_scroll_x(gradual_move.x_direction));
596 write_buffer.extend(self.buffered_scroll_y(gradual_move.y_direction));
597 }
598 for _ in 0..gradual_move.move_only_x {
599 write_buffer.extend(self.buffered_scroll_x(gradual_move.x_direction));
600 }
601 for _ in 0..gradual_move.move_only_y {
602 write_buffer.extend(self.buffered_scroll_y(gradual_move.y_direction));
603 }
604
605 write_buffer
606 }
607
608 #[inline]
609 pub fn scroll_y(&mut self, value: Coord) -> EmptyResult {
610 self.write_batch(&[
611 (EV_REL, REL_WHEEL, value),
612 SYN_PARAMS
613 ])
614 }
615
616 #[inline]
617 pub fn buffered_press(&mut self, button: Button) -> Vec<EventParams> {
618 vec![
619 (EV_KEY, button, 1),
620 SYN_PARAMS
621 ]
622 }
623
624 #[inline]
625 pub fn buffered_release(&mut self, button: Button) -> Vec<EventParams> {
626 vec![
627 (EV_KEY, button, 0),
628 SYN_PARAMS
629 ]
630 }
631
632 #[inline]
633 pub fn press(&mut self, button: Button) -> EmptyResult {
634 self.write_batch(&[
635 (EV_KEY, button, 1),
636 SYN_PARAMS
637 ])
638 }
639
640 #[inline]
641 pub fn release(&mut self, button: Button) -> EmptyResult {
642 self.write_batch(&[
643 (EV_KEY, button, 0),
644 SYN_PARAMS
645 ])
646 }
647
648 pub fn click(&mut self, button: Button) -> EmptyResult {
649 self.press(button)?;
650 sleep(SLEEP_BEFORE_RELEASE); self.release(button)
652 }
653}
654
655impl Drop for VirtualDevice {
656 fn drop(&mut self) {
657 unsafe {
658 ui_dev_destroy(self.file.as_raw_fd());
659 }
660 }
661}