basic input event decoding

This commit is contained in:
Ferdinand Schober
2023-12-20 02:47:37 +01:00
parent a129e27a26
commit b81e5806ab

View File

@@ -13,9 +13,11 @@ use crate::client::{ClientEvent, ClientHandle};
use tokio::io::unix::AsyncFd; use tokio::io::unix::AsyncFd;
use x11::xlib::{ use x11::xlib::{
self, KeyPressMask, KeyReleaseMask, PointerMotionMask, XWhitePixel, XCloseDisplay, self, CWBackPixel, CWEventMask, CWOverrideRedirect, CopyFromParent, EnterWindowMask,
XDefaultScreen, XNextEvent, XOpenDisplay, XPending, ExposureMask, KeyPress, KeyPressMask, KeyRelease, KeyReleaseMask, LeaveWindowMask,
XRootWindow, XFlush, CWOverrideRedirect, CWBackPixel, CWEventMask, XSetWindowAttributes, XCreateWindow, CopyFromParent, XMapRaised, VisibilityChangeMask, ExposureMask, XSetClassHint, XClassHint, PointerMotionMask, VisibilityChangeMask, XClassHint, XCloseDisplay, XCreateWindow,
XDefaultScreen, XFlush, XMapRaised, XNextEvent, XOpenDisplay, XPending, XRootWindow,
XSetClassHint, XSetWindowAttributes, XWhitePixel, EnterNotify, XGetInputFocus, XGrabKeyboard, XDefaultRootWindow, GrabModeAsync, CurrentTime, XGrabPointer, ButtonPressMask, ButtonReleaseMask, MotionNotify,
}; };
pub struct X11Producer(AsyncFd<Inner>); pub struct X11Producer(AsyncFd<Inner>);
@@ -24,6 +26,7 @@ struct Inner {
connection_fd: RawFd, connection_fd: RawFd,
display: *mut xlib::Display, display: *mut xlib::Display,
pending_events: VecDeque<(ClientHandle, Event)>, pending_events: VecDeque<(ClientHandle, Event)>,
window: u64,
} }
impl AsRawFd for Inner { impl AsRawFd for Inner {
@@ -50,10 +53,17 @@ impl X11Producer {
let mut attr: XSetWindowAttributes = unsafe { std::mem::zeroed() }; let mut attr: XSetWindowAttributes = unsafe { std::mem::zeroed() };
attr.override_redirect = true as i32; attr.override_redirect = true as i32;
attr.background_pixel = unsafe { XWhitePixel(display, screen) }; attr.background_pixel = unsafe { XWhitePixel(display, screen) };
attr.event_mask = ExposureMask | VisibilityChangeMask | KeyPressMask | KeyReleaseMask | PointerMotionMask; attr.event_mask = ExposureMask
| VisibilityChangeMask
| KeyPressMask
| KeyReleaseMask
| PointerMotionMask
| EnterWindowMask
| LeaveWindowMask;
let window = unsafe { let window = unsafe {
XCreateWindow( XCreateWindow(
display, root_window, display,
root_window,
0, /* x */ 0, /* x */
0, /* y */ 0, /* y */
2560, /* min width */ 2560, /* min width */
@@ -70,8 +80,8 @@ impl X11Producer {
let name = name.as_mut_ptr(); let name = name.as_mut_ptr();
let mut class_hint = XClassHint { let mut class_hint = XClassHint {
res_name: name as * mut i8, res_name: name as *mut i8,
res_class: name as * mut i8, res_class: name as *mut i8,
}; };
unsafe { XSetClassHint(display, window, &mut class_hint as *mut _) }; unsafe { XSetClassHint(display, window, &mut class_hint as *mut _) };
log::warn!("window: {window}"); log::warn!("window: {window}");
@@ -85,6 +95,7 @@ impl X11Producer {
let inner = Inner { let inner = Inner {
connection_fd, connection_fd,
display, display,
window,
pending_events, pending_events,
}; };
let async_fd = AsyncFd::new(inner)?; let async_fd = AsyncFd::new(inner)?;
@@ -93,27 +104,46 @@ impl X11Producer {
} }
impl Inner { impl Inner {
fn decode(&self, xevent: xlib::XEvent) -> Option<(u32, Event)> { fn decode(&mut self, xevent: xlib::XEvent) -> Option<(u32, Event)> {
let _ = xevent; log::info!("decoding {xevent:?}");
Some(( match xevent.get_type() {
t if t == KeyPress || t == KeyRelease => {
let key_event: xlib::XKeyEvent = unsafe { xevent.key };
let code = key_event.keycode;
let linux_code = code - 8;
let state = (xevent.get_type() == KeyPress) as u8;
return Some((
0, 0,
Event::Pointer(PointerEvent::Motion { Event::Keyboard(crate::event::KeyboardEvent::Key {
time: 0, time: 0,
relative_x: 1., key: linux_code,
relative_y: 0., state,
}), }),
)) ));
}
t if t == EnterNotify => {
let mut prev_win = 0;
unsafe { XGetInputFocus(self.display, &mut self.window as *mut _, &mut prev_win as * mut _) };
unsafe { XGrabKeyboard(self.display, XDefaultRootWindow(self.display), true as i32, GrabModeAsync, GrabModeAsync, CurrentTime) };
unsafe { XGrabPointer(self.display, XDefaultRootWindow(self.display), true as i32, (PointerMotionMask | ButtonPressMask | ButtonReleaseMask) as u32, GrabModeAsync, GrabModeAsync, self.window, 0, CurrentTime) };
Some((0, Event::Enter()))
}
t if t == MotionNotify => {
let pointer_event = unsafe { xevent.motion };
let (abs_x, abs_y) = (pointer_event.x, pointer_event.y);
let event = Event::Pointer(PointerEvent::Motion { time: 0, relative_x: abs_x as f64, relative_y: abs_y as f64 });
Some((0, event))
}
_ => None,
}
} }
fn dispatch(&mut self) -> io::Result<bool> { fn dispatch(&mut self) -> io::Result<bool> {
unsafe { unsafe {
if XPending(self.display) > 0 { if XPending(self.display) > 0 {
let mut xevent: xlib::XEvent = std::mem::zeroed(); let mut xevent: xlib::XEvent = std::mem::zeroed();
if XNextEvent(self.display, &mut xevent as *mut _) != 0 { XNextEvent(self.display, &mut xevent as *mut _);
log::info!("event: {xevent:?}");
return Err(io::Error::last_os_error().into());
}
log::info!("event: {xevent:?}");
if let Some(event) = self.decode(xevent) { if let Some(event) = self.decode(xevent) {
self.pending_events.push_back(event); self.pending_events.push_back(event);
} }