mirror of
https://github.com/feschber/lan-mouse.git
synced 2026-04-21 11:53:18 +03:00
basic input event decoding
This commit is contained in:
@@ -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,18 +53,25 @@ 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,
|
||||||
0, /* x */
|
root_window,
|
||||||
0, /* y */
|
0, /* x */
|
||||||
2560, /* min width */
|
0, /* y */
|
||||||
10, /* min height */
|
2560, /* min width */
|
||||||
0, /* border width */
|
10, /* min height */
|
||||||
CopyFromParent, /* depth */
|
0, /* border width */
|
||||||
|
CopyFromParent, /* depth */
|
||||||
CopyFromParent as u32, /* class */
|
CopyFromParent as u32, /* class */
|
||||||
ptr::null_mut(), /* Visual *visual */
|
ptr::null_mut(), /* Visual *visual */
|
||||||
CWOverrideRedirect | CWBackPixel | CWEventMask,
|
CWOverrideRedirect | CWBackPixel | CWEventMask,
|
||||||
&mut attr as *mut _,
|
&mut attr as *mut _,
|
||||||
)
|
)
|
||||||
@@ -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() {
|
||||||
0,
|
t if t == KeyPress || t == KeyRelease => {
|
||||||
Event::Pointer(PointerEvent::Motion {
|
let key_event: xlib::XKeyEvent = unsafe { xevent.key };
|
||||||
time: 0,
|
let code = key_event.keycode;
|
||||||
relative_x: 1.,
|
let linux_code = code - 8;
|
||||||
relative_y: 0.,
|
let state = (xevent.get_type() == KeyPress) as u8;
|
||||||
}),
|
return Some((
|
||||||
))
|
0,
|
||||||
|
Event::Keyboard(crate::event::KeyboardEvent::Key {
|
||||||
|
time: 0,
|
||||||
|
key: linux_code,
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user