1use crate::base::{Connection, Reply};
2use crate::ffi::{
3 xcb_connection_t, xcb_extension_t, xcb_get_extension_data, xcb_prefetch_extension_data,
4};
5use crate::x;
6
7use std::fmt;
8use std::mem;
9use std::ptr;
10
11#[derive(Copy, Clone, Debug, PartialEq, Eq)]
13pub enum Extension {
14 BigRequests,
16
17 XcMisc,
19
20 #[cfg(feature = "composite")]
21 Composite,
24
25 #[cfg(feature = "damage")]
26 Damage,
29
30 #[cfg(feature = "dpms")]
31 Dpms,
34
35 #[cfg(feature = "dri2")]
36 Dri2,
39
40 #[cfg(feature = "dri3")]
41 Dri3,
44
45 #[cfg(feature = "ge")]
46 GenericEvent,
49
50 #[cfg(feature = "glx")]
51 Glx,
54
55 #[cfg(feature = "present")]
56 Present,
59
60 #[cfg(feature = "randr")]
61 RandR,
64
65 #[cfg(feature = "record")]
66 Record,
69
70 #[cfg(feature = "render")]
71 Render,
74
75 #[cfg(feature = "res")]
76 Res,
79
80 #[cfg(feature = "screensaver")]
81 ScreenSaver,
84
85 #[cfg(feature = "shape")]
86 Shape,
89
90 #[cfg(feature = "shm")]
91 Shm,
94
95 #[cfg(feature = "sync")]
96 Sync,
99
100 #[cfg(feature = "xevie")]
101 Xevie,
104
105 #[cfg(feature = "xf86dri")]
106 Xf86Dri,
109
110 #[cfg(feature = "xf86vidmode")]
111 Xf86VidMode,
114
115 #[cfg(feature = "xfixes")]
116 XFixes,
119
120 #[cfg(feature = "xinerama")]
121 Xinerama,
124
125 #[cfg(feature = "xinput")]
126 Input,
129
130 #[cfg(feature = "xkb")]
131 Xkb,
134
135 #[cfg(feature = "xprint")]
136 XPrint,
139
140 #[cfg(feature = "xselinux")]
141 SeLinux,
144
145 #[cfg(feature = "xtest")]
146 Test,
149
150 #[cfg(feature = "xv")]
151 Xv,
154
155 #[cfg(feature = "xvmc")]
156 XvMc,
159}
160
161impl Extension {
162 fn xname(&self) -> &'static str {
165 match self {
166 Extension::BigRequests => crate::bigreq::XNAME,
167 Extension::XcMisc => crate::xc_misc::XNAME,
168
169 #[cfg(feature = "composite")]
170 Extension::Composite => crate::composite::XNAME,
171
172 #[cfg(feature = "damage")]
173 Extension::Damage => crate::damage::XNAME,
174
175 #[cfg(feature = "dpms")]
176 Extension::Dpms => crate::dpms::XNAME,
177
178 #[cfg(feature = "dri2")]
179 Extension::Dri2 => crate::dri2::XNAME,
180
181 #[cfg(feature = "dri3")]
182 Extension::Dri3 => crate::dri3::XNAME,
183
184 #[cfg(feature = "ge")]
185 Extension::GenericEvent => crate::ge::XNAME,
186
187 #[cfg(feature = "glx")]
188 Extension::Glx => crate::glx::XNAME,
189
190 #[cfg(feature = "present")]
191 Extension::Present => crate::present::XNAME,
192
193 #[cfg(feature = "randr")]
194 Extension::RandR => crate::randr::XNAME,
195
196 #[cfg(feature = "record")]
197 Extension::Record => crate::record::XNAME,
198
199 #[cfg(feature = "render")]
200 Extension::Render => crate::render::XNAME,
201
202 #[cfg(feature = "res")]
203 Extension::Res => crate::res::XNAME,
204
205 #[cfg(feature = "screensaver")]
206 Extension::ScreenSaver => crate::screensaver::XNAME,
207
208 #[cfg(feature = "shape")]
209 Extension::Shape => crate::shape::XNAME,
210
211 #[cfg(feature = "shm")]
212 Extension::Shm => crate::shm::XNAME,
213
214 #[cfg(feature = "sync")]
215 Extension::Sync => crate::sync::XNAME,
216
217 #[cfg(feature = "xevie")]
218 Extension::Xevie => crate::xevie::XNAME,
219
220 #[cfg(feature = "xf86dri")]
221 Extension::Xf86Dri => crate::xf86dri::XNAME,
222
223 #[cfg(feature = "xf86vidmode")]
224 Extension::Xf86VidMode => crate::xf86vidmode::XNAME,
225
226 #[cfg(feature = "xfixes")]
227 Extension::XFixes => crate::xfixes::XNAME,
228
229 #[cfg(feature = "xinerama")]
230 Extension::Xinerama => crate::xinerama::XNAME,
231
232 #[cfg(feature = "xinput")]
233 Extension::Input => crate::xinput::XNAME,
234
235 #[cfg(feature = "xkb")]
236 Extension::Xkb => crate::xkb::XNAME,
237
238 #[cfg(feature = "xprint")]
239 Extension::XPrint => crate::xprint::XNAME,
240
241 #[cfg(feature = "xselinux")]
242 Extension::SeLinux => crate::xselinux::XNAME,
243
244 #[cfg(feature = "xtest")]
245 Extension::Test => crate::xtest::XNAME,
246
247 #[cfg(feature = "xv")]
248 Extension::Xv => crate::xv::XNAME,
249
250 #[cfg(feature = "xvmc")]
251 Extension::XvMc => crate::xvmc::XNAME,
252 }
253 }
254}
255
256impl fmt::Display for Extension {
257 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
258 self.xname().fmt(f)
259 }
260}
261
262#[derive(Debug)]
266pub struct ExtensionData {
267 pub ext: Extension,
268 pub major_opcode: u8,
269 pub first_event: u8,
270 pub first_error: u8,
271}
272
273pub fn cache_extensions_data(
280 conn: *mut xcb_connection_t,
281 mandatory: &[Extension],
282 optional: &[Extension],
283) -> Vec<ExtensionData> {
284 unsafe {
285 for ext in mandatory {
286 let ext_id = get_extension_id(*ext);
287 xcb_prefetch_extension_data(conn, ext_id);
288 }
289 for ext in optional {
290 let ext_id = get_extension_id(*ext);
291 xcb_prefetch_extension_data(conn, ext_id);
292 }
293
294 let mut ext_data = Vec::new();
295
296 for ext in mandatory {
297 let ext_id = get_extension_id(*ext);
298 let raw = xcb_get_extension_data(conn, ext_id);
299 let reply = x::QueryExtensionReply::from_raw(raw);
300
301 assert!(
302 reply.present(),
303 "mandatory extension {} is not present on this system",
304 ext
305 );
306 ext_data.push(ExtensionData {
307 ext: *ext,
308 major_opcode: reply.major_opcode(),
309 first_event: reply.first_event(),
310 first_error: reply.first_error(),
311 });
312 mem::forget(reply);
313 }
314
315 for ext in optional {
316 let ext_id = get_extension_id(*ext);
317 let raw = xcb_get_extension_data(conn, ext_id);
318 let reply = x::QueryExtensionReply::from_raw(raw);
319
320 if !reply.present() {
321 mem::forget(reply);
322 continue;
323 }
324
325 ext_data.push(ExtensionData {
326 ext: *ext,
327 major_opcode: reply.major_opcode(),
328 first_event: reply.first_event(),
329 first_error: reply.first_error(),
330 });
331 mem::forget(reply);
332 }
333
334 ext_data.sort_by(|a, b| b.first_event.cmp(&a.first_event));
336
337 ext_data
338 }
339}
340
341unsafe fn get_extension_id(ext: Extension) -> *mut xcb_extension_t {
342 match ext {
343 Extension::BigRequests => ptr::addr_of_mut!(crate::bigreq::FFI_EXT),
344 Extension::XcMisc => ptr::addr_of_mut!(crate::xc_misc::FFI_EXT),
345
346 #[cfg(feature = "composite")]
347 Extension::Composite => ptr::addr_of_mut!(crate::composite::FFI_EXT),
348
349 #[cfg(feature = "damage")]
350 Extension::Damage => ptr::addr_of_mut!(crate::damage::FFI_EXT),
351
352 #[cfg(feature = "dpms")]
353 Extension::Dpms => ptr::addr_of_mut!(crate::dpms::FFI_EXT),
354
355 #[cfg(feature = "dri2")]
356 Extension::Dri2 => ptr::addr_of_mut!(crate::dri2::FFI_EXT),
357
358 #[cfg(feature = "dri3")]
359 Extension::Dri3 => ptr::addr_of_mut!(crate::dri3::FFI_EXT),
360
361 #[cfg(feature = "ge")]
362 Extension::GenericEvent => ptr::addr_of_mut!(crate::ge::FFI_EXT),
363
364 #[cfg(feature = "glx")]
365 Extension::Glx => ptr::addr_of_mut!(crate::glx::FFI_EXT),
366
367 #[cfg(feature = "present")]
368 Extension::Present => ptr::addr_of_mut!(crate::present::FFI_EXT),
369
370 #[cfg(feature = "randr")]
371 Extension::RandR => ptr::addr_of_mut!(crate::randr::FFI_EXT),
372
373 #[cfg(feature = "record")]
374 Extension::Record => ptr::addr_of_mut!(crate::record::FFI_EXT),
375
376 #[cfg(feature = "render")]
377 Extension::Render => ptr::addr_of_mut!(crate::render::FFI_EXT),
378
379 #[cfg(feature = "res")]
380 Extension::Res => ptr::addr_of_mut!(crate::res::FFI_EXT),
381
382 #[cfg(feature = "screensaver")]
383 Extension::ScreenSaver => ptr::addr_of_mut!(crate::screensaver::FFI_EXT),
384
385 #[cfg(feature = "shape")]
386 Extension::Shape => ptr::addr_of_mut!(crate::shape::FFI_EXT),
387
388 #[cfg(feature = "shm")]
389 Extension::Shm => ptr::addr_of_mut!(crate::shm::FFI_EXT),
390
391 #[cfg(feature = "sync")]
392 Extension::Sync => ptr::addr_of_mut!(crate::sync::FFI_EXT),
393
394 #[cfg(feature = "xevie")]
395 Extension::Xevie => ptr::addr_of_mut!(crate::xevie::FFI_EXT),
396
397 #[cfg(feature = "xf86dri")]
398 Extension::Xf86Dri => ptr::addr_of_mut!(crate::xf86dri::FFI_EXT),
399
400 #[cfg(feature = "xf86vidmode")]
401 Extension::Xf86VidMode => ptr::addr_of_mut!(crate::xf86vidmode::FFI_EXT),
402
403 #[cfg(feature = "xfixes")]
404 Extension::XFixes => ptr::addr_of_mut!(crate::xfixes::FFI_EXT),
405
406 #[cfg(feature = "xinerama")]
407 Extension::Xinerama => ptr::addr_of_mut!(crate::xinerama::FFI_EXT),
408
409 #[cfg(feature = "xinput")]
410 Extension::Input => ptr::addr_of_mut!(crate::xinput::FFI_EXT),
411
412 #[cfg(feature = "xkb")]
413 Extension::Xkb => ptr::addr_of_mut!(crate::xkb::FFI_EXT),
414
415 #[cfg(feature = "xprint")]
416 Extension::XPrint => ptr::addr_of_mut!(crate::xprint::FFI_EXT),
417
418 #[cfg(feature = "xselinux")]
419 Extension::SeLinux => ptr::addr_of_mut!(crate::xselinux::FFI_EXT),
420
421 #[cfg(feature = "xtest")]
422 Extension::Test => ptr::addr_of_mut!(crate::xtest::FFI_EXT),
423
424 #[cfg(feature = "xv")]
425 Extension::Xv => ptr::addr_of_mut!(crate::xv::FFI_EXT),
426
427 #[cfg(feature = "xvmc")]
428 Extension::XvMc => ptr::addr_of_mut!(crate::xvmc::FFI_EXT),
429 }
430}