miniquad/native/linux_x11/
xi_input.rs

1#![allow(non_upper_case_globals, non_snake_case)]
2
3use super::{
4    libx11::{self, Display, Window, _XPrivDisplay},
5    xi_input,
6};
7
8pub const XIAllDevices: libc::c_int = 0 as libc::c_int;
9pub const XI_RawMotion: libc::c_int = 17 as libc::c_int;
10pub const XI_RawMotionMask: libc::c_int = (1 as libc::c_int) << XI_RawMotion;
11
12#[derive(Copy, Clone)]
13#[repr(C)]
14pub struct XIEventMask {
15    pub deviceid: libc::c_int,
16    pub mask_len: libc::c_int,
17    pub mask: *mut libc::c_uchar,
18}
19
20#[derive(Copy, Clone)]
21#[repr(C)]
22pub struct XIValuatorState {
23    pub mask_len: libc::c_int,
24    pub mask: *mut libc::c_uchar,
25    pub values: *mut libc::c_double,
26}
27
28pub type Time = libc::c_ulong;
29
30#[derive(Copy, Clone)]
31#[repr(C)]
32pub struct XIRawEvent {
33    pub type_0: libc::c_int,
34    pub serial: libc::c_ulong,
35    pub send_event: libc::c_int,
36    pub display: *mut Display,
37    pub extension: libc::c_int,
38    pub evtype: libc::c_int,
39    pub time: Time,
40    pub deviceid: libc::c_int,
41    pub sourceid: libc::c_int,
42    pub detail: libc::c_int,
43    pub flags: libc::c_int,
44    pub valuators: XIValuatorState,
45    pub raw_values: *mut libc::c_double,
46}
47
48use core::ffi::{c_char, c_int};
49crate::declare_module!(
50    LibXi,
51    "libXi.so",
52    "libXi.so.6",
53    ...
54    ...
55    pub fn XQueryExtension(*mut Display, *const c_char, *mut c_int, *mut c_int, *mut c_int) -> c_int,
56    pub fn XIQueryVersion(*mut Display, *mut c_int, *mut c_int) -> c_int,
57    pub fn XISelectEvents(*mut Display, Window, *mut XIEventMask, c_int),
58    pub fn XGetEventData(*mut Display, *mut libx11::XGenericEventCookie) -> c_int,
59    pub fn XFreeEventData(*mut Display, *mut libx11::XGenericEventCookie),
60    ...
61    ...
62    pub xi_extension_opcode: Option<i32>,
63);
64
65impl LibXi {
66    pub unsafe fn query_xi_extension(
67        &mut self,
68        libx11: &mut libx11::LibX11,
69        display: *mut Display,
70    ) {
71        let mut ev = 0;
72        let mut err = 0;
73        let mut xi_opcode = 0;
74
75        if (libx11.XQueryExtension)(
76            display,
77            b"XInputExtension\x00" as *const u8 as *const libc::c_char,
78            &mut xi_opcode,
79            &mut ev,
80            &mut err,
81        ) == 0
82        {
83            return;
84        }
85
86        // check the version of XInput
87        let mut major = 2;
88        let mut minor = 3;
89        if (self.XIQueryVersion)(display, &mut major, &mut minor) != 0 {
90            return;
91        }
92
93        // select events to listen
94        let mut mask = XI_RawMotionMask;
95        let mut masks = XIEventMask {
96            deviceid: XIAllDevices,
97            mask_len: ::std::mem::size_of::<libc::c_int>() as _,
98            mask: &mut mask as *mut _ as *mut _,
99        };
100
101        (self.XISelectEvents)(
102            display,
103            // this weird pointers is macro expansion of DefaultRootWindow(display)
104            (*(*(display as _XPrivDisplay))
105                .screens
106                .offset((*(display as _XPrivDisplay)).default_screen as isize))
107            .root,
108            &mut masks,
109            1 as libc::c_int,
110        );
111        self.xi_extension_opcode = Some(xi_opcode);
112    }
113
114    /// Get mouse delta from XI_RawMotion's event XGenericEventCookie data
115    pub unsafe fn read_cookie(
116        &mut self,
117        xcookie: &mut libx11::XGenericEventCookie,
118        display: *mut Display,
119    ) -> (f64, f64) {
120        assert!(xcookie.evtype == xi_input::XI_RawMotion);
121
122        (self.XGetEventData)(display, xcookie);
123
124        let raw_event = xcookie.data as *mut xi_input::XIRawEvent;
125
126        let dx = *(*raw_event).raw_values;
127        let dy = *(*raw_event).raw_values.offset(1);
128
129        (self.XFreeEventData)(display, &mut (*xcookie) as *mut _);
130
131        (dx, dy)
132    }
133}