7MWGEO4D53CRQYELJQJ3PMI3BZJNAJJRX7AESNZ4NMF23XGBFEGAC
Q5YCA2QNTHQ236GPBNSWIE7U5YAIGSOD4Z5S2EP547WHTDNVR66QC
SO2VFZUJI2CLGDHNDLJIEPCQKFDP4TOH6WREPVJYPEVJ66EITDMQC
LSQ7OPL7Z5WJDO7ZZS3D4UPMEEWUUF2LNQ3FZUWWFUVZEXA7CIOAC
BQFOYJRTLAFIBZ3SOERSUB2ZXMXJUAROXOGMGWHJW4CVBRT4R5QAC
H36WAZXM2LZAJGYPRRMJUUQTER6RUOV4YXJDFXBZOHG73UPA7M5AC
6WLPW4L4PN6ANYYW3I6AOCN3SXQP37RQTUOM52IVXL3SRZD7UHAAC
YYUB6HZYSVQSCO7DGF6ETPAXTMG6SG2RQQXLP73NKPLDMZEC3PGAC
7RMAZDLQ6FEEQGUUAIVEM4X2VME7IUUZMEJMMV3H46U3UKO4BODQC
K3I54HXNNCTEA7L6UGWIVBFB5TPZVZZXDBRSR2YZDIKREXQVWRIQC
KWR2TS2D7YN4LCGMQZ35V4WBLQDHAVSZJV3SZAIR5HQRSJAWLWCQC
RPECDMZ4O7MMU32H6Z7EW75GRVEQ6IJYNPWSV54HUPTCX5H7I26QC
JVO3ABY7VTFBUPUEPNXVSGWLCBJLPDHLSLZJEW2LSEOFUR5Z4RIAC
JUNCSETUHRAPHZYVBESYW4LTKL6EW3X4G73ILT736PWDXB45Z6GQC
7VYQARQVDMISCO5566F55TG5FIDSOO3JQEIKVOUKEFEU4X5HZNEAC
#[derive(Clone, Copy, Serialize, Deserialize, Debug)]
pub enum Selection {
Primary,
Clipboard,
}
// Query XInput2
unsafe {
let mut major_opcode = mem::uninitialized();
let mut first_event = mem::uninitialized();
let mut first_error = mem::uninitialized();
if (xlib.XQueryExtension)(display,
CString::new("XInputExtension").unwrap().as_ptr(),
&mut major_opcode,
&mut first_event,
&mut first_error,
) == xlib::False {
panic!("Failed to query XInputExtension");
};
}
// Query XFixes
let xfixes_event_base = unsafe {
let mut event_base: i32 = mem::uninitialized();
let mut error_base: i32 = mem::uninitialized();
if (xfixes.XFixesQueryExtension)(display,
&mut event_base,
&mut error_base,
) == xlib::False {
panic!("Failed to query XFixes");
}
// Setup default events
fn init(&self) {
// Initialize last_pos for computing cursor deltas
self.last_pos.set(self.cursor_pos());
// Setup selection events
self.select_selection_input(self.root, xlib::XA_PRIMARY, xfixes::XFixesSetSelectionOwnerNotifyMask);
self.select_selection_input(self.root, self.clipboard, xfixes::XFixesSetSelectionOwnerNotifyMask);
// Setup raw motion events
fn recv_selection_event(&self, event: xfixes::XFixesSelectionNotifyEvent) -> Option<HostEvent> {
match event.subtype {
xfixes::XFixesSetSelectionOwnerNotify => {
if event.selection == xlib::XA_PRIMARY {
Some(HostEvent::Selection(Selection::Primary))
} else if event.selection == self.clipboard {
Some(HostEvent::Selection(Selection::Clipboard))
} else {
warn!("Unexpected selection source: {}", event.selection);
None
}
},
subtype => {
warn!("Unexpected XFixesSelection sub event: {}", subtype);
None
}
}
}
match event.get_type() {
xlib::GenericEvent => self.recv_generic_event(From::from(event)),
xlib::ButtonPress => self.recv_button_event(From::from(event), true),
xlib::ButtonRelease => self.recv_button_event(From::from(event), false),
xlib::KeyPress => self.recv_key_event(From::from(event), true),
xlib::KeyRelease => self.recv_key_event(From::from(event), false),
xlib::MappingNotify => None,
event => {
warn!("Unexpected X11 event: {}", event);
None
},
}
let event_type = event.get_type();
// Standard events
match event_type {
xlib::GenericEvent => return self.recv_generic_event(From::from(event)),
xlib::ButtonPress => return self.recv_button_event(From::from(event), true),
xlib::ButtonRelease => return self.recv_button_event(From::from(event), false),
xlib::KeyPress => return self.recv_key_event(From::from(event), true),
xlib::KeyRelease => return self.recv_key_event(From::from(event), false),
xlib::MappingNotify => return None,
_ => (),
};
// XFixes selection events
match event_type - self.xfixes_event_base {
xfixes::XFixesSelectionNotify => return self.recv_selection_event(From::from(event)),
_ => (),
};
warn!("Unexpected X11 event: {}", event_type);
None