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
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
// MIT/Apache2 License

//! `breadx` is an implementation of the X Window System Protocol. In addition to providing the raw data
//! structures needed to create and parse requests, replies and events, it also provides convenient, functional
//! abstractions over the protocol.
//!
//! The design goals of `breadx` include speed, safety, and a reduction in complexity.
//!
//! * **Speed** - `breadx` takes advantage of modern languages features to reduce the time spent not sending
//!               protocol across the connection. First and foremost, `breadx` takes advantage of Rust's
//!               mutability system to ensure only one thread has access to the connection at once, negating
//!               the usual need for computationally expensive mutexes. In addition, `breadx` keeps as much
//!               data as possible on the stack, ensuring an increase in speed on modern computers.
//! * **Safety** - Rust's safety checking system is world-class in preventing bugs from propogating before
//!                they can even happen. `breadx` abides by these rules by including as little unsafe code as
//!                possible. The crate itself is `#![forbid(unsafe_code)]`, and its dependencies either use
//!                no unsafe code (`tinyvec`) or extensively check to ensure its unsafe code is correct
//!                (`bytemuck`).
//! * **Simple** - `breadx` tries to be as easy to understand as possible. Its API is well-documented, and
//!                it is accessible to both veteran X programmers and people who've never used it before.
//!
//! In addition, `breadx` implements Rust's new `async` system to allow it to be a part of a greater whole
//! when it comes to large, complex systems running on the async runtime. It also implements the standard
//! `log` logging facade for easy debugging.
//!
//! # Tutorials
//!
//! The official tutorial series begins [here](./tutorials/intro/index.html), and covers usage of `breadx`
//! and the X Window System Protocol.
//!
//! # Example
//!
//! This example opens a connection to the X server, then creates a basic window titled "Hello World!".
//!
//! ```rust,no_run
//! use breadx::{prelude::*, DisplayConnection, Event, WindowClass};
//! use std::{boxed::Box, error::Error};
//!
//! fn main() -> Result<(), Box<dyn Error>> {
//!     // open up the connection
//!     // note that the connection must be mutable
//!     let mut conn = DisplayConnection::create(None, None)?;
//!    
//!     // create a 640x400 window.
//!     let root = conn.default_screen().root;
//!     let window = conn
//!         .create_window(
//!             root, // parent
//!             WindowClass::CopyFromParent, // window class
//!             None, // depth (none means inherit from parent)
//!             None, // visual (none means "       "    "    )
//!             0, // x
//!             0, // y
//!             640, // width
//!             400, // height
//!             0, // border width
//!             Default::default() // additional properties
//!         )?;
//!
//!     // map the window and set its title
//!     window.map(&mut conn)?;
//!     window.set_title(&mut conn, "Hello World!")?;
//!
//!     // set up the exit protocol, this ensures the window exits when the "X"
//!     // button is clicked
//!     let wm_delete_window = conn
//!         .intern_atom_immediate("WM_DELETE_WINDOW".to_owned(), false)?;
//!     window.set_wm_protocols(&mut conn, &[wm_delete_window])?;
//!
//!     'evloop: loop {
//!         // grab an event from the connection
//!         let ev = conn.wait_for_event()?;
//!
//!         // if the event is telling us to close, then close
//!         if let Event::ClientMessage(cme) = ev {
//!             // check if the client message indicates the deletion protocol
//!             if cme.data.longs()[0] == wm_delete_window.xid {
//!                 break 'evloop;
//!             }
//!         }
//!     }
//!
//!     Ok(())
//! }
//! ```
//!
//! See the `examples` directory in the repository root for more example `breadx` programs.
//!
//! # Features
//!
//! * `std` - Enabled by default. This enables the use of the standard library, and enables
//!           `DisplayConnection` and `DisplayConnection::create`. This library can be used without
//!           the standard library; however, it requires the programmer to provide a connection, rather
//!           than building a connection itself.
//! * `async` - Enables the `_async` suffix family of functions. These functions and methods are similar
//!             to their blocking variants, but they use non-blocking variants of network calls. This uses
//!             the [`async-io`](https://crates.io/crates/async-io) crate to provide non-blocking calls.
//!             However, it nearly triples the size of this package's dependency tree.
//! * `image-support` - Adds the `from_image` method to the `Image` class, allowing one to convert a struct of
//!                     type `image::Image` from the [`image`](https://crates.io/crates/image) crate into this
//!                     image.
//! * `sync-display` - Enables the `SyncDisplay` struct, which allows usage of the display in thread-safe
//!                    contexts. However, it does require importing more dependencies (although some of these
//!                    dependencies overlap with those of the `async` feature).

#![deny(deprecated)]
#![forbid(unsafe_code)]
#![warn(missing_copy_implementations)]
#![warn(unused_qualifications)]
#![no_std]
#![warn(clippy::pedantic)]
#![allow(
    clippy::cast_possible_truncation, // used on purpose quite abit
    clippy::cast_possible_wrap,
    clippy::default_trait_access, // more readable, IMO
    clippy::map_err_ignore, // sometimes we just need to drop the error
    clippy::missing_errors_doc, // lots of "async redox" functions
    clippy::missing_panics_doc,
    clippy::module_name_repetitions, // doesn't matter IMO
    clippy::needless_for_each, // i like using for_each instead of for loops
    clippy::needless_pass_by_value,
    clippy::too_many_arguments, // we need this sometimes for compliance
    clippy::used_underscore_binding,
    clippy::ptr_as_ptr,
    unknown_lints,
)]

#[cfg(feature = "std")]
extern crate std;

extern crate alloc;
extern crate core;

mod auth_info;
pub mod auto;
pub mod client_message_data;
pub mod display;
pub mod error;
pub mod event;
pub mod extension;
pub mod image;
pub mod keyboard;
pub(crate) mod paramatizer;
pub(crate) mod util;
mod xid;

#[cfg(feature = "xkb")]
pub mod action;
#[cfg(feature = "xkb")]
pub mod behavior;

#[cfg(feature = "randr")]
pub mod notify_data;

#[cfg(feature = "render")]
pub mod render;

pub use crate::image::Image;
pub use auth_info::*;
pub use display::*;
pub use error::*;
pub use event::Event;
pub use extension::*;
pub use keyboard::*;
pub use xid::*;

pub type Fd = cty::c_int;

/// A request that can be sent as an instruction to the X server.
pub trait Request: auto::AsByteSequence {
    type Reply: auto::AsByteSequence;
    // Excerpt from the X Window System Protocol:
    //
    // Every request contains an 8-bit major opcode
    const OPCODE: u8;

    /// The name of the extension that this request belongs to.
    const EXTENSION: Option<&'static str>;

    /// Whether or not this request's reply includes file descriptors.
    const REPLY_EXPECTS_FDS: bool;
}

pub use auto::xproto::{
    Arc, Atom, ColormapAlloc, Drawable, EventMask, Gcontext, ImageFormat, Pixmap, Rectangle,
    Segment, Setup, VisualClass, Visualid, Visualtype, Window, WindowClass,
};

//#[path = "../tutorials/mod.rs"]
//pub mod tutorials;

#[doc(hidden)]
#[macro_export]
macro_rules! log_debug {
    ($($tt: tt)*) => {{
        #[cfg(debug_assertions)]
        log::debug!($($tt)*)
    }}
}

#[doc(hidden)]
#[macro_export]
macro_rules! log_trace {
    ($($tt: tt)*) => {{
        #[cfg(debug_assertions)]
        log::trace!($($tt)*)
    }}
}