use x11rb::protocol::xproto::*;
pub fn find_visual_by_depth(screen: &Screen, depth: u8) -> Option<Visualtype> {
screen
.allowed_depths
.iter()
.filter(|depth_info| depth_info.depth == depth)
.flat_map(|depth_info| &depth_info.visuals)
.find(|visual| visual.class == VisualClass::TRUE_COLOR)
.copied()
}
pub fn find_argb_visual(screen: &Screen) -> Option<Visualtype> {
find_visual_by_depth(screen, 32)
}
pub fn find_rgb_visual(screen: &Screen) -> Option<Visualtype> {
find_visual_by_depth(screen, 24)
}
pub fn get_visual_info(visual: &Visualtype) -> VisualInfo {
let r_bits = visual.red_mask.count_ones() as u8;
let g_bits = visual.green_mask.count_ones() as u8;
let b_bits = visual.blue_mask.count_ones() as u8;
let r_shift = visual.red_mask.trailing_zeros() as u8;
let g_shift = visual.green_mask.trailing_zeros() as u8;
let b_shift = visual.blue_mask.trailing_zeros() as u8;
VisualInfo {
visual_id: visual.visual_id,
class: visual.class,
bits_per_rgb: visual.bits_per_rgb_value,
colormap_entries: visual.colormap_entries,
red_mask: visual.red_mask,
green_mask: visual.green_mask,
blue_mask: visual.blue_mask,
red_bits: r_bits,
green_bits: g_bits,
blue_bits: b_bits,
red_shift: r_shift,
green_shift: g_shift,
blue_shift: b_shift,
total_bits: r_bits + g_bits + b_bits,
}
}
#[derive(Debug, Clone)]
pub struct VisualInfo {
pub visual_id: Visualid,
pub class: VisualClass,
pub bits_per_rgb: u8,
pub colormap_entries: u16,
pub red_mask: u32,
pub green_mask: u32,
pub blue_mask: u32,
pub red_bits: u8,
pub green_bits: u8,
pub blue_bits: u8,
pub red_shift: u8,
pub green_shift: u8,
pub blue_shift: u8,
pub total_bits: u8,
}
impl VisualInfo {
pub fn supports_transparency(&self) -> bool {
self.total_bits > 24
}
pub fn pack_rgb(&self, r: u8, g: u8, b: u8) -> u32 {
((r as u32) << self.red_shift)
| ((g as u32) << self.green_shift)
| ((b as u32) << self.blue_shift)
}
pub fn pack_argb(&self, a: u8, r: u8, g: u8, b: u8) -> u32 {
if self.supports_transparency() {
((a as u32) << 24) | self.pack_rgb(r, g, b)
} else {
self.pack_rgb(r, g, b)
}
}
pub fn unpack_rgb(&self, pixel: u32) -> (u8, u8, u8) {
let r = ((pixel & self.red_mask) >> self.red_shift) as u8;
let g = ((pixel & self.green_mask) >> self.green_shift) as u8;
let b = ((pixel & self.blue_mask) >> self.blue_shift) as u8;
(r, g, b)
}
}