1use crate::base::{BaseEvent, Raw, ResolveWireEvent, ResolveWireGeEvent};
2use crate::ext::{Extension, ExtensionData};
3use crate::ffi::*;
4use crate::x;
5
6#[cfg(feature = "damage")]
7use crate::damage;
8
9#[cfg(feature = "dri2")]
10use crate::dri2;
11
12#[cfg(feature = "glx")]
13use crate::glx;
14
15#[cfg(feature = "present")]
16use crate::present;
17
18#[cfg(feature = "randr")]
19use crate::randr;
20
21#[cfg(feature = "screensaver")]
22use crate::screensaver;
23
24#[cfg(feature = "shape")]
25use crate::shape;
26
27#[cfg(feature = "shm")]
28use crate::shm;
29
30#[cfg(feature = "sync")]
31use crate::sync;
32
33#[cfg(feature = "xfixes")]
34use crate::xfixes;
35
36#[cfg(feature = "xinput")]
37use crate::xinput;
38
39#[cfg(feature = "xkb")]
40use crate::xkb;
41
42#[cfg(feature = "xprint")]
43use crate::xprint;
44
45#[cfg(feature = "xv")]
46use crate::xv;
47
48#[derive(Debug)]
50pub enum Event {
51 X(x::Event),
53
54 #[cfg(feature = "damage")]
55 Damage(damage::Event),
57
58 #[cfg(feature = "dri2")]
59 Dri2(dri2::Event),
61
62 #[cfg(feature = "glx")]
63 Glx(glx::Event),
65
66 #[cfg(feature = "present")]
67 Present(present::Event),
69
70 #[cfg(feature = "randr")]
71 RandR(randr::Event),
73
74 #[cfg(feature = "screensaver")]
75 ScreenSaver(screensaver::Event),
77
78 #[cfg(feature = "shape")]
79 Shape(shape::Event),
81
82 #[cfg(feature = "shm")]
83 Shm(shm::Event),
85
86 #[cfg(feature = "sync")]
87 Sync(sync::Event),
89
90 #[cfg(feature = "xfixes")]
91 XFixes(xfixes::Event),
93
94 #[cfg(feature = "xinput")]
95 Input(xinput::Event),
97
98 #[cfg(feature = "xkb")]
99 Xkb(xkb::Event),
101
102 #[cfg(feature = "xprint")]
103 XPrint(xprint::Event),
105
106 #[cfg(feature = "xv")]
107 Xv(xv::Event),
109
110 Unknown(UnknownEvent),
112}
113
114impl Event {
115 pub fn as_raw(&self) -> *mut xcb_generic_event_t {
116 match self {
117 Self::X(e) => e.as_raw(),
118 #[cfg(feature = "damage")]
119 Self::Damage(e) => e.as_raw(),
120 #[cfg(feature = "dri2")]
121 Self::Dri2(e) => e.as_raw(),
122 #[cfg(feature = "glx")]
123 Self::Glx(e) => e.as_raw(),
124 #[cfg(feature = "present")]
125 Self::Present(e) => e.as_raw(),
126 #[cfg(feature = "randr")]
127 Self::RandR(e) => e.as_raw(),
128 #[cfg(feature = "screensaver")]
129 Self::ScreenSaver(e) => e.as_raw(),
130 #[cfg(feature = "shape")]
131 Self::Shape(e) => e.as_raw(),
132 #[cfg(feature = "shm")]
133 Self::Shm(e) => e.as_raw(),
134 #[cfg(feature = "sync")]
135 Self::Sync(e) => e.as_raw(),
136 #[cfg(feature = "xfixes")]
137 Self::XFixes(e) => e.as_raw(),
138 #[cfg(feature = "xinput")]
139 Self::Input(e) => e.as_raw(),
140 #[cfg(feature = "xkb")]
141 Self::Xkb(e) => e.as_raw(),
142 #[cfg(feature = "xprint")]
143 Self::XPrint(e) => e.as_raw(),
144 #[cfg(feature = "xv")]
145 Self::Xv(e) => e.as_raw(),
146 Self::Unknown(e) => e.as_raw(),
147 }
148 }
149}
150
151pub struct UnknownEvent {
153 raw: *mut xcb_generic_event_t,
154}
155
156impl Raw<xcb_generic_event_t> for UnknownEvent {
157 unsafe fn from_raw(raw: *mut xcb_generic_event_t) -> Self {
158 UnknownEvent { raw }
159 }
160
161 fn as_raw(&self) -> *mut xcb_generic_event_t {
162 self.raw
163 }
164}
165
166impl BaseEvent for UnknownEvent {
167 const EXTENSION: Option<Extension> = None;
168 const NUMBER: u32 = u32::MAX;
169}
170
171impl UnknownEvent {
172 pub fn response_type(&self) -> u8 {
173 unsafe { (*self.raw).response_type }
174 }
175 pub fn sequence(&self) -> u16 {
176 unsafe { (*self.raw).sequence }
177 }
178 pub fn full_sequence(&self) -> u32 {
179 unsafe { (*self.raw).full_sequence }
180 }
181}
182
183unsafe impl Send for UnknownEvent {}
184unsafe impl Sync for UnknownEvent {}
185
186impl std::fmt::Debug for UnknownEvent {
187 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
188 f.debug_tuple("UnknownEvent").finish()
189 }
190}
191
192impl Drop for UnknownEvent {
193 fn drop(&mut self) {
194 unsafe { libc::free(self.raw as *mut _) }
195 }
196}
197
198pub unsafe fn resolve_event(
211 event: *mut xcb_generic_event_t,
212 extension_data: &[ExtensionData],
213) -> Event {
214 let response_type = (*event).response_type & 0x7F;
215
216 if response_type == XCB_GE_GENERIC {
217 let event = event as *mut xcb_ge_generic_event_t;
218 let extension = (*event).extension;
219 for ext in extension_data {
220 if ext.major_opcode == extension {
221 match ext.ext {
222 #[cfg(feature = "present")]
223 Extension::Present => {
224 return Event::Present(present::Event::resolve_wire_ge_event(event));
225 }
226 #[cfg(feature = "xinput")]
227 Extension::Input => {
228 return Event::Input(xinput::Event::resolve_wire_ge_event(event));
229 }
230 _ => panic!("could not resolve Generic Event extension"),
231 }
232 }
233 }
234 return Event::Unknown(UnknownEvent::from_raw(event as *mut _));
235 }
236
237 for data in extension_data {
238 if response_type >= data.first_event && data.first_event != 0 {
239 match data.ext {
240 #[cfg(feature = "damage")]
241 Extension::Damage => {
242 return Event::Damage(
243 damage::Event::resolve_wire_event(data.first_event, event).unwrap(),
244 );
245 }
246
247 #[cfg(feature = "dri2")]
248 Extension::Dri2 => {
249 return Event::Dri2(
250 dri2::Event::resolve_wire_event(data.first_event, event).unwrap(),
251 );
252 }
253
254 #[cfg(feature = "glx")]
255 Extension::Glx => {
256 return Event::Glx(
257 glx::Event::resolve_wire_event(data.first_event, event).unwrap(),
258 );
259 }
260
261 #[cfg(feature = "present")]
262 Extension::Present => {
263 return Event::Present(
264 present::Event::resolve_wire_event(data.first_event, event).unwrap(),
265 );
266 }
267
268 #[cfg(feature = "randr")]
269 Extension::RandR => {
270 return Event::RandR(
271 randr::Event::resolve_wire_event(data.first_event, event).unwrap(),
272 );
273 }
274
275 #[cfg(feature = "screensaver")]
276 Extension::ScreenSaver => {
277 return Event::ScreenSaver(
278 screensaver::Event::resolve_wire_event(data.first_event, event).unwrap(),
279 );
280 }
281
282 #[cfg(feature = "shape")]
283 Extension::Shape => {
284 return Event::Shape(
285 shape::Event::resolve_wire_event(data.first_event, event).unwrap(),
286 );
287 }
288
289 #[cfg(feature = "shm")]
290 Extension::Shm => {
291 return Event::Shm(
292 shm::Event::resolve_wire_event(data.first_event, event).unwrap(),
293 );
294 }
295
296 #[cfg(feature = "sync")]
297 Extension::Sync => {
298 return Event::Sync(
299 sync::Event::resolve_wire_event(data.first_event, event).unwrap(),
300 );
301 }
302
303 #[cfg(feature = "xfixes")]
304 Extension::XFixes => {
305 return Event::XFixes(
306 xfixes::Event::resolve_wire_event(data.first_event, event).unwrap(),
307 );
308 }
309
310 #[cfg(feature = "xinput")]
311 Extension::Input => {
312 return Event::Input(
313 xinput::Event::resolve_wire_event(data.first_event, event).unwrap(),
314 );
315 }
316
317 #[cfg(feature = "xkb")]
318 Extension::Xkb => {
319 return Event::Xkb(
320 xkb::Event::resolve_wire_event(data.first_event, event).unwrap(),
321 );
322 }
323
324 #[cfg(feature = "xprint")]
325 Extension::XPrint => {
326 return Event::XPrint(
327 xprint::Event::resolve_wire_event(data.first_event, event).unwrap(),
328 );
329 }
330
331 #[cfg(feature = "xv")]
332 Extension::Xv => {
333 return Event::Xv(
334 xv::Event::resolve_wire_event(data.first_event, event).unwrap(),
335 );
336 }
337
338 _ => {}
339 }
340 }
341 }
342
343 x::Event::resolve_wire_event(0, event)
344 .map(Event::X)
345 .unwrap_or_else(|| {
346 let unknown = UnknownEvent::from_raw(event);
349 Event::Unknown(unknown)
350 })
351}
352
353#[test]
354fn test_event_send_sync() {
355 fn assert_send<T: Send>() {}
356 fn assert_sync<T: Sync>() {}
357
358 assert_send::<Event>();
359 assert_sync::<Event>();
360}