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