Skip to content

Commit d5e8ca3

Browse files
committed
Moving to Fn(Event) -> () instead of fn pointer.
1 parent 81ef1f4 commit d5e8ca3

File tree

9 files changed

+83
-80
lines changed

9 files changed

+83
-80
lines changed

examples/channel.rs

Lines changed: 11 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,22 @@
1-
use lazy_static::lazy_static;
2-
use rdev::{listen, Event};
3-
use std::sync::mpsc::{channel, Receiver, Sender};
4-
use std::sync::Mutex;
1+
use rdev::listen;
2+
use std::sync::mpsc::channel;
53
use std::thread;
64

7-
lazy_static! {
8-
static ref EVENT_CHANNEL: (Mutex<Sender<Event>>, Mutex<Receiver<Event>>) = {
9-
let (send, recv) = channel();
10-
(Mutex::new(send), Mutex::new(recv))
11-
};
12-
}
13-
14-
fn send_event(event: Event) {
15-
EVENT_CHANNEL
16-
.0
17-
.lock()
18-
.expect("Failed to unlock Mutex")
19-
.send(event)
20-
.expect("Receiving end of EVENT_CHANNEL was closed");
21-
}
22-
235
fn main() {
246
// spawn new thread because listen blocks
7+
let (schan, rchan) = channel();
258
let _listener = thread::spawn(move || {
26-
listen(send_event).expect("Could not listen");
9+
listen(move |event| {
10+
schan
11+
.send(event)
12+
.unwrap_or_else(|e| println!("Could not send event {:?}", e));
13+
})
14+
.expect("Could not listen");
2715
});
2816

29-
let recv = EVENT_CHANNEL.1.lock().expect("Failed to unlock Mutex");
3017
let mut events = Vec::new();
31-
for event in recv.iter() {
18+
for event in rchan.iter() {
19+
println!("Received {:?}", event);
3220
events.push(event);
33-
println!("Received {} events", events.len());
3421
}
3522
}

src/lib.rs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@
171171
//! Serialization and deserialization. (Requires `serialize` feature).
172172
mod rdev;
173173
pub use crate::rdev::{
174-
Button, Callback, DisplayError, Event, EventType, GrabCallback, GrabError, Key, KeyboardState,
174+
Button, DisplayError, Event, EventType, GrabCallback, GrabError, Key, KeyboardState,
175175
ListenError, SimulateError,
176176
};
177177

@@ -217,7 +217,10 @@ use crate::windows::{display_size as _display_size, listen as _listen, simulate
217217
/// }
218218
/// }
219219
/// ```
220-
pub fn listen(callback: Callback) -> Result<(), ListenError> {
220+
pub fn listen<T: 'static>(callback: T) -> Result<(), ListenError>
221+
where
222+
T: Fn(Event) -> (),
223+
{
221224
_listen(callback)
222225
}
223226

@@ -306,7 +309,10 @@ pub use crate::windows::grab as _grab;
306309
/// }
307310
/// ```
308311
#[cfg(any(feature = "unstable_grab"))]
309-
pub fn grab(callback: GrabCallback) -> Result<(), GrabError> {
312+
pub fn grab<T>(callback: T) -> Result<(), GrabError>
313+
where
314+
T: Fn(Event) -> Option<Event> + 'static,
315+
{
310316
_grab(callback)
311317
}
312318

src/linux/grab.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use crate::linux::common::Display;
22
use crate::linux::keyboard::Keyboard;
3-
use crate::rdev::{Button, Event, EventType, GrabCallback, GrabError, Key, KeyboardState};
3+
use crate::rdev::{Button, Event, EventType, GrabError, Key, KeyboardState};
44
use epoll::ControlOptions::{EPOLL_CTL_ADD, EPOLL_CTL_DEL};
55
use evdev_rs::{
66
enums::{EventCode, EV_KEY, EV_REL},
@@ -301,7 +301,10 @@ fn evdev_event_to_rdev_event(
301301
// }
302302
// }
303303

304-
pub fn grab(callback: GrabCallback) -> Result<(), GrabError> {
304+
pub fn grab<T>(callback: T) -> Result<(), GrabError>
305+
where
306+
T: Fn(Event) -> Option<Event> + 'static,
307+
{
305308
let mut kb = Keyboard::new().ok_or(GrabError::KeyboardError)?;
306309
let display = Display::new().ok_or(GrabError::MissingDisplayError)?;
307310
let (width, height) = display.get_size().ok_or(GrabError::MissingDisplayError)?;

src/linux/listen.rs

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,27 +2,26 @@ extern crate libc;
22
extern crate x11;
33
use crate::linux::common::{convert, FALSE, KEYBOARD};
44
use crate::linux::keyboard::Keyboard;
5-
use crate::rdev::{Callback, Event, ListenError};
5+
use crate::rdev::{Event, ListenError};
66
use std::convert::TryInto;
77
use std::ffi::CStr;
88
use std::os::raw::{c_char, c_int, c_uchar, c_uint, c_ulong};
99
use std::ptr::null;
1010
use x11::xlib;
1111
use x11::xrecord;
1212

13-
fn default_callback(event: Event) {
14-
println!("Default : Event {:?}", event);
15-
}
16-
1713
static mut RECORD_ALL_CLIENTS: c_ulong = xrecord::XRecordAllClients;
18-
static mut GLOBAL_CALLBACK: Callback = default_callback;
14+
static mut GLOBAL_CALLBACK: Option<Box<dyn Fn(Event) -> ()>> = None;
1915

20-
pub fn listen(callback: Callback) -> Result<(), ListenError> {
16+
pub fn listen<T>(callback: T) -> Result<(), ListenError>
17+
where
18+
T: Fn(Event) -> () + 'static,
19+
{
2120
let keyboard = Keyboard::new().ok_or(ListenError::KeyboardError)?;
2221

2322
unsafe {
2423
KEYBOARD = Some(keyboard);
25-
GLOBAL_CALLBACK = callback;
24+
GLOBAL_CALLBACK = Some(Box::new(callback));
2625
// Open displays
2726
let dpy_control = xlib::XOpenDisplay(null());
2827
if dpy_control.is_null() {
@@ -107,7 +106,9 @@ unsafe extern "C" fn record_callback(
107106
let y = xdatum.root_y as f64;
108107

109108
if let Some(event) = convert(&mut KEYBOARD, code, type_, x, y) {
110-
GLOBAL_CALLBACK(event);
109+
if let Some(callback) = &GLOBAL_CALLBACK {
110+
callback(event);
111+
}
111112
}
112113
xrecord::XRecordFreeData(raw_data);
113114
}

src/macos/grab.rs

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,12 @@
11
#![allow(improper_ctypes_definitions)]
22
use crate::macos::common::*;
3-
use crate::rdev::{Event, GrabCallback, GrabError};
3+
use crate::rdev::{Event, GrabError};
44
use cocoa::base::nil;
55
use cocoa::foundation::NSAutoreleasePool;
66
use core_graphics::event::{CGEventTapLocation, CGEventType};
77
use std::os::raw::c_void;
88

9-
fn default_callback(event: Event) -> Option<Event> {
10-
println!("Default {:?}", event);
11-
Some(event)
12-
}
13-
static mut GLOBAL_CALLBACK: GrabCallback = default_callback;
9+
static mut GLOBAL_CALLBACK: Option<Box<dyn Fn(Event) -> Option<Event>>> = None;
1410

1511
unsafe extern "C" fn raw_callback(
1612
_proxy: CGEventTapProxy,
@@ -23,18 +19,23 @@ unsafe extern "C" fn raw_callback(
2319
let opt = KEYBOARD_STATE.lock();
2420
if let Ok(mut keyboard) = opt {
2521
if let Some(event) = convert(_type, &cg_event, &mut keyboard) {
26-
if GLOBAL_CALLBACK(event).is_none() {
27-
cg_event.set_type(CGEventType::Null);
22+
if let Some(callback) = &GLOBAL_CALLBACK {
23+
if callback(event).is_none() {
24+
cg_event.set_type(CGEventType::Null);
25+
}
2826
}
2927
}
3028
}
3129
cg_event
3230
}
3331

3432
#[link(name = "Cocoa", kind = "framework")]
35-
pub fn grab(callback: GrabCallback) -> Result<(), GrabError> {
33+
pub fn grab<T>(callback: T) -> Result<(), GrabError>
34+
where
35+
T: Fn(Event) -> Option<Event> + 'static,
36+
{
3637
unsafe {
37-
GLOBAL_CALLBACK = callback;
38+
GLOBAL_CALLBACK = Some(Box::new(callback));
3839
let _pool = NSAutoreleasePool::new(nil);
3940
let tap = CGEventTapCreate(
4041
CGEventTapLocation::HID, // HID, Session, AnnotatedSession,

src/macos/listen.rs

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,12 @@
11
#![allow(improper_ctypes_definitions)]
22
use crate::macos::common::*;
3-
use crate::rdev::{Callback, Event, ListenError};
3+
use crate::rdev::{Event, ListenError};
44
use cocoa::base::nil;
55
use cocoa::foundation::NSAutoreleasePool;
66
use core_graphics::event::{CGEventTapLocation, CGEventType};
77
use std::os::raw::c_void;
88

9-
fn default_callback(event: Event) {
10-
println!("Default {:?}", event)
11-
}
12-
static mut GLOBAL_CALLBACK: Callback = default_callback;
9+
static mut GLOBAL_CALLBACK: Option<Box<dyn Fn(Event) -> ()>> = None;
1310

1411
unsafe extern "C" fn raw_callback(
1512
_proxy: CGEventTapProxy,
@@ -22,7 +19,9 @@ unsafe extern "C" fn raw_callback(
2219
let opt = KEYBOARD_STATE.lock();
2320
if let Ok(mut keyboard) = opt {
2421
if let Some(event) = convert(_type, &cg_event, &mut keyboard) {
25-
GLOBAL_CALLBACK(event);
22+
if let Some(callback) = &GLOBAL_CALLBACK {
23+
callback(event);
24+
}
2625
}
2726
}
2827
// println!("Event ref END {:?}", cg_event_ptr);
@@ -31,9 +30,12 @@ unsafe extern "C" fn raw_callback(
3130
}
3231

3332
#[link(name = "Cocoa", kind = "framework")]
34-
pub fn listen(callback: Callback) -> Result<(), ListenError> {
33+
pub fn listen<T>(callback: T) -> Result<(), ListenError>
34+
where
35+
T: Fn(Event) -> () + 'static,
36+
{
3537
unsafe {
36-
GLOBAL_CALLBACK = callback;
38+
GLOBAL_CALLBACK = Some(Box::new(callback));
3739
let _pool = NSAutoreleasePool::new(nil);
3840
let tap = CGEventTapCreate(
3941
CGEventTapLocation::HID, // HID, Session, AnnotatedSession,

src/rdev.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ use serde::{Deserialize, Serialize};
33
use std::time::SystemTime;
44
use std::{fmt, fmt::Display};
55

6-
/// Callback type to send to listen function.
7-
pub type Callback = fn(event: Event);
6+
// /// Callback type to send to listen function.
7+
// pub type Callback = dyn FnMut(Event) -> ();
88

99
/// Callback type to send to grab function.
1010
pub type GrabCallback = fn(event: Event) -> Option<Event>;

src/windows/grab.rs

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,10 @@
1-
use crate::rdev::{Event, EventType, GrabCallback, GrabError};
1+
use crate::rdev::{Event, EventType, GrabError};
22
use crate::windows::common::{convert, set_key_hook, set_mouse_hook, HookError, HOOK, KEYBOARD};
33
use std::ptr::null_mut;
44
use std::time::SystemTime;
55
use winapi::um::winuser::{CallNextHookEx, GetMessageA, HC_ACTION};
66

7-
fn default_callback(event: Event) -> Option<Event> {
8-
println!("Default : Event {:?}", event);
9-
Some(event)
10-
}
11-
static mut GLOBAL_CALLBACK: GrabCallback = default_callback;
7+
static mut GLOBAL_CALLBACK: Option<Box<dyn Fn(Event) -> Option<Event>>> = None;
128

139
unsafe extern "system" fn raw_callback(code: i32, param: usize, lpdata: isize) -> isize {
1410
if code == HC_ACTION {
@@ -26,12 +22,14 @@ unsafe extern "system" fn raw_callback(code: i32, param: usize, lpdata: isize) -
2622
time: SystemTime::now(),
2723
name,
2824
};
29-
if GLOBAL_CALLBACK(event).is_none() {
30-
// https://stackoverflow.com/questions/42756284/blocking-windows-mouse-click-using-setwindowshookex
31-
// https://android.developreference.com/article/14560004/Blocking+windows+mouse+click+using+SetWindowsHookEx()
32-
// https://cboard.cprogramming.com/windows-programming/99678-setwindowshookex-wm_keyboard_ll.html
33-
// let _result = CallNextHookEx(HOOK, code, param, lpdata);
34-
return 1;
25+
if let Some(callback) = &GLOBAL_CALLBACK {
26+
if callback(event).is_none() {
27+
// https://stackoverflow.com/questions/42756284/blocking-windows-mouse-click-using-setwindowshookex
28+
// https://android.developreference.com/article/14560004/Blocking+windows+mouse+click+using+SetWindowsHookEx()
29+
// https://cboard.cprogramming.com/windows-programming/99678-setwindowshookex-wm_keyboard_ll.html
30+
// let _result = CallNextHookEx(HOOK, code, param, lpdata);
31+
return 1;
32+
}
3533
}
3634
}
3735
}
@@ -46,9 +44,12 @@ impl From<HookError> for GrabError {
4644
}
4745
}
4846

49-
pub fn grab(callback: GrabCallback) -> Result<(), GrabError> {
47+
pub fn grab<T>(callback: T) -> Result<(), GrabError>
48+
where
49+
T: Fn(Event) -> Option<Event> + 'static,
50+
{
5051
unsafe {
51-
GLOBAL_CALLBACK = callback;
52+
GLOBAL_CALLBACK = Some(Box::new(callback));
5253
set_key_hook(raw_callback)?;
5354
set_mouse_hook(raw_callback)?;
5455

src/windows/listen.rs

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,12 @@
1-
use crate::rdev::{Callback, Event, EventType, ListenError};
1+
use crate::rdev::{Event, EventType, ListenError};
22
use crate::windows::common::{convert, set_key_hook, set_mouse_hook, HookError, HOOK, KEYBOARD};
33
use std::os::raw::c_int;
44
use std::ptr::null_mut;
55
use std::time::SystemTime;
66
use winapi::shared::minwindef::{LPARAM, LRESULT, WPARAM};
77
use winapi::um::winuser::{CallNextHookEx, GetMessageA, HC_ACTION};
88

9-
fn default_callback(event: Event) {
10-
println!("Default : Event {:?}", event);
11-
}
12-
static mut GLOBAL_CALLBACK: Callback = default_callback;
9+
static mut GLOBAL_CALLBACK: Option<Box<dyn Fn(Event) -> ()>> = None;
1310

1411
impl From<HookError> for ListenError {
1512
fn from(error: HookError) -> Self {
@@ -36,15 +33,20 @@ unsafe extern "system" fn raw_callback(code: c_int, param: WPARAM, lpdata: LPARA
3633
time: SystemTime::now(),
3734
name,
3835
};
39-
GLOBAL_CALLBACK(event);
36+
if let Some(callback) = &GLOBAL_CALLBACK {
37+
callback(event);
38+
}
4039
}
4140
}
4241
CallNextHookEx(HOOK, code, param, lpdata)
4342
}
4443

45-
pub fn listen(callback: Callback) -> Result<(), ListenError> {
44+
pub fn listen<T>(callback: T) -> Result<(), ListenError>
45+
where
46+
T: Fn(Event) -> () + 'static,
47+
{
4648
unsafe {
47-
GLOBAL_CALLBACK = callback;
49+
GLOBAL_CALLBACK = Some(Box::new(callback));
4850
set_key_hook(raw_callback)?;
4951
set_mouse_hook(raw_callback)?;
5052

0 commit comments

Comments
 (0)