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
|
/* Color management in X has become an obscure topic because everyone prefers
* to assume they have 24-bit direct. In dealing with it, [1] has been an
* important resource.
*
* [1] https://xcb.freedesktop.org/xlibtoxcbtranslationguide/
*/
use crate::x::connection::*;
use crate::x::display::*;
use x11::xrender::XRenderColor;
use x11::xft::XftColor;
use xcb::x::{ AllocColor, Visualtype };
pub struct Color {
/* We need to store both the original 16-bit components and the pixel
* value. Additionally, there are situations in which we need to return
* an XftColor, which contains both of those. So, we might as well use it
* as the authoritative format.
*
* We treat the contents as opaque, to allow us to pretend it's
* something cleaner. :)
*/
font_color: XftColor,
}
impl Color {
/* Please notice that the constructor is private. */
fn new(pixel: u32, red: u16, green: u16, blue: u16) -> Self {
Color {
font_color: XftColor {
pixel: pixel as u64,
color: XRenderColor {
red, green, blue,
alpha: 65535,
}
}
}
}
pub fn as_pixel(&self) -> u32 {
self.font_color.pixel as u32
}
pub fn as_xft_color(&self) -> &XftColor {
&self.font_color
}
}
pub trait DisplayColorExt: DisplayExt {
/* This is sufficiently obscure knowledge that it's worth keeping here
* even though it's unused.
*/
#[allow(dead_code)]
fn find_root_visual(&self) -> Option<&Visualtype> {
let visual_id = self.screen().root_visual();
for depth in self.screen().allowed_depths() {
for visual in depth.visuals() {
if visual_id == visual.visual_id() {
return Some(visual);
}
}
}
None
}
fn allocate_color(&self, red: u16, green: u16, blue: u16)
-> xcb::Result<Color>
{
let connection = self.connection();
let colormap = self.screen().default_colormap();
let cookie = connection.send_request(&AllocColor {
cmap: colormap,
red, green, blue,
});
let pixel = connection.wait_for_reply(cookie)?.pixel();
Ok(Color::new(pixel, red, green, blue))
}
}
impl<T: DisplayExt> DisplayColorExt for T { }
|