#[doc(hidden)]
#[macro_export]
macro_rules! mtry {
($expr: expr) => {
match ($expr)? {
AsyncStatus::Ready(t) => t,
status => return Ok(status.map(|_| unreachable!())),
}
};
}
mod basic;
pub use basic::BasicDisplay;
cfg_std! {
pub use basic::DisplayConnection;
}
mod cell;
pub use cell::CellDisplay;
mod cookie;
pub use cookie::Cookie;
mod ext;
pub use ext::*;
mod extension_map;
pub(crate) use extension_map::ExtensionMap;
mod sans_io;
pub(crate) use sans_io::X11Core;
mod poison;
pub(crate) use poison::Poisonable;
mod prefetch;
pub(crate) use prefetch::Prefetch;
mod raw_request;
pub use raw_request::{
from_reply_fds_request, from_reply_request, from_void_request, RawReply, RawRequest,
};
cfg_sync! {
mod sync;
pub use sync::SyncDisplay;
}
cfg_test! {
}
pub use crate::automatically_generated::DisplayFunctionsExt;
cfg_async! {
pub use crate::automatically_generated::AsyncDisplayFunctionsExt;
pub(crate) use raw_request::BufferedRequest;
use core::task::{Context, Poll};
}
use crate::Result;
use alloc::{boxed::Box, sync::Arc};
use x11rb_protocol::protocol::{
xproto::{GetInputFocusRequest, Screen, Setup},
Event,
};
pub trait DisplayBase {
fn setup(&self) -> &Arc<Setup>;
fn default_screen_index(&self) -> usize;
fn poll_for_reply_raw(&mut self, seq: u64) -> Result<Option<RawReply>>;
fn poll_for_event(&mut self) -> Result<Option<Event>>;
fn screens(&self) -> &[Screen] {
&self.setup().roots
}
fn default_screen(&self) -> &Screen {
self.screens()
.get(self.default_screen_index())
.unwrap_or_else(|| {
panic!(
"Default screen index {} is not a valid screen",
self.default_screen_index()
)
})
}
}
pub trait Display: DisplayBase {
fn send_request_raw(&mut self, req: RawRequest<'_, '_>) -> Result<u64>;
fn wait_for_reply_raw(&mut self, seq: u64) -> Result<RawReply>;
fn wait_for_event(&mut self) -> Result<Event>;
fn maximum_request_length(&mut self) -> Result<usize>;
fn generate_xid(&mut self) -> Result<u32>;
fn synchronize(&mut self) -> Result<()> {
let span = tracing::info_span!("synchronize");
let _enter = span.enter();
let get_input_focus = GetInputFocusRequest {};
raw_request::from_reply_request(get_input_focus, |req| {
let seq = self.send_request_raw(req)?;
self.flush()?;
self.wait_for_reply_raw(seq).map(|_| ())
})
}
fn check_for_error(&mut self, seq: u64) -> Result<()>;
fn flush(&mut self) -> Result<()>;
}
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[cfg_attr(not(feature = "async"), doc(hidden))]
pub enum AsyncStatus<T> {
Ready(T),
Read,
Write,
UserControlled,
}
impl<T> AsyncStatus<T> {
pub fn is_ready(&self) -> bool {
matches!(self, Self::Ready(_))
}
pub fn map<R>(self, f: impl FnOnce(T) -> R) -> AsyncStatus<R> {
match self {
Self::Ready(t) => AsyncStatus::Ready(f(t)),
Self::Read => AsyncStatus::Read,
Self::Write => AsyncStatus::Write,
Self::UserControlled => AsyncStatus::UserControlled,
}
}
pub fn unwrap(self) -> T {
match self {
Self::Ready(t) => t,
_ => panic!("unwrap() called on non-ready AsyncStatus"),
}
}
pub fn ready(self) -> Option<T> {
match self {
Self::Ready(t) => Some(t),
_ => None,
}
}
}
impl<T: Copy> AsyncStatus<&T> {
#[must_use]
pub fn copied(self) -> AsyncStatus<T> {
self.map(|&t| t)
}
}
cfg_async! {
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum Interest {
Readable,
Writable,
}
pub trait CanBeAsyncDisplay: DisplayBase {
fn format_request(
&mut self,
req: &mut RawRequest<'_, '_>,
ctx: &mut Context<'_>,
) -> Result<AsyncStatus<u64>>;
fn try_send_request_raw(
&mut self,
req: &mut RawRequest<'_, '_>,
ctx: &mut Context<'_>,
) -> Result<AsyncStatus<()>>;
fn try_wait_for_reply_raw(
&mut self,
seq: u64,
ctx: &mut Context<'_>,
) -> Result<AsyncStatus<RawReply>>;
fn try_wait_for_event(&mut self, ctx: &mut Context<'_>) -> Result<AsyncStatus<Event>>;
fn try_flush(&mut self, ctx: &mut Context<'_>) -> Result<AsyncStatus<()>>;
fn try_generate_xid(&mut self, ctx: &mut Context<'_>) -> Result<AsyncStatus<u32>>;
fn try_maximum_request_length(&mut self, ctx: &mut Context<'_>) -> Result<AsyncStatus<usize>>;
fn try_check_for_error(&mut self, seq: u64, ctx: &mut Context<'_>) -> Result<AsyncStatus<()>>;
}
pub trait AsyncDisplay: CanBeAsyncDisplay {
fn poll_for_interest(
&mut self,
interest: Interest,
callback: &mut dyn FnMut(&mut dyn AsyncDisplay, &mut Context<'_>) -> Result<()>,
ctx: &mut Context<'_>,
) -> Poll<Result<()>>;
}
}
impl<D: DisplayBase + ?Sized> DisplayBase for &mut D {
fn setup(&self) -> &Arc<Setup> {
(**self).setup()
}
fn default_screen_index(&self) -> usize {
(**self).default_screen_index()
}
fn poll_for_event(&mut self) -> Result<Option<Event>> {
(**self).poll_for_event()
}
fn poll_for_reply_raw(&mut self, seq: u64) -> Result<Option<RawReply>> {
(**self).poll_for_reply_raw(seq)
}
}
impl<D: Display + ?Sized> Display for &mut D {
fn send_request_raw(&mut self, req: RawRequest<'_, '_>) -> Result<u64> {
(**self).send_request_raw(req)
}
fn wait_for_event(&mut self) -> Result<Event> {
(**self).wait_for_event()
}
fn wait_for_reply_raw(&mut self, seq: u64) -> Result<RawReply> {
(**self).wait_for_reply_raw(seq)
}
fn flush(&mut self) -> Result<()> {
(**self).flush()
}
fn synchronize(&mut self) -> Result<()> {
(**self).synchronize()
}
fn generate_xid(&mut self) -> Result<u32> {
(**self).generate_xid()
}
fn maximum_request_length(&mut self) -> Result<usize> {
(**self).maximum_request_length()
}
fn check_for_error(&mut self, seq: u64) -> Result<()> {
(**self).check_for_error(seq)
}
}
cfg_async! {
impl<D: CanBeAsyncDisplay + ?Sized> CanBeAsyncDisplay for &mut D {
fn format_request(
&mut self,
req: &mut RawRequest<'_, '_>,
ctx: &mut Context<'_>,
) -> Result<AsyncStatus<u64>> {
(**self).format_request(req, ctx)
}
fn try_send_request_raw(
&mut self,
req: &mut RawRequest<'_, '_>,
ctx: &mut Context<'_>,
) -> Result<AsyncStatus<()>> {
(**self).try_send_request_raw(req, ctx)
}
fn try_wait_for_event(&mut self, ctx: &mut Context<'_>) -> Result<AsyncStatus<Event>> {
(**self).try_wait_for_event(ctx)
}
fn try_wait_for_reply_raw(
&mut self,
seq: u64,
ctx: &mut Context<'_>,
) -> Result<AsyncStatus<RawReply>> {
(**self).try_wait_for_reply_raw(seq, ctx)
}
fn try_flush(&mut self, ctx: &mut Context<'_>) -> Result<AsyncStatus<()>> {
(**self).try_flush(ctx)
}
fn try_generate_xid(&mut self, ctx: &mut Context<'_>) -> Result<AsyncStatus<u32>> {
(**self).try_generate_xid(ctx)
}
fn try_maximum_request_length(&mut self, ctx: &mut Context<'_>) -> Result<AsyncStatus<usize>> {
(**self).try_maximum_request_length(ctx)
}
fn try_check_for_error(
&mut self,
seq: u64,
ctx: &mut Context<'_>,
) -> Result<AsyncStatus<()>> {
(**self).try_check_for_error(seq, ctx)
}
}
impl<D: AsyncDisplay + ?Sized> AsyncDisplay for &mut D {
fn poll_for_interest(
&mut self,
interest: Interest,
callback: &mut dyn FnMut(&mut dyn AsyncDisplay, &mut Context< '_>) -> Result<()>,
ctx: &mut Context< '_>
) -> Poll<Result<()>> {
(**self).poll_for_interest(interest, callback, ctx)
}
}
}
impl<D: DisplayBase + ?Sized> DisplayBase for Box<D> {
fn setup(&self) -> &Arc<Setup> {
(**self).setup()
}
fn default_screen_index(&self) -> usize {
(**self).default_screen_index()
}
fn poll_for_event(&mut self) -> Result<Option<Event>> {
(**self).poll_for_event()
}
fn poll_for_reply_raw(&mut self, seq: u64) -> Result<Option<RawReply>> {
(**self).poll_for_reply_raw(seq)
}
}
impl<D: Display + ?Sized> Display for Box<D> {
fn send_request_raw(&mut self, req: RawRequest<'_, '_>) -> Result<u64> {
(**self).send_request_raw(req)
}
fn maximum_request_length(&mut self) -> Result<usize> {
(**self).maximum_request_length()
}
fn flush(&mut self) -> Result<()> {
(**self).flush()
}
fn generate_xid(&mut self) -> Result<u32> {
(**self).generate_xid()
}
fn synchronize(&mut self) -> Result<()> {
(**self).synchronize()
}
fn wait_for_event(&mut self) -> Result<Event> {
(**self).wait_for_event()
}
fn wait_for_reply_raw(&mut self, seq: u64) -> Result<RawReply> {
(**self).wait_for_reply_raw(seq)
}
fn check_for_error(&mut self, seq: u64) -> Result<()> {
(**self).check_for_error(seq)
}
}
cfg_async! {
impl<D: CanBeAsyncDisplay + ?Sized> CanBeAsyncDisplay for Box<D> {
fn format_request(
&mut self,
req: &mut RawRequest<'_, '_>,
ctx: &mut Context<'_>,
) -> Result<AsyncStatus<u64>> {
(**self).format_request(req, ctx)
}
fn try_flush(&mut self, ctx: &mut Context<'_>) -> Result<AsyncStatus<()>> {
(**self).try_flush(ctx)
}
fn try_generate_xid(&mut self, ctx: &mut Context<'_>) -> Result<AsyncStatus<u32>> {
(**self).try_generate_xid(ctx)
}
fn try_maximum_request_length(&mut self, ctx: &mut Context<'_>) -> Result<AsyncStatus<usize>> {
(**self).try_maximum_request_length(ctx)
}
fn try_send_request_raw(
&mut self,
req: &mut RawRequest<'_, '_>,
ctx: &mut Context<'_>,
) -> Result<AsyncStatus<()>> {
(**self).try_send_request_raw(req, ctx)
}
fn try_wait_for_event(&mut self, ctx: &mut Context<'_>) -> Result<AsyncStatus<Event>> {
(**self).try_wait_for_event(ctx)
}
fn try_wait_for_reply_raw(
&mut self,
seq: u64,
ctx: &mut Context<'_>,
) -> Result<AsyncStatus<RawReply>> {
(**self).try_wait_for_reply_raw(seq, ctx)
}
fn try_check_for_error(
&mut self,
seq: u64,
ctx: &mut Context<'_>,
) -> Result<AsyncStatus<()>> {
(**self).try_check_for_error(seq, ctx)
}
}
impl<D: AsyncDisplay + ?Sized> AsyncDisplay for Box<D> {
fn poll_for_interest(
&mut self,
interest: Interest,
callback: &mut dyn FnMut(&mut dyn AsyncDisplay, &mut Context< '_>) -> Result<()>,
ctx: &mut Context<'_>
) -> Poll<Result<()>> {
(**self).poll_for_interest(interest, callback, ctx)
}
}
}