1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
use crate::platform::unix::x11::XConnection;
use glutin_glx_sys as ffi;
use std::sync::Arc;
pub fn get_visual_info_from_xid(xconn: &Arc<XConnection>, xid: ffi::VisualID) -> ffi::XVisualInfo {
assert_ne!(xid, 0);
let mut template: ffi::XVisualInfo = unsafe { std::mem::zeroed() };
template.visualid = xid;
let mut num_visuals = 0;
let vi = unsafe {
(xconn.xlib.XGetVisualInfo)(
xconn.display,
ffi::VisualIDMask,
&mut template,
&mut num_visuals,
)
};
xconn.check_errors().expect("Failed to call `XGetVisualInfo`");
assert!(!vi.is_null());
assert!(num_visuals == 1);
let vi_copy = unsafe { std::ptr::read(vi as *const _) };
unsafe {
(xconn.xlib.XFree)(vi as *mut _);
}
vi_copy
}
#[derive(Clone, Copy, Debug)]
pub enum Lacks {
Transparency,
XID,
}
pub fn examine_visual_info(
xconn: &Arc<XConnection>,
visual_infos: ffi::XVisualInfo,
want_transparency: bool,
want_xid: Option<ffi::VisualID>,
) -> Result<(), Lacks> {
if let Some(want_xid) = want_xid {
if visual_infos.visualid != want_xid {
return Err(Lacks::XID);
}
}
unsafe {
if want_transparency {
let pict_format = (xconn.xrender.XRenderFindVisualFormat)(
xconn.display as *mut _,
visual_infos.visual,
);
if pict_format.is_null() {
return Err(Lacks::Transparency);
}
if (*pict_format).direct.alphaMask == 0 {
return Err(Lacks::Transparency);
}
}
}
return Ok(());
}
pub use super::select_config;
pub use crate::api::egl::SurfaceType;