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}
56