mirror of
https://github.com/feschber/lan-mouse.git
synced 2026-03-25 14:10:55 +03:00
split into input-{event,capture,emulation}
This commit is contained in:
committed by
Ferdinand Schober
parent
7b511bb97d
commit
4db2d37f32
151
input-emulation/src/x11.rs
Normal file
151
input-emulation/src/x11.rs
Normal file
@@ -0,0 +1,151 @@
|
||||
use async_trait::async_trait;
|
||||
use std::ptr;
|
||||
use x11::{
|
||||
xlib::{self, XCloseDisplay},
|
||||
xtest,
|
||||
};
|
||||
|
||||
use input_event::{
|
||||
Event, KeyboardEvent, PointerEvent, BTN_BACK, BTN_FORWARD, BTN_LEFT, BTN_MIDDLE, BTN_RIGHT,
|
||||
};
|
||||
|
||||
use super::{error::X11EmulationCreationError, EmulationHandle, InputEmulation};
|
||||
|
||||
pub struct X11Emulation {
|
||||
display: *mut xlib::Display,
|
||||
}
|
||||
|
||||
unsafe impl Send for X11Emulation {}
|
||||
|
||||
impl X11Emulation {
|
||||
pub fn new() -> Result<Self, X11EmulationCreationError> {
|
||||
let display = unsafe {
|
||||
match xlib::XOpenDisplay(ptr::null()) {
|
||||
d if d == ptr::null::<xlib::Display>() as *mut xlib::Display => {
|
||||
Err(X11EmulationCreationError::OpenDisplay)
|
||||
}
|
||||
display => Ok(display),
|
||||
}
|
||||
}?;
|
||||
Ok(Self { display })
|
||||
}
|
||||
|
||||
fn relative_motion(&self, dx: i32, dy: i32) {
|
||||
unsafe {
|
||||
xtest::XTestFakeRelativeMotionEvent(self.display, dx, dy, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
fn emulate_mouse_button(&self, button: u32, state: u32) {
|
||||
unsafe {
|
||||
let x11_button = match button {
|
||||
BTN_RIGHT => 3,
|
||||
BTN_MIDDLE => 2,
|
||||
BTN_BACK => 8,
|
||||
BTN_FORWARD => 9,
|
||||
BTN_LEFT => 1,
|
||||
_ => 1,
|
||||
};
|
||||
xtest::XTestFakeButtonEvent(self.display, x11_button, state as i32, 0);
|
||||
};
|
||||
}
|
||||
|
||||
const SCROLL_UP: u32 = 4;
|
||||
const SCROLL_DOWN: u32 = 5;
|
||||
const SCROLL_LEFT: u32 = 6;
|
||||
const SCROLL_RIGHT: u32 = 7;
|
||||
|
||||
fn emulate_scroll(&self, axis: u8, value: f64) {
|
||||
let direction = match axis {
|
||||
1 => {
|
||||
if value < 0.0 {
|
||||
Self::SCROLL_LEFT
|
||||
} else {
|
||||
Self::SCROLL_RIGHT
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
if value < 0.0 {
|
||||
Self::SCROLL_UP
|
||||
} else {
|
||||
Self::SCROLL_DOWN
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
unsafe {
|
||||
xtest::XTestFakeButtonEvent(self.display, direction, 1, 0);
|
||||
xtest::XTestFakeButtonEvent(self.display, direction, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
fn emulate_key(&self, key: u32, state: u8) {
|
||||
let key = key + 8; // xorg keycodes are shifted by 8
|
||||
unsafe {
|
||||
xtest::XTestFakeKeyEvent(self.display, key, state as i32, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for X11Emulation {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
XCloseDisplay(self.display);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl InputEmulation for X11Emulation {
|
||||
async fn consume(&mut self, event: Event, _: EmulationHandle) {
|
||||
match event {
|
||||
Event::Pointer(pointer_event) => match pointer_event {
|
||||
PointerEvent::Motion {
|
||||
time: _,
|
||||
relative_x,
|
||||
relative_y,
|
||||
} => {
|
||||
self.relative_motion(relative_x as i32, relative_y as i32);
|
||||
}
|
||||
PointerEvent::Button {
|
||||
time: _,
|
||||
button,
|
||||
state,
|
||||
} => {
|
||||
self.emulate_mouse_button(button, state);
|
||||
}
|
||||
PointerEvent::Axis {
|
||||
time: _,
|
||||
axis,
|
||||
value,
|
||||
} => {
|
||||
self.emulate_scroll(axis, value);
|
||||
}
|
||||
PointerEvent::AxisDiscrete120 { axis, value } => {
|
||||
self.emulate_scroll(axis, value as f64);
|
||||
}
|
||||
PointerEvent::Frame {} => {}
|
||||
},
|
||||
Event::Keyboard(KeyboardEvent::Key {
|
||||
time: _,
|
||||
key,
|
||||
state,
|
||||
}) => {
|
||||
self.emulate_key(key, state);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
unsafe {
|
||||
xlib::XFlush(self.display);
|
||||
}
|
||||
}
|
||||
|
||||
async fn create(&mut self, _: EmulationHandle) {
|
||||
// for our purposes it does not matter what client sent the event
|
||||
}
|
||||
|
||||
async fn destroy(&mut self, _: EmulationHandle) {
|
||||
// for our purposes it does not matter what client sent the event
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user