use crate::{
auto::xproto::{AllocColorReply, AllocColorRequest, Colormap},
Connection, Display, RequestCookie,
};
#[inline]
#[must_use]
pub const fn rgb(r: u8, g: u8, b: u8) -> u32 {
let r = r as u32;
let g = g as u32;
let b = b as u32;
b + (g << 8) + (r << 16)
}
#[derive(Debug, Clone, Copy)]
pub enum ColorAllocation {
NoChange(u32),
Changed {
pixel: u32,
red: u16,
green: u16,
blue: u16,
},
}
impl ColorAllocation {
#[inline]
#[must_use]
pub fn pixel(&self) -> u32 {
match self {
Self::NoChange(pixel) | Self::Changed { pixel, .. } => *pixel,
}
}
#[inline]
#[must_use]
pub fn from_alloc_color_reply(acr: AllocColorReply, r: u16, g: u16, b: u16) -> Self {
if acr.red == r && acr.green == g && acr.blue == b {
Self::NoChange(acr.pixel)
} else {
Self::Changed {
red: acr.red,
green: acr.green,
blue: acr.blue,
pixel: acr.pixel,
}
}
}
}
impl From<ColorAllocation> for u32 {
#[inline]
fn from(ca: ColorAllocation) -> u32 {
ca.pixel()
}
}
impl Colormap {
#[inline]
fn alloc_color_request(self, r: u16, g: u16, b: u16) -> AllocColorRequest {
AllocColorRequest {
cmap: self,
red: r,
green: g,
blue: b,
..Default::default()
}
}
#[inline]
pub fn alloc_color<Conn: Connection>(
self,
dpy: &mut Display<Conn>,
r: u16,
g: u16,
b: u16,
) -> crate::Result<RequestCookie<AllocColorRequest>> {
let acr = self.alloc_color_request(r, g, b);
log::debug!("Sending AllocColorRequest to server.");
let tok = dpy.send_request(acr)?;
log::debug!("Sent AllocColorRequest to server.");
Ok(tok)
}
#[cfg(feature = "async")]
#[inline]
pub async fn alloc_color_async<Conn: Connection>(
self,
dpy: &mut Display<Conn>,
r: u16,
g: u16,
b: u16,
) -> crate::Result<RequestCookie<AllocColorRequest>> {
let acr = self.alloc_color_request(r, g, b);
log::debug!("Sending AllocColorRequest to server.");
let tok = dpy.send_request_async(acr).await?;
log::debug!("Sent AllocColorRequest to server.");
Ok(tok)
}
#[inline]
pub fn alloc_color_immediate<Conn: Connection>(
self,
dpy: &mut Display<Conn>,
r: u16,
g: u16,
b: u16,
) -> crate::Result<ColorAllocation> {
let tok = self.alloc_color(dpy, r, g, b)?;
Ok(ColorAllocation::from_alloc_color_reply(
dpy.resolve_request(tok)?,
r,
g,
b,
))
}
#[cfg(feature = "async")]
#[inline]
pub async fn alloc_color_immediate_async<Conn: Connection>(
self,
dpy: &mut Display<Conn>,
r: u16,
g: u16,
b: u16,
) -> crate::Result<ColorAllocation> {
let tok = self.alloc_color_async(dpy, r, g, b).await?;
Ok(ColorAllocation::from_alloc_color_reply(
dpy.resolve_request_async(tok).await?,
r,
g,
b,
))
}
}