use crate::macro_writer::MacroWriter; use crate::x11_safe_wrapper::XDisplay; use crate::{Instructions, Keycode, Position}; use std::mem; use std::time; use x11::xlib; use x11::xrecord::{XRecordContext, XRecordInterceptData}; #[repr(C)] pub struct EvCallbackData { pub writer: MacroWriter, pub xdpy: XDisplay, pub recdpy: XDisplay, pub ctx: XRecordContext, pub working: bool, pub last_event: xlib::Time, pub pos: Position, pub stop_key: Keycode, pub ev_nr: u32, pub max_delay: Option, pub no_keypress_yet: bool, pub moving: bool, } impl EvCallbackData { pub fn new( writer: MacroWriter, xdpy: XDisplay, recdpy: XDisplay, ctx: XRecordContext, stop_key: Keycode, pos: Position, max_delay: Option, ) -> Self { EvCallbackData { writer, xdpy, recdpy, ctx, stop_key, ev_nr: 0, working: true, pos, max_delay, no_keypress_yet: true, last_event: time::SystemTime::now() .duration_since(time::UNIX_EPOCH) .unwrap() .as_millis() as xlib::Time, moving: false, } } pub fn ptr_is_moving(&self) -> bool { self.moving } pub unsafe fn update_pos( &mut self, intercept_data: &mut XRecordInterceptData, ) -> Position { self.pos.0 = *((intercept_data.data as usize + mem::size_of::() * 10) as *const i16); self.pos.1 = *((intercept_data.data as usize + mem::size_of::() * 11) as *const i16); self.pos } pub fn write_pos(&mut self) { self.writer.write(Instructions::MotionNotify(self.pos)); self.moving = false; } pub fn maybe_write_delay(&mut self, server_time: xlib::Time) { if server_time - self.last_event > 1 { self.writer.write(Instructions::Delay(calculate_delay( server_time, self.last_event, self.max_delay, ))); self.last_event = server_time; } } } fn calculate_delay(server_time: xlib::Time, last_event: xlib::Time, max_delay: Option) -> xlib::Time { if let Some(max) = max_delay { let max = max as u64; let delay = server_time - last_event; if delay > max { max } else { delay } } else { server_time - last_event } }