2JZYL7R4OQIZMHTBGZA6HNAC7KLN7DSGZJRE7YILLMTR3WR2XLHAC 42CBEYZTGKPTDFNBTNCBUWWCABZOMBY3FCWWHUILQIGO2M54OJXQC SMM42WXFAYFMOMUR7DCVCZCK7QMXIE5KUH4GUOIZPVFDDYB4ZMZAC AWPTZQQYEYW2BMXCWYAWSZAVUE55YOMO7IE4VCXP5J4UOKUMKQFAC M2FGQSGQITI7FYU3RWY3IGIA4ZLS6JAZMHIO64WNHKS4JIL53OWQC AGPU6SD7V5FQNI6W54HDRJQCVHWYCZIHDHL6IL5LVVMJ7SVJL7UAC KWR2TS2D7YN4LCGMQZ35V4WBLQDHAVSZJV3SZAIR5HQRSJAWLWCQC 2DG7PVTZAJ4NMGY2BNODJRLYTOV3MPTH3V6EZMK3WSIUZESLPQXQC VODZCAIINDFQAU6RUV5VBRGJSMCWNMYAQ3ZE56SNBYU2WOSHFOMAC BQFOYJRTLAFIBZ3SOERSUB2ZXMXJUAROXOGMGWHJW4CVBRT4R5QAC LSQ7OPL7Z5WJDO7ZZS3D4UPMEEWUUF2LNQ3FZUWWFUVZEXA7CIOAC YYUB6HZYSVQSCO7DGF6ETPAXTMG6SG2RQQXLP73NKPLDMZEC3PGAC AYQYCR7JKWTAZASLQTY5DPVI6A5MN6X4XMPC3GBS5KJRH3EGRPIQC RPECDMZ4O7MMU32H6Z7EW75GRVEQ6IJYNPWSV54HUPTCX5H7I26QC K3I54HXNNCTEA7L6UGWIVBFB5TPZVZZXDBRSR2YZDIKREXQVWRIQC 7RMAZDLQ6FEEQGUUAIVEM4X2VME7IUUZMEJMMV3H46U3UKO4BODQC LKAUS67VU5SLG5O5MTSO6N4VVT5OB2X4VNR6HYLIJ3ZOAXRQ4Q2QC 7MWGEO4D53CRQYELJQJ3PMI3BZJNAJJRX7AESNZ4NMF23XGBFEGAC JVO3ABY7VTFBUPUEPNXVSGWLCBJLPDHLSLZJEW2LSEOFUR5Z4RIAC JUNCSETUHRAPHZYVBESYW4LTKL6EW3X4G73ILT736PWDXB45Z6GQC ZJ22USKSC26EQ25RKGXJCRYR7RG65YNAVZ5TKN5WY6ADVAXB5YJAC [[package]]name = "futures"version = "0.3.5"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "1e05b85ec287aac0dc34db7d4a569323df697f9c55b99b15d6b4ef8cde49f613"dependencies = ["futures-channel","futures-core","futures-executor","futures-io","futures-sink","futures-task","futures-util",]
[[package]]name = "futures-executor"version = "0.3.5"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "10d6bb888be1153d3abeb9006b11b02cf5e9b209fda28693c31ae1e4e012e314"dependencies = ["futures-core","futures-task","futures-util",][[package]]name = "futures-io"version = "0.3.5"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "de27142b013a8e869c14957e6d2edeef89e97c289e69d042ee3a49acd8b51789"[[package]]name = "futures-macro"version = "0.3.5"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "d0b5a30a4328ab5473878237c447333c093297bded83a4983d10f4deea240d39"dependencies = ["proc-macro-hack","proc-macro2","quote","syn",]
name = "futures-sink"version = "0.3.5"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "3f2032893cb734c7a05d85ce0cc8b8c4075278e93b24b66f9de99d6eb0fa8acc"[[package]]name = "futures-task"version = "0.3.5"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "bdb66b5f09e22019b1ab0830f7785bcea8e7a42148683f99214f73f8ec21a626"dependencies = ["once_cell",][[package]]name = "futures-util"version = "0.3.5"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "8764574ff08b701a084482c3c7031349104b07ac897393010494beaa18ce32c6"dependencies = ["futures-channel","futures-core","futures-io","futures-macro","futures-sink","futures-task","memchr","pin-project","pin-utils","proc-macro-hack","proc-macro-nested","slab",][[package]]
name = "pin-project"version = "0.4.23"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "ca4433fff2ae79342e497d9f8ee990d174071408f28f726d6d83af93e58e48aa"dependencies = ["pin-project-internal",][[package]]name = "pin-project-internal"version = "0.4.23"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "2c0e815c3ee9a031fdf5af21c10aa17c573c9c6a566328d99e3936c34e36461f"dependencies = ["proc-macro2","quote","syn",][[package]]
name = "pin-utils"version = "0.1.0"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"[[package]]name = "proc-macro-hack"version = "0.5.18"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "99c605b9a0adc77b7211c6b1f722dcb613d68d66859a44f3d485a6da332b0598"[[package]]name = "proc-macro-nested"version = "0.1.6"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "eba180dafb9038b050a4c280019bbedf9f2467b61e5d892dcad585bb57aadc5a"[[package]]
pub fn refocus<H>(&mut self, host: &H, focus: Focus) whereH: HostInterface{let was_focused = self.locally_focused();self.private_refocus(host, focus, was_focused);}
// pub fn refocus<H>(&mut self, host: &H, focus: Focus) where// H: HostInterface// {// let was_focused = self.locally_focused();// self.private_refocus(host, focus, was_focused);// }
fn private_refocus<H>(&mut self, host: &H, focus: Focus, was_focused: bool) whereH: HostInterface{self.focus = self.normalize_focus(focus);if self.locally_focused() {if !was_focused {host.ungrab_cursor();host.ungrab_keyboard();}
// fn private_refocus<H>(&mut self, host: &H, focus: Focus, was_focused: bool) where// H: HostInterface// {// self.focus = self.normalize_focus(focus);// if self.locally_focused() {// if !was_focused {// host.ungrab_cursor();// host.ungrab_keyboard();// }
host.send_event(HostEvent::Position(PositionEvent {x: self.focus.pos.x, y: self.focus.pos.y,}));} else {if was_focused {host.grab_cursor();host.grab_keyboard();}}}
// host.send_event(HostEvent::Position(PositionEvent {// x: self.focus.pos.x, y: self.focus.pos.y,// }));// } else {// if was_focused {// host.grab_cursor();// host.grab_keyboard();// }// }// }
use x11_dl::xfixes;use x11_dl::xinput2;use x11_dl::xlib;use x11_dl::xtest;
use tokio::io::PollEvented;use x11_dl::{xfixes,xinput2,xlib,xtest,};
let xlib = xlib::Xlib::open().unwrap();let xtest = xtest::Xf86vmode::open().unwrap();let xinput2 = xinput2::XInput2::open().unwrap();let xfixes = xfixes::XFixes::open().unwrap();
unsafe {let xlib = xlib::Xlib::open().unwrap();let display = (xlib.XOpenDisplay)(ptr::null());if display.is_null() {panic!("Failed to open display");}let io = PollEvented::new(Connection {fd: (xlib.XConnectionNumber)(display)}).unwrap();let root = (xlib.XDefaultRootWindow)(display);
let display = unsafe { (xlib.XOpenDisplay)(ptr::null()) };if display.is_null() {panic!("Failed to open display");}
// Query Xlet xfixes = xfixes::XFixes::open().unwrap();let xfixes_event_base = {let mut event_base = MaybeUninit::uninit();if (xfixes.XFixesQueryExtension)(display,event_base.as_mut_ptr(),ptr::null_mut(),) == xlib::False {panic!("Failed to query XFixes");}
// Query XInput2unsafe {let mut major_opcode = MaybeUninit::uninit();let mut first_event = MaybeUninit::uninit();let mut first_error = MaybeUninit::uninit();if (xlib.XQueryExtension)(display,CString::new("XInputExtension").unwrap().as_ptr(),major_opcode.as_mut_ptr(),first_event.as_mut_ptr(),first_error.as_mut_ptr(),) == xlib::False {panic!("Failed to query XInputExtension");
event_base.assume_init()
// Query XFixeslet xfixes_event_base = unsafe {let mut event_base = MaybeUninit::uninit();let mut error_base = MaybeUninit::uninit();if (xfixes.XFixesQueryExtension)(display,event_base.as_mut_ptr(),error_base.as_mut_ptr(),) == xlib::False {panic!("Failed to query XFixes");}
// Setup selection events(xfixes.XFixesSelectSelectionInput)(display,root,xlib::XA_PRIMARY,xfixes::XFixesSetSelectionOwnerNotifyMask);
let root = unsafe { (xlib.XDefaultRootWindow)(display) };let clipboard = unsafe { (xlib.XInternAtom)(display, CString::new("CLIPBOARD").unwrap().as_ptr(), 0) };
(xfixes.XFixesSelectSelectionInput)(display,root,clipboard,xfixes::XFixesSetSelectionOwnerNotifyMask);
let host = Self {xlib,xtest,xinput2,xfixes,xfixes_event_base,
// Query XInput2let xinput2 = xinput2::XInput2::open().unwrap();if (xlib.XQueryExtension)(display,CString::new("XInputExtension").unwrap().as_ptr(),ptr::null_mut(),ptr::null_mut(),ptr::null_mut(),) == xlib::False {panic!("Failed to query XInputExtension");};
// Setup selection eventsself.select_selection_input(self.root, xlib::XA_PRIMARY, xfixes::XFixesSetSelectionOwnerNotifyMask);self.select_selection_input(self.root, self.clipboard, xfixes::XFixesSetSelectionOwnerNotifyMask);
let host = Self {xlib,display,io,root,clipboard,
fn next_event(&self) -> xlib::XEvent {unsafe {let mut event = MaybeUninit::uninit();(self.xlib.XNextEvent)(self.display, event.as_mut_ptr());event.assume_init()
fn map_button_event(event: xlib::XButtonEvent, state: bool) -> ButtonEvent {ButtonEvent {button: event.button,state,
// xfixesfn select_selection_input(&self, window: xlib::Window, atom: xlib::Atom, event_mask: u64) {unsafe { (self.xfixes.XFixesSelectSelectionInput)(self.display, window, atom, event_mask) };
fn map_key_event(&self, event: xlib::XKeyEvent, state: bool) -> KeyEvent {let key = unsafe {(self.xlib.XKeycodeToKeysym)(self.display, event.keycode as u8, 0)};KeyEvent {key,state,}
// xinput2fn select_events(&self, window: xlib::Window, mask: &mut [xinput2::XIEventMask]) {unsafe { (self.xinput2.XISelectEvents)(self.display, window,&mut mask[0] as *mut xinput2::XIEventMask, mask.len() as i32) };
fn map_generic_event(&self, cookie: xlib::XGenericEventCookie) -> Option<HostEvent> {// FIXME: Check XInput2 extension in cookie.extensionmatch cookie.evtype {xinput2::XI_RawMotion => Some(HostEvent::Motion(self.map_raw_motion())),_ => None,}
fn recv_generic_event(&self, cookie: xlib::XGenericEventCookie) -> Option<HostEvent> {// FIXME: Assert XInput2 extension in cookie.extensionassert_eq!(cookie.evtype, xinput2::XI_RawMotion);
fn map_raw_motion(&self) -> MotionEvent {
Some(HostEvent::Motion(MotionEvent { dx, dy }))}fn recv_button_event(&self, event: xlib::XButtonEvent, state: bool) -> Option<HostEvent> {Some(HostEvent::Button(ButtonEvent {button: event.button,state,}))}
fn recv_key_event(&self, event: xlib::XKeyEvent, state: bool) -> Option<HostEvent> {let key = unsafe { (self.xlib.XKeycodeToKeysym)(self.display, event.keycode as u8, 0) };Some(HostEvent::Key(KeyEvent {key,state,}))
MotionEvent { dx, dy }
let screen = &*(self.xlib.XDefaultScreenOfDisplay)(self.display);assert!(screen.width > 0 && screen.height > 0);(screen.width, screen.height)
(self.xlib.XCloseDisplay)(self.display);
(self.xlib.XQueryPointer)(self.display, self.root,root.as_mut_ptr(), child.as_mut_ptr(),root_x.as_mut_ptr(), root_y.as_mut_ptr(),child_x.as_mut_ptr(), child_y.as_mut_ptr(),mask.as_mut_ptr());
(self.xlib.XQueryPointer)(self.display, self.root,ptr::null_mut(), ptr::null_mut(),root_x.as_mut_ptr(), root_y.as_mut_ptr(),ptr::null_mut(), ptr::null_mut(),ptr::null_mut());
unsafe { (self.xlib.XGrabKeyboard)(self.display, self.root, xlib::True,xlib::GrabModeAsync, xlib::GrabModeAsync, xlib::CurrentTime) };
unsafe {(self.xlib.XGrabKeyboard)(self.display, self.root, xlib::True,xlib::GrabModeAsync, xlib::GrabModeAsync, xlib::CurrentTime);}
fn recv_event(&self) -> Option<HostEvent> {
impl Stream for Host {type Item = HostEvent;fn poll_next(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Option<Self::Item>> {match self.io.poll_read_ready(cx, mio::Ready::readable()) {Poll::Ready(result) => result.unwrap(),Poll::Pending => return Poll::Pending,};
// Standard eventsmatch 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,_ => (),
let event = unsafe {let mut event = MaybeUninit::uninit();(self.xlib.XNextEvent)(self.display, event.as_mut_ptr());event.assume_init()
// XFixes selection eventsmatch event_type - self.xfixes_event_base {xfixes::XFixesSelectionNotify => return self.recv_selection_event(From::from(event)),_ => (),
let host_event = match event.get_type() {// Standard eventsxlib::ButtonPress => Some(HostEvent::Button(Self::map_button_event(event.into(), true))),xlib::ButtonRelease => Some(HostEvent::Button(Self::map_button_event(event.into(), false))),xlib::KeyPress => Some(HostEvent::Key(self.map_key_event(event.into(), true))),xlib::KeyRelease => Some(HostEvent::Key(self.map_key_event(event.into(), false))),xlib::MappingNotify => None,xlib::GenericEvent => self.map_generic_event(event.into()),// XFixes selection eventsevent_type if event_type - self.xfixes_event_base == xfixes::XFixesSelectionNotify =>self.map_selection_event(event.into()),event_type => {warn!("Unexpected X11 event: {}", event_type);None}
warn!("Unexpected X11 event: {}", event_type);None
fn poll_ready(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Result<(), Self::Error>> {match self.io.poll_write_ready(cx) {Poll::Ready(result) => Poll::Ready(result.map(|_| ())),Poll::Pending => Poll::Pending,}
event => warn!("Unexpected host event: {:?}", event),
HostEvent::Selection(_event) => todo!(),}Ok(())}fn poll_flush(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Result<(), Self::Error>> {match self.io.poll_write_ready(cx) {Poll::Ready(result) => Poll::Ready(result.map(|_| unsafe {(self.xlib.XFlush)(self.display);})),Poll::Pending => Poll::Pending,
// /*// * FIXME(Future):// * Method delegation: https://github.com/rust-lang/rfcs/pull/1406// */// impl Evented for X11Interface {// fn register(&self, selector: &mut Selector, token: Token, interest: EventSet, opts: PollOpt) -> io::Result<()> {// selector.register(self.connection_number(), token, interest, opts)// }
struct Connection {fd: RawFd,}
// fn reregister(&self, selector: &mut Selector, token: Token, interest: EventSet, opts: PollOpt) -> io::Result<()> {// selector.reregister(self.connection_number(), token, interest, opts)// }
impl mio::Evented for Connection {fn register(&self, poll: &mio::Poll, token: mio::Token, interest: mio::Ready, opts: mio::PollOpt)-> io::Result<()>{mio::unix::EventedFd(&self.fd).register(poll, token, interest, opts)}
// fn deregister(&self, selector: &mut Selector) -> io::Result<()> {// selector.deregister(self.connection_number())// }// }
fn reregister(&self, poll: &mio::Poll, token: mio::Token, interest: mio::Ready, opts: mio::PollOpt)-> io::Result<()>{mio::unix::EventedFd(&self.fd).reregister(poll, token, interest, opts)}
impl Drop for X11Interface {fn drop(&mut self) {unsafe { (self.xlib.XCloseDisplay)(self.display) };
fn deregister(&self, poll: &mio::Poll) -> io::Result<()> {mio::unix::EventedFd(&self.fd).deregister(poll)