use super::cookie::VoidCookie;
use super::errors::{ConnectionError, ReplyError};
use super::protocol::xproto::{Atom, ConnectionExt as XProtoConnectionExt, PropMode, Window};
pub trait ConnectionExt: XProtoConnectionExt {
fn change_property8<A, B>(
&self,
mode: PropMode,
window: Window,
property: A,
type_: B,
data: &[u8],
) -> Result<VoidCookie<'_, Self>, ConnectionError>
where
A: Into<Atom>,
B: Into<Atom>,
{
self.change_property(
mode,
window,
property,
type_,
8,
data.len().try_into().expect("`data` has too many elements"),
data,
)
}
fn change_property16<A, B>(
&self,
mode: PropMode,
window: Window,
property: A,
type_: B,
data: &[u16],
) -> Result<VoidCookie<'_, Self>, ConnectionError>
where
A: Into<Atom>,
B: Into<Atom>,
{
let mut data_u8 = Vec::with_capacity(data.len() * 2);
for item in data {
data_u8.extend(item.to_ne_bytes());
}
self.change_property(
mode,
window,
property,
type_,
16,
data.len().try_into().expect("`data` has too many elements"),
&data_u8,
)
}
fn change_property32<A, B>(
&self,
mode: PropMode,
window: Window,
property: A,
type_: B,
data: &[u32],
) -> Result<VoidCookie<'_, Self>, ConnectionError>
where
A: Into<Atom>,
B: Into<Atom>,
{
let mut data_u8 = Vec::with_capacity(data.len() * 4);
for item in data {
data_u8.extend(item.to_ne_bytes());
}
self.change_property(
mode,
window,
property,
type_,
32,
data.len().try_into().expect("`data` has too many elements"),
&data_u8,
)
}
fn sync(&self) -> Result<(), ReplyError> {
self.get_input_focus()?.reply().and(Ok(()))
}
}
impl<C: XProtoConnectionExt + ?Sized> ConnectionExt for C {}
#[derive(Debug)]
pub struct GrabServer<'c, C: XProtoConnectionExt>(&'c C);
impl<'c, C: XProtoConnectionExt> GrabServer<'c, C> {
pub fn grab(conn: &'c C) -> Result<Self, ConnectionError> {
drop(conn.grab_server()?);
Ok(Self(conn))
}
}
impl<C: XProtoConnectionExt> Drop for GrabServer<'_, C> {
fn drop(&mut self) {
let _ = (self.0).ungrab_server();
}
}