forked from RustAudio/baseview
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathvisual_info.rs
More file actions
94 lines (82 loc) · 2.95 KB
/
visual_info.rs
File metadata and controls
94 lines (82 loc) · 2.95 KB
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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
use crate::x11::xcb_connection::XcbConnection;
use std::error::Error;
use x11rb::connection::Connection;
use x11rb::protocol::xproto::{
Colormap, ColormapAlloc, ConnectionExt, Screen, VisualClass, Visualid,
};
use x11rb::COPY_FROM_PARENT;
pub(super) struct WindowVisualConfig {
#[cfg(feature = "opengl")]
pub fb_config: Option<crate::gl::x11::FbConfig>,
pub visual_depth: u8,
pub visual_id: Visualid,
pub color_map: Option<Colormap>,
}
// TODO: make visual negotiation actually check all of a visual's parameters
impl WindowVisualConfig {
#[cfg(feature = "opengl")]
pub fn find_best_visual_config_for_gl(
connection: &XcbConnection, gl_config: Option<crate::gl::GlConfig>,
) -> Result<Self, Box<dyn Error>> {
let Some(gl_config) = gl_config else { return Self::find_best_visual_config(connection) };
// SAFETY: TODO
let (fb_config, window_config) = unsafe {
crate::gl::platform::GlContext::get_fb_config_and_visual(connection.dpy, gl_config)
}
.expect("Could not fetch framebuffer config");
Ok(Self {
fb_config: Some(fb_config),
visual_depth: window_config.depth,
visual_id: window_config.visual,
color_map: Some(create_color_map(connection, window_config.visual)?),
})
}
pub fn find_best_visual_config(connection: &XcbConnection) -> Result<Self, Box<dyn Error>> {
match find_visual_for_depth(connection.screen(), 32) {
None => Ok(Self::copy_from_parent()),
Some(visual_id) => Ok(Self {
#[cfg(feature = "opengl")]
fb_config: None,
visual_id,
visual_depth: 32,
color_map: Some(create_color_map(connection, visual_id)?),
}),
}
}
const fn copy_from_parent() -> Self {
Self {
#[cfg(feature = "opengl")]
fb_config: None,
visual_depth: COPY_FROM_PARENT as u8,
visual_id: COPY_FROM_PARENT,
color_map: None,
}
}
}
// For this 32-bit depth to work, you also need to define a color map and set a border
// pixel: https://cgit.freedesktop.org/xorg/xserver/tree/dix/window.c#n818
fn create_color_map(
connection: &XcbConnection, visual_id: Visualid,
) -> Result<Colormap, Box<dyn Error>> {
let colormap = connection.conn.generate_id()?;
connection.conn.create_colormap(
ColormapAlloc::NONE,
colormap,
connection.screen().root,
visual_id,
)?;
Ok(colormap)
}
fn find_visual_for_depth(screen: &Screen, depth: u8) -> Option<Visualid> {
for candidate_depth in &screen.allowed_depths {
if candidate_depth.depth != depth {
continue;
}
for candidate_visual in &candidate_depth.visuals {
if candidate_visual.class == VisualClass::TRUE_COLOR {
return Some(candidate_visual.visual_id);
}
}
}
None
}