1use crate::coordinates::{CoordinateTransformer, MonitorInfo};
7use crate::error::{InputError, Result};
8use crate::keyboard::{KeyModifiers, KeyboardEvent, KeyboardHandler};
9use crate::mouse::{MouseButton, MouseEvent, MouseHandler};
10use std::time::Instant;
11use tracing::{debug, warn};
12
13#[derive(Debug, Clone)]
15pub enum RdpInputEvent {
16 KeyboardScancode {
18 scancode: u16,
20 extended: bool,
22 e1_prefix: bool,
24 pressed: bool,
26 },
27
28 MouseMove {
30 x: u32,
32 y: u32,
34 },
35
36 MouseMoveRelative {
38 delta_x: i32,
40 delta_y: i32,
42 },
43
44 MouseButton {
46 button: u16,
48 pressed: bool,
50 },
51
52 MouseWheel {
54 delta_x: i32,
56 delta_y: i32,
58 },
59}
60
61#[derive(Debug, Clone)]
63pub enum LinuxInputEvent {
64 Keyboard {
66 event_type: KeyboardEventType,
68 keycode: u32,
70 scancode: u16,
72 modifiers: KeyModifiers,
74 timestamp: Instant,
76 },
77
78 MouseMove {
80 x: f64,
82 y: f64,
84 timestamp: Instant,
86 },
87
88 MouseButton {
90 button_code: u32,
92 button: MouseButton,
94 pressed: bool,
96 timestamp: Instant,
98 },
99
100 MouseWheel {
102 delta_x: i32,
104 delta_y: i32,
106 timestamp: Instant,
108 },
109}
110
111#[derive(Debug, Clone, Copy, PartialEq, Eq)]
113pub enum KeyboardEventType {
114 KeyDown,
116 KeyUp,
118 KeyRepeat,
120}
121
122pub struct InputTranslator {
124 keyboard: KeyboardHandler,
126
127 mouse: MouseHandler,
129
130 coord_transformer: CoordinateTransformer,
132
133 events_processed: u64,
135
136 events_this_second: u64,
138
139 last_eps_time: Instant,
141}
142
143impl InputTranslator {
144 pub fn new(monitors: Vec<MonitorInfo>) -> Result<Self> {
146 Ok(Self {
147 keyboard: KeyboardHandler::new(),
148 mouse: MouseHandler::new(),
149 coord_transformer: CoordinateTransformer::new(monitors)?,
150 events_processed: 0,
151 events_this_second: 0,
152 last_eps_time: Instant::now(),
153 })
154 }
155
156 pub fn translate_event(&mut self, event: RdpInputEvent) -> Result<LinuxInputEvent> {
158 self.events_processed += 1;
159 self.events_this_second += 1;
160
161 if self.last_eps_time.elapsed().as_secs() >= 1 {
163 debug!("Input events per second: {}", self.events_this_second);
164 self.events_this_second = 0;
165 self.last_eps_time = Instant::now();
166 }
167
168 match event {
169 RdpInputEvent::KeyboardScancode {
170 scancode,
171 extended,
172 e1_prefix,
173 pressed,
174 } => self.translate_keyboard(scancode, extended, e1_prefix, pressed),
175
176 RdpInputEvent::MouseMove { x, y } => self.translate_mouse_move(x, y),
177
178 RdpInputEvent::MouseMoveRelative { delta_x, delta_y } => {
179 self.translate_mouse_move_relative(delta_x, delta_y)
180 }
181
182 RdpInputEvent::MouseButton { button, pressed } => self.translate_mouse_button(button, pressed),
183
184 RdpInputEvent::MouseWheel { delta_x, delta_y } => self.translate_mouse_wheel(delta_x, delta_y),
185 }
186 }
187
188 fn translate_keyboard(
190 &mut self,
191 scancode: u16,
192 extended: bool,
193 e1_prefix: bool,
194 pressed: bool,
195 ) -> Result<LinuxInputEvent> {
196 let kbd_event = if pressed {
197 self.keyboard.handle_key_down(scancode, extended, e1_prefix)?
198 } else {
199 self.keyboard.handle_key_up(scancode, extended, e1_prefix)?
200 };
201
202 match kbd_event {
203 KeyboardEvent::KeyDown {
204 keycode,
205 scancode,
206 modifiers,
207 timestamp,
208 } => Ok(LinuxInputEvent::Keyboard {
209 event_type: KeyboardEventType::KeyDown,
210 keycode,
211 scancode,
212 modifiers,
213 timestamp,
214 }),
215
216 KeyboardEvent::KeyUp {
217 keycode,
218 scancode,
219 modifiers,
220 timestamp,
221 } => Ok(LinuxInputEvent::Keyboard {
222 event_type: KeyboardEventType::KeyUp,
223 keycode,
224 scancode,
225 modifiers,
226 timestamp,
227 }),
228
229 KeyboardEvent::KeyRepeat {
230 keycode,
231 scancode,
232 modifiers,
233 timestamp,
234 } => Ok(LinuxInputEvent::Keyboard {
235 event_type: KeyboardEventType::KeyRepeat,
236 keycode,
237 scancode,
238 modifiers,
239 timestamp,
240 }),
241 }
242 }
243
244 fn translate_mouse_move(&mut self, x: u32, y: u32) -> Result<LinuxInputEvent> {
246 let mouse_event = self.mouse.handle_absolute_move(x, y, &mut self.coord_transformer)?;
247
248 match mouse_event {
249 MouseEvent::Move { x, y, timestamp } => Ok(LinuxInputEvent::MouseMove { x, y, timestamp }),
250 _ => Err(InputError::InvalidState("Unexpected mouse event type".to_string())),
251 }
252 }
253
254 fn translate_mouse_move_relative(&mut self, delta_x: i32, delta_y: i32) -> Result<LinuxInputEvent> {
256 let mouse_event = self
257 .mouse
258 .handle_relative_move(delta_x, delta_y, &mut self.coord_transformer)?;
259
260 match mouse_event {
261 MouseEvent::Move { x, y, timestamp } => Ok(LinuxInputEvent::MouseMove { x, y, timestamp }),
262 _ => Err(InputError::InvalidState("Unexpected mouse event type".to_string())),
263 }
264 }
265
266 fn translate_mouse_button(&mut self, button_flags: u16, pressed: bool) -> Result<LinuxInputEvent> {
268 let button = MouseButton::from_rdp_button(button_flags).ok_or_else(|| {
269 warn!("Unknown RDP mouse button: 0x{:04X}", button_flags);
270 InputError::Unknown(format!("Unknown mouse button: 0x{:04X}", button_flags))
271 })?;
272
273 let mouse_event = if pressed {
274 self.mouse.handle_button_down(button)?
275 } else {
276 self.mouse.handle_button_up(button)?
277 };
278
279 match mouse_event {
280 MouseEvent::ButtonDown { button, timestamp } => Ok(LinuxInputEvent::MouseButton {
281 button_code: button.to_linux_button(),
282 button,
283 pressed: true,
284 timestamp,
285 }),
286
287 MouseEvent::ButtonUp { button, timestamp } => Ok(LinuxInputEvent::MouseButton {
288 button_code: button.to_linux_button(),
289 button,
290 pressed: false,
291 timestamp,
292 }),
293
294 _ => Err(InputError::InvalidState("Unexpected mouse event type".to_string())),
295 }
296 }
297
298 fn translate_mouse_wheel(&mut self, delta_x: i32, delta_y: i32) -> Result<LinuxInputEvent> {
300 let mouse_event = self.mouse.handle_scroll(delta_x, delta_y)?;
301
302 match mouse_event {
303 MouseEvent::Scroll {
304 delta_x,
305 delta_y,
306 timestamp,
307 } => Ok(LinuxInputEvent::MouseWheel {
308 delta_x,
309 delta_y,
310 timestamp,
311 }),
312 _ => Err(InputError::InvalidState("Unexpected mouse event type".to_string())),
313 }
314 }
315
316 pub fn update_monitors(&mut self, monitors: Vec<MonitorInfo>) -> Result<()> {
318 self.coord_transformer.update_monitors(monitors)
319 }
320
321 pub fn set_keyboard_layout(&mut self, layout: &str) {
323 self.keyboard.set_layout(layout);
324 }
325
326 pub fn keyboard_layout(&self) -> &str {
328 self.keyboard.layout()
329 }
330
331 pub fn set_mouse_acceleration(&mut self, enabled: bool) {
333 self.coord_transformer.set_acceleration_enabled(enabled);
334 }
335
336 pub fn set_mouse_acceleration_factor(&mut self, factor: f64) {
338 self.coord_transformer.set_acceleration_factor(factor);
339 }
340
341 pub fn set_high_precision_scroll(&mut self, enabled: bool) {
343 self.mouse.set_high_precision_scroll(enabled);
344 }
345
346 pub fn reset(&mut self) {
348 self.keyboard.reset();
349 self.mouse.reset();
350 debug!("Input translator reset");
351 }
352
353 pub fn events_processed(&self) -> u64 {
355 self.events_processed
356 }
357
358 pub fn mouse_position(&self) -> (f64, f64) {
360 self.mouse.current_position()
361 }
362
363 pub fn keyboard_modifiers(&self) -> KeyModifiers {
365 self.keyboard.modifiers()
366 }
367
368 pub fn monitor_count(&self) -> usize {
370 self.coord_transformer.monitor_count()
371 }
372}
373
374#[cfg(test)]
375mod tests {
376 use super::*;
377
378 fn create_test_monitor() -> MonitorInfo {
379 MonitorInfo {
380 id: 1,
381 name: "Primary".to_string(),
382 x: 0,
383 y: 0,
384 width: 1920,
385 height: 1080,
386 dpi: 96.0,
387 scale_factor: 1.0,
388 stream_x: 0,
389 stream_y: 0,
390 stream_width: 1920,
391 stream_height: 1080,
392 is_primary: true,
393 }
394 }
395
396 #[test]
397 fn test_translator_creation() {
398 let translator = InputTranslator::new(vec![create_test_monitor()]).unwrap();
399 assert_eq!(translator.events_processed(), 0);
400 assert_eq!(translator.monitor_count(), 1);
401 }
402
403 #[test]
404 fn test_translate_keyboard_event() {
405 let mut translator = InputTranslator::new(vec![create_test_monitor()]).unwrap();
406
407 let event = RdpInputEvent::KeyboardScancode {
409 scancode: 0x1E, extended: false,
411 e1_prefix: false,
412 pressed: true,
413 };
414
415 let result = translator.translate_event(event).unwrap();
416
417 match result {
418 LinuxInputEvent::Keyboard {
419 event_type, keycode, ..
420 } => {
421 assert_eq!(event_type, KeyboardEventType::KeyDown);
422 assert!(keycode > 0);
423 }
424 _ => panic!("Expected Keyboard event"),
425 }
426
427 assert_eq!(translator.events_processed(), 1);
428 }
429
430 #[test]
431 fn test_translate_mouse_move() {
432 let mut translator = InputTranslator::new(vec![create_test_monitor()]).unwrap();
433
434 let event = RdpInputEvent::MouseMove { x: 960, y: 540 };
435
436 let result = translator.translate_event(event).unwrap();
437
438 match result {
439 LinuxInputEvent::MouseMove { x, y, .. } => {
440 assert!(x >= 0.0);
441 assert!(y >= 0.0);
442 }
443 _ => panic!("Expected MouseMove event"),
444 }
445 }
446
447 #[test]
448 fn test_translate_mouse_button() {
449 let mut translator = InputTranslator::new(vec![create_test_monitor()]).unwrap();
450
451 let event = RdpInputEvent::MouseButton {
452 button: 0x1000, pressed: true,
454 };
455
456 let result = translator.translate_event(event).unwrap();
457
458 match result {
459 LinuxInputEvent::MouseButton {
460 button,
461 pressed,
462 button_code,
463 ..
464 } => {
465 assert_eq!(button, MouseButton::Left);
466 assert!(pressed);
467 assert_eq!(button_code, 0x110);
468 }
469 _ => panic!("Expected MouseButton event"),
470 }
471 }
472
473 #[test]
474 fn test_translate_mouse_wheel() {
475 let mut translator = InputTranslator::new(vec![create_test_monitor()]).unwrap();
476
477 let event = RdpInputEvent::MouseWheel {
478 delta_x: 0,
479 delta_y: 120,
480 };
481
482 let result = translator.translate_event(event).unwrap();
483
484 match result {
485 LinuxInputEvent::MouseWheel { delta_y, .. } => {
486 assert_eq!(delta_y, 1);
487 }
488 _ => panic!("Expected MouseWheel event"),
489 }
490 }
491
492 #[test]
493 fn test_keyboard_modifiers() {
494 let mut translator = InputTranslator::new(vec![create_test_monitor()]).unwrap();
495
496 let event = RdpInputEvent::KeyboardScancode {
498 scancode: 0x2A, extended: false,
500 e1_prefix: false,
501 pressed: true,
502 };
503
504 translator.translate_event(event).unwrap();
505
506 let modifiers = translator.keyboard_modifiers();
507 assert!(modifiers.shift);
508 }
509
510 #[test]
511 fn test_layout_change() {
512 let mut translator = InputTranslator::new(vec![create_test_monitor()]).unwrap();
513
514 assert_eq!(translator.keyboard_layout(), "us");
515
516 translator.set_keyboard_layout("de");
517 assert_eq!(translator.keyboard_layout(), "de");
518 }
519
520 #[test]
521 fn test_reset() {
522 let mut translator = InputTranslator::new(vec![create_test_monitor()]).unwrap();
523
524 translator
526 .translate_event(RdpInputEvent::KeyboardScancode {
527 scancode: 0x1E,
528 extended: false,
529 e1_prefix: false,
530 pressed: true,
531 })
532 .unwrap();
533
534 translator.reset();
536
537 let modifiers = translator.keyboard_modifiers();
538 assert!(!modifiers.shift);
539 assert!(!modifiers.ctrl);
540 }
541
542 #[test]
543 fn test_events_counter() {
544 let mut translator = InputTranslator::new(vec![create_test_monitor()]).unwrap();
545
546 for i in 0..10 {
547 translator
548 .translate_event(RdpInputEvent::MouseMove { x: i * 100, y: i * 100 })
549 .unwrap();
550 }
551
552 assert_eq!(translator.events_processed(), 10);
553 }
554
555 #[test]
556 fn test_mouse_position_tracking() {
557 let mut translator = InputTranslator::new(vec![create_test_monitor()]).unwrap();
558
559 translator
560 .translate_event(RdpInputEvent::MouseMove { x: 100, y: 200 })
561 .unwrap();
562
563 let (x, y) = translator.mouse_position();
564 assert!(x >= 0.0);
565 assert!(y >= 0.0);
566 }
567}