87 lines
2 KiB
Rust
87 lines
2 KiB
Rust
|
use std::mem::size_of;
|
||
|
use std::time::{SystemTime, UNIX_EPOCH};
|
||
|
use x11::xlib::Time;
|
||
|
use x11::xrecord::{XRecordContext, XRecordInterceptData};
|
||
|
use crate::{Instructions, Keycode, Position};
|
||
|
use crate::macro_writer::MacroWriter;
|
||
|
use crate::x11_safe_wrapper::XDisplay;
|
||
|
|
||
|
#[repr(C)]
|
||
|
pub struct EvCallbackData {
|
||
|
pub writer: MacroWriter,
|
||
|
pub xdpy: XDisplay,
|
||
|
pub recdpy: XDisplay,
|
||
|
pub ctx: XRecordContext,
|
||
|
pub working: bool,
|
||
|
pub last_event: Time,
|
||
|
pub pos: Position<i16>,
|
||
|
pub stop_key: Keycode,
|
||
|
pub ev_nr: u32,
|
||
|
pub max_delay: Option<Time>,
|
||
|
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<i16>,
|
||
|
max_delay: Option<Time>,
|
||
|
) -> Self {
|
||
|
EvCallbackData {
|
||
|
writer,
|
||
|
xdpy,
|
||
|
recdpy,
|
||
|
ctx,
|
||
|
stop_key,
|
||
|
ev_nr: 0,
|
||
|
working: true,
|
||
|
pos,
|
||
|
max_delay,
|
||
|
no_keypress_yet: true,
|
||
|
last_event: SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_millis() as Time,
|
||
|
moving: false,
|
||
|
}
|
||
|
}
|
||
|
|
||
|
pub fn ptr_is_moving(&self) -> bool { self.moving }
|
||
|
|
||
|
pub unsafe fn update_pos(&mut self, intercept_data: &mut XRecordInterceptData) -> Position<i16> {
|
||
|
self.pos.0 = *((intercept_data.data as usize + size_of::<i16>() * 10) as *const i16);
|
||
|
self.pos.1 = *((intercept_data.data as usize + size_of::<i16>() * 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: 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: Time, last_event: Time, max_delay: Option<Time>) -> 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
|
||
|
}
|
||
|
}
|
||
|
|