1use crate::error::Result;
4use crate::hid::MouseReport;
5use crate::platform::HidBackend;
6use crate::Device;
7use bitflags::bitflags;
8use serde::{Deserialize, Serialize};
9
10bitflags! {
11 #[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
13 pub struct MouseButton: u8 {
14 const LEFT = 0x01;
15 const RIGHT = 0x02;
16 const MIDDLE = 0x04;
17 const BUTTON4 = 0x08;
18 const BUTTON5 = 0x10;
19 }
20}
21
22pub struct Mouse {
24 backend: Option<Box<dyn HidBackend>>,
25 report: MouseReport,
26 name: String,
27}
28
29impl Mouse {
30 pub fn new() -> Self {
32 Self::with_name("useHID Virtual Mouse")
33 }
34
35 pub fn with_name(name: &str) -> Self {
37 Self {
38 backend: None,
39 report: MouseReport::default(),
40 name: name.to_string(),
41 }
42 }
43
44 pub fn move_by(&mut self, dx: i32, dy: i32) -> Result<()> {
46 let steps_x = (dx.abs() + 126) / 127;
48 let steps_y = (dy.abs() + 126) / 127;
49 let steps = steps_x.max(steps_y).max(1);
50
51 for i in 0..steps {
52 let x = if i < steps_x {
53 (dx.signum() * (dx.abs() / steps).min(127)) as i8
54 } else {
55 0
56 };
57 let y = if i < steps_y {
58 (dy.signum() * (dy.abs() / steps).min(127)) as i8
59 } else {
60 0
61 };
62
63 self.report.x = x;
64 self.report.y = y;
65 self.send_report()?;
66 }
67
68 self.report.x = 0;
69 self.report.y = 0;
70 Ok(())
71 }
72
73 pub fn press(&mut self, button: MouseButton) -> Result<()> {
75 self.report.buttons |= button.bits();
76 self.send_report()
77 }
78
79 pub fn release(&mut self, button: MouseButton) -> Result<()> {
81 self.report.buttons &= !button.bits();
82 self.send_report()
83 }
84
85 pub fn click(&mut self, button: MouseButton) -> Result<()> {
87 self.press(button)?;
88 std::thread::sleep(std::time::Duration::from_millis(10));
89 self.release(button)
90 }
91
92 pub fn double_click(&mut self, button: MouseButton) -> Result<()> {
94 self.click(button)?;
95 std::thread::sleep(std::time::Duration::from_millis(50));
96 self.click(button)
97 }
98
99 pub fn scroll(&mut self, delta: i8) -> Result<()> {
101 self.report.wheel = delta;
102 self.send_report()?;
103 self.report.wheel = 0;
104 Ok(())
105 }
106
107 fn send_report(&self) -> Result<()> {
108 if let Some(backend) = &self.backend {
109 backend.send_report(self.report.as_bytes())
110 } else {
111 Err(crate::error::Error::DeviceNotCreated)
112 }
113 }
114}
115
116impl Default for Mouse {
117 fn default() -> Self {
118 Self::new()
119 }
120}
121
122impl Device for Mouse {
123 fn create(&mut self) -> Result<()> {
124 if self.backend.is_some() {
125 return Err(crate::error::Error::DeviceAlreadyExists);
126 }
127
128 let backend = crate::platform::create_mouse_backend(&self.name)?;
129 self.backend = Some(backend);
130 Ok(())
131 }
132
133 fn destroy(&mut self) -> Result<()> {
134 if let Some(backend) = self.backend.take() {
135 backend.destroy()
136 } else {
137 Err(crate::error::Error::DeviceNotCreated)
138 }
139 }
140
141 fn is_created(&self) -> bool {
142 self.backend.is_some()
143 }
144}