1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111
|
// Example for X Record Extension
#![cfg_attr(not(feature = "xlib"), allow(dead_code))]
#![cfg_attr(not(feature = "xlib"), allow(unused_imports))]
extern crate libc;
extern crate x11;
use std::ffi::CString;
use std::ptr::{null, null_mut};
use std::os::raw::{c_char, c_int};
use x11::xlib;
use x11::xrecord;
static mut EVENT_COUNT: u32 = 0;
#[cfg(not(all(feature = "xlib", feature = "xrecord")))]
fn main() {
panic!("this example requires `--features 'xlib xrecord'`");
}
#[cfg(all(feature = "xlib", feature = "xrecord"))]
fn main() {
unsafe {
// Open displays
let dpy_control = xlib::XOpenDisplay(null());
let dpy_data = xlib::XOpenDisplay(null());
if dpy_control == null_mut() || dpy_data == null_mut() {
panic!("can't open display");
}
// Enable synchronization
xlib::XSynchronize(dpy_control, 1);
let extension_name = CString::new("RECORD").unwrap();
let extension = xlib::XInitExtension(dpy_control, extension_name.as_ptr());
if extension.is_null() {
panic!("Error init X Record Extension");
}
// Get version
let mut version_major: c_int = 0;
let mut version_minor: c_int = 0;
xrecord::XRecordQueryVersion(dpy_control, &mut version_major, &mut version_minor);
println!(
"RECORD extension version {}.{}",
version_major, version_minor
);
// Prepare record range
let mut record_range: xrecord::XRecordRange = *xrecord::XRecordAllocRange();
record_range.device_events.first = xlib::KeyPress as u8;
record_range.device_events.last = xlib::MotionNotify as u8;
// Create context
let context = xrecord::XRecordCreateContext(
dpy_control,
0,
&mut xrecord::XRecordAllClients,
1,
std::mem::transmute(&mut &mut record_range),
1,
);
if context == 0 {
panic!("Fail create Record context\n");
}
// Run
let result =
xrecord::XRecordEnableContext(dpy_data, context, Some(record_callback), &mut 0);
if result == 0 {
panic!("Cound not enable the Record context!\n");
}
}
}
unsafe extern "C" fn record_callback(_: *mut c_char, raw_data: *mut xrecord::XRecordInterceptData) {
EVENT_COUNT += 1;
let data = &*raw_data;
// Skip server events
if data.category != xrecord::XRecordFromServer {
return;
}
// Cast binary data
let xdatum = &*(data.data as *mut XRecordDatum);
let event_type = match xdatum.xtype as i32 {
xlib::KeyPress => "KeyPress",
xlib::KeyRelease => "KeyRelease",
xlib::ButtonPress => "ButtonPress",
xlib::ButtonRelease => "ButtonRelease",
xlib::MotionNotify => "MotionNotify",
_ => "Other",
};
println!("Event recieve\t{:?}\tevent.", event_type);
xrecord::XRecordFreeData(raw_data);
}
#[repr(C)]
struct XRecordDatum {
xtype: u8,
code: u8,
unknown1: u8,
unknown2: u8,
}
|