winit/platform_impl/linux/x11/util/
cookie.rs

1use std::ffi::c_int;
2use std::sync::Arc;
3
4use x11_dl::xlib::{self, XEvent, XGenericEventCookie};
5
6use crate::platform_impl::x11::XConnection;
7
8/// XEvents of type GenericEvent store their actual data in an XGenericEventCookie data structure.
9/// This is a wrapper to extract the cookie from a GenericEvent XEvent and release the cookie data
10/// once it has been processed
11pub struct GenericEventCookie {
12    cookie: XGenericEventCookie,
13    xconn: Arc<XConnection>,
14}
15
16impl GenericEventCookie {
17    pub fn from_event(xconn: Arc<XConnection>, event: XEvent) -> Option<GenericEventCookie> {
18        unsafe {
19            let mut cookie: XGenericEventCookie = From::from(event);
20            if (xconn.xlib.XGetEventData)(xconn.display, &mut cookie) == xlib::True {
21                Some(GenericEventCookie { cookie, xconn })
22            } else {
23                None
24            }
25        }
26    }
27
28    #[inline]
29    pub fn extension(&self) -> u8 {
30        self.cookie.extension as u8
31    }
32
33    #[inline]
34    pub fn evtype(&self) -> c_int {
35        self.cookie.evtype
36    }
37
38    /// Borrow inner event data as `&T`.
39    ///
40    /// ## SAFETY
41    ///
42    /// The caller must ensure that the event has the `T` inside of it.
43    #[inline]
44    pub unsafe fn as_event<T>(&self) -> &T {
45        unsafe { &*(self.cookie.data as *const _) }
46    }
47}
48
49impl Drop for GenericEventCookie {
50    fn drop(&mut self) {
51        unsafe {
52            (self.xconn.xlib.XFreeEventData)(self.xconn.display, &mut self.cookie);
53        }
54    }
55}