这是indexloc提供的服务,不要输入任何密码
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
[package]
name = "rdev"
version = "0.5.3"
version = "0.6.0"
authors = ["Nicolas Patry <patry.nicolas@protonmail.com>"]
edition = "2018"
edition = "2024"

description = "Listen and send keyboard and mouse events on Windows, Linux and MacOS."
documentation = "https://docs.rs/rdev/"
Expand Down
2 changes: 1 addition & 1 deletion examples/grab.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use rdev::{grab, Event, EventType, Key};
use rdev::{Event, EventType, Key, grab};

fn main() {
// This will block.
Expand Down
2 changes: 1 addition & 1 deletion examples/listen.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use rdev::{listen, Event};
use rdev::{Event, listen};

fn main() {
// This will block.
Expand Down
2 changes: 1 addition & 1 deletion examples/simulate.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use rdev::{simulate, Button, EventType, Key, SimulateError};
use rdev::{Button, EventType, Key, SimulateError, simulate};
use std::{
thread,
time::{self, Duration},
Expand Down
4 changes: 2 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -226,9 +226,9 @@ pub use crate::rdev::{
#[cfg(target_os = "macos")]
mod macos;
#[cfg(target_os = "macos")]
use crate::macos::{display_size as _display_size, listen as _listen, simulate as _simulate};
pub use crate::macos::{Keyboard, set_is_main_thread};
#[cfg(target_os = "macos")]
pub use crate::macos::{set_is_main_thread, Keyboard};
use crate::macos::{display_size as _display_size, listen as _listen, simulate as _simulate};

#[cfg(all(target_family = "unix", not(target_os = "macos")))]
mod linux;
Expand Down
4 changes: 2 additions & 2 deletions src/linux/wayland/grab.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@ use super::keyboard::Keyboard;
use crate::rdev::{Button, Event, EventType, GrabError, Key, KeyboardState};
use epoll::ControlOptions::{EPOLL_CTL_ADD, EPOLL_CTL_DEL};
use evdev_rs::{
enums::{EventCode, EV_KEY, EV_REL},
Device, InputEvent, UInputDevice,
enums::{EV_KEY, EV_REL, EventCode},
};
use inotify::{Inotify, WatchMask};
use std::ffi::{OsStr, OsString};
use std::fs::{read_dir, File};
use std::fs::{File, read_dir};
use std::io;
use std::os::unix::{
ffi::OsStrExt,
Expand Down
2 changes: 1 addition & 1 deletion src/linux/wayland/keycodes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,7 @@ decl_keycodes_uinput!(

#[cfg(test)]
mod test {
use super::{code_from_key, key_from_code, key_from_ukey, ukey_from_key, UKey};
use super::{UKey, code_from_key, key_from_code, key_from_ukey, ukey_from_key};
#[test]
fn test_reversible() {
for code in 0..65636 {
Expand Down
2 changes: 1 addition & 1 deletion src/linux/wayland/listen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ use super::keyboard::Keyboard;
use super::keycodes::key_from_code;
use crate::rdev::{Event, KeyboardState, ListenError};
use crate::{Button, EventType};
use input::event::PointerEvent;
use input::event::keyboard::{KeyState, KeyboardEventTrait};
use input::event::pointer::{Axis, ButtonState};
use input::event::PointerEvent;
use input::{Event as LibEvent, Libinput, LibinputInterface};
use libc::{O_RDONLY, O_RDWR, O_WRONLY};
use std::fs::{File, OpenOptions};
Expand Down
4 changes: 2 additions & 2 deletions src/linux/wayland/simulate.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
use crate::SimulateError;
use crate::linux::wayland::keycodes::ukey_from_key;
use crate::rdev::{Button, EventType};
use crate::SimulateError;
use input_linux::{
EventKind, EventTime, InputEvent, InputId, Key as UKey, KeyEvent, KeyState, RelativeAxis,
RelativeEvent, SynchronizeEvent, SynchronizeKind, UInputHandle,
};
use libc::{input_event, O_NONBLOCK};
use libc::{O_NONBLOCK, input_event};
use std::fs::{File, OpenOptions};
use std::os::unix::fs::OpenOptionsExt;
use std::sync::{LazyLock, Mutex};
Expand Down
4 changes: 2 additions & 2 deletions src/linux/x11/grab.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@ use super::keyboard::Keyboard;
use crate::rdev::{Button, Event, EventType, GrabError, Key, KeyboardState};
use epoll::ControlOptions::{EPOLL_CTL_ADD, EPOLL_CTL_DEL};
use evdev_rs::{
enums::{EventCode, EV_KEY, EV_REL},
Device, InputEvent, UInputDevice,
enums::{EV_KEY, EV_REL, EventCode},
};
use inotify::{Inotify, WatchMask};
use std::ffi::{OsStr, OsString};
use std::fs::{read_dir, File};
use std::fs::{File, read_dir};
use std::io;
use std::os::unix::{
ffi::OsStrExt,
Expand Down
92 changes: 47 additions & 45 deletions src/linux/x11/keyboard.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use super::keycodes::code_from_key;
use crate::rdev::{EventType, Key, KeyboardState};
use std::ffi::CString;
use std::os::raw::{c_char, c_int, c_uint, c_ulong, c_void};
use std::ptr::{null, null_mut, NonNull};
use std::ptr::{NonNull, null, null_mut};
use x11::xlib;

#[derive(Debug)]
Expand Down Expand Up @@ -151,54 +151,56 @@ impl Keyboard {
keycode: c_uint,
state: c_uint,
) -> Option<String> {
if self.display.is_null() || self.xic.is_null() {
println!("We don't seem to have a display or a xic");
return None;
}
const BUF_LEN: usize = 4;
let mut buf = [0_u8; BUF_LEN];
let key = xlib::XKeyEvent {
display: *self.display,
root: 0,
window: *self.window,
subwindow: 0,
x: 0,
y: 0,
x_root: 0,
y_root: 0,
state,
keycode,
same_screen: 0,
send_event: 0,
serial: self.serial,
type_: xlib::KeyPress,
time: xlib::CurrentTime,
};
self.serial += 1;
unsafe {
if self.display.is_null() || self.xic.is_null() {
println!("We don't seem to have a display or a xic");
return None;
}
const BUF_LEN: usize = 4;
let mut buf = [0_u8; BUF_LEN];
let key = xlib::XKeyEvent {
display: *self.display,
root: 0,
window: *self.window,
subwindow: 0,
x: 0,
y: 0,
x_root: 0,
y_root: 0,
state,
keycode,
same_screen: 0,
send_event: 0,
serial: self.serial,
type_: xlib::KeyPress,
time: xlib::CurrentTime,
};
self.serial += 1;

let mut event = xlib::XEvent { key };

let mut event = xlib::XEvent { key };
// -----------------------------------------------------------------
// XXX: This is **OMEGA IMPORTANT** This is what enables us to receive
// the correct keyvalue from the utf8LookupString !!
// https://stackoverflow.com/questions/18246848/get-utf-8-input-with-x11-display#
// -----------------------------------------------------------------
xlib::XFilterEvent(&mut event, 0);

// -----------------------------------------------------------------
// XXX: This is **OMEGA IMPORTANT** This is what enables us to receive
// the correct keyvalue from the utf8LookupString !!
// https://stackoverflow.com/questions/18246848/get-utf-8-input-with-x11-display#
// -----------------------------------------------------------------
xlib::XFilterEvent(&mut event, 0);
let ret = xlib::Xutf8LookupString(
*self.xic,
&mut event.key,
buf.as_mut_ptr() as *mut c_char,
BUF_LEN as c_int,
&mut *self.keysym,
&mut *self.status,
);
if ret == xlib::NoSymbol {
return None;
}

let ret = xlib::Xutf8LookupString(
*self.xic,
&mut event.key,
buf.as_mut_ptr() as *mut c_char,
BUF_LEN as c_int,
&mut *self.keysym,
&mut *self.status,
);
if ret == xlib::NoSymbol {
return None;
let len = buf.iter().position(|ch| ch == &0).unwrap_or(BUF_LEN);
String::from_utf8(buf[..len].to_vec()).ok()
}

let len = buf.iter().position(|ch| ch == &0).unwrap_or(BUF_LEN);
String::from_utf8(buf[..len].to_vec()).ok()
}
}

Expand Down
44 changes: 22 additions & 22 deletions src/linux/x11/listen.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
extern crate libc;
extern crate x11;
use super::common::{convert, FALSE, KEYBOARD};
use super::common::{FALSE, KEYBOARD, convert};
use super::keyboard::Keyboard;
use crate::rdev::{Event, ListenError};
use std::convert::TryInto;
use std::ffi::CStr;
use std::os::raw::{c_char, c_int, c_uchar, c_uint, c_ulong};
use std::ptr::null;
use x11::xlib;
Expand All @@ -27,8 +26,7 @@ where
if dpy_control.is_null() {
return Err(ListenError::MissingDisplayError);
}
let extension_name = CStr::from_bytes_with_nul(b"RECORD\0")
.map_err(|_| ListenError::XRecordExtensionError)?;
let extension_name = c"RECORD";
let extension = xlib::XInitExtension(dpy_control, extension_name.as_ptr());
if extension.is_null() {
return Err(ListenError::XRecordExtensionError);
Expand Down Expand Up @@ -90,28 +88,30 @@ unsafe extern "C" fn record_callback(
_null: *mut c_char,
raw_data: *mut xrecord::XRecordInterceptData,
) {
let data = raw_data.as_ref().unwrap();
if data.category != xrecord::XRecordFromServer {
return;
}
unsafe {
let data = raw_data.as_ref().unwrap();
if data.category != xrecord::XRecordFromServer {
return;
}

debug_assert!(data.data_len * 4 >= std::mem::size_of::<XRecordDatum>().try_into().unwrap());
// Cast binary data
#[allow(clippy::cast_ptr_alignment)]
let xdatum = (data.data as *const XRecordDatum).as_ref().unwrap();
debug_assert!(data.data_len * 4 >= std::mem::size_of::<XRecordDatum>().try_into().unwrap());
// Cast binary data
#[allow(clippy::cast_ptr_alignment)]
let xdatum = (data.data as *const XRecordDatum).as_ref().unwrap();

let code: c_uint = xdatum.code.into();
let type_: c_int = xdatum.type_.into();
let code: c_uint = xdatum.code.into();
let type_: c_int = xdatum.type_.into();

let x = xdatum.root_x as f64;
let y = xdatum.root_y as f64;
let x = xdatum.root_x as f64;
let y = xdatum.root_y as f64;

let ptr = &raw mut KEYBOARD;
if let Some(event) = convert(&mut *ptr, code, type_, x, y) {
let ptr = &raw mut GLOBAL_CALLBACK;
if let Some(callback) = &mut *ptr {
callback(event);
let ptr = &raw mut KEYBOARD;
if let Some(event) = convert(&mut *ptr, code, type_, x, y) {
let ptr = &raw mut GLOBAL_CALLBACK;
if let Some(callback) = &mut *ptr {
callback(event);
}
}
xrecord::XRecordFreeData(raw_data);
}
xrecord::XRecordFreeData(raw_data);
}
Loading