1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
use std::sync::Arc; use std::sync::Mutex; use crate::ffi::xcb::*; use crate::cores::InputEvent; use xcb_event_mask_t::*; struct XcbInputInterpreterState { x_last: Option<i16>, y_last: Option<i16>, } impl Default for XcbInputInterpreterState { fn default() -> Self { Self { x_last: None, y_last: None, } } } pub struct XcbInputInterpreter { window: Arc<XcbWindow>, state: Arc<Mutex<XcbInputInterpreterState>>, } impl XcbInputInterpreter { pub fn new(window: &Arc<XcbWindow>) -> Self { Self { window: Arc::clone(window), state: Arc::new(Mutex::new(Default::default())) } } pub fn next(&self) -> Option<InputEvent> { let events = self.window.events(); let events = if let Some(events) = events { events } else { return None }; let event_types: Vec<&XcbEventType> = events.iter() .filter_map(|v| v.event_type()) .collect(); let mut state = self.state.lock().unwrap(); let motion = event_types.iter() .filter_map(|v| match v { XcbEventType::MotionNotify(event) => Some(event), _ => None, }) .fold((state.x_last, state.y_last, 0i64, 0i64), |acc, event| { if (event.state & XCB_EVENT_MASK_BUTTON_1_MOTION as u16) == 0 { return (Some(event.event_x), Some(event.event_y), acc.2, acc.3) } let (x_last, y_last, acc_x, acc_y) = acc; let dx = x_last .map(|x| event.event_x - x) .map(|dx| dx as i64) .map(|dx| dx + acc_x) .unwrap_or(0); let dy = y_last .map(|y| event.event_y - y) .map(|dy| dy as i64) .map(|dy| dy + acc_y) .unwrap_or(0); (Some(event.event_x), Some(event.event_y), dx, dy) }); let (x_last, y_last, dx, dy) = motion; state.x_last = x_last; state.y_last = y_last; if dx == 0 && dy == 0 { None } else { Some(InputEvent::MoveDelta(dx as f32, dy as f32)) } } }