x11rb/lib.rs
1//! X11 rust bindings.
2//!
3//! This library allows to interact with an X11 server from rust code. A connection to an X11
4//! server is represented by an implementation of the `Connection` trait.
5//!
6//! The client can interact with the server by sending requests. The server can answer requests and
7//! can also generate events.
8//!
9//! The examples that come with this library might be a good starting point for new users.
10//!
11//!
12//! # Getting started with X11
13//!
14//! X11 is a big protocol. I would claim that most of it is not actually that complicated, but it
15//! is still difficult to get into it. A good starting point might be some [libxcb
16//! tutorial](https://www.x.org/releases/X11R7.7/doc/libxcb/tutorial/index.html). This tutorial
17//! was adapted in this crate [as an
18//! example](https://github.com/psychon/x11rb/blob/master/x11rb/examples/tutorial.rs). A more in-depth
19//! look at the X11 protocol can be gained from the [protocol reference
20//! manual](https://www.x.org/releases/X11R7.6/doc/xproto/x11protocol.html), but this requires some
21//! existing basic understanding of X11. If you want to figure out what some specific request does,
22//! be sure to look it up in the specification!
23//!
24//! Most extensions can be understood by reading their specification. Most of them can be found
25//! [here](https://www.x.org/releases/current/doc/index.html#protocol). For example, [the
26//! specification of Composite
27//! 0.4](https://www.x.org/releases/X11R7.5/doc/compositeproto/compositeproto.txt) consists of
28//! about six pages of text.
29//!
30//! The notable exception is the X keyboard extension, which is documented in a [PDF file with 168
31//! pages](https://www.x.org/releases/current/doc/kbproto/xkbproto.pdf) which I am never going to
32//! read completely.
33//!
34//!
35//! # Getting started with x11rb
36//!
37//! Most code in this code is automatically generated from an XML description of the protocol. This
38//! is the same approach as taken by [libxcb](https://xcb.freedesktop.org/) (and in fact this uses
39//! the same XML description). This means that if you know your way around X11, most things should
40//! be obvious to you.
41//!
42//! For example, here is how to create a new window with x11rb:
43//! ```no_run
44//! use x11rb::connection::Connection;
45//! use x11rb::errors::ReplyOrIdError;
46//! use x11rb::protocol::xproto::*;
47//! use x11rb::COPY_DEPTH_FROM_PARENT;
48//!
49//! fn main() -> Result<(), Box<dyn std::error::Error>> {
50//! let (conn, screen_num) = x11rb::connect(None).unwrap();
51//! let screen = &conn.setup().roots[screen_num];
52//! let win_id = conn.generate_id()?;
53//! conn.create_window(
54//! COPY_DEPTH_FROM_PARENT,
55//! win_id,
56//! screen.root,
57//! 0,
58//! 0,
59//! 100,
60//! 100,
61//! 0,
62//! WindowClass::INPUT_OUTPUT,
63//! 0,
64//! &CreateWindowAux::new().background_pixel(screen.white_pixel),
65//! )?;
66//! conn.map_window(win_id)?;
67//! conn.flush();
68//! loop {
69//! println!("Event: {:?}", conn.wait_for_event()?);
70//! }
71//! }
72//! ```
73//! More examples can be found in the
74//! [examples](https://github.com/psychon/x11rb/tree/master/x11rb/examples) directory.
75//!
76//! ## Feature flags
77//!
78//! This crate uses [feature
79//! flags](https://doc.rust-lang.org/cargo/reference/manifest.html#the-features-section) to reduce
80//! the amount of compiled code. There are two kinds of feature flags available:
81//!
82//! * Feature flags for specific X11 extensions
83//! * Feature flags for additional functionality
84//!
85//! ### Feature flags for specific X11 extensions
86//!
87//! By default, only the core X11 protocol and X11 extensions that are needed internally are
88//! enabled. These are the `bigreq`, `ge` and `xc_misc` extensions. Further extensions need to be
89//! explicitly enabled via their feature flag:
90//!
91//! `composite`, `damage`, `dpms`, `dri2`, `dri3`, `glx`, `present`, `randr`, `record`, `render`,
92//! `res`, `screensaver`, `shape`, `shm`, `sync`, `xevie`, `xf86dri`, `xf86vidmode`, `xfixes`,
93//! `xinerama`, `xinput`, `xkb`, `xprint`, `xselinux`, `xtest`, `xv`, `xvmc`.
94//!
95//! If you want to take the "I do not want to think about this"-approach, you can enable the
96//! `all-extensions` feature to just enable, well, all extensions.
97//!
98//! ### Feature flags for additional functionality
99//!
100//! Additionally, the following flags exist:
101//! * `allow-unsafe-code`: Enable features that require `unsafe`. Without this flag,
102//! [`xcb_ffi::XCBConnection`] and some support code for it are unavailable.
103//! * `cursor`: Enable the code in [cursor] for loading cursor files.
104//! * `resource_manager`: Enable the code in [resource_manager] for loading and querying the
105//! X11 resource database.
106//! * `image`: Enable the code in [image] for working with pixel image data.
107//! * `dl-libxcb`: Enabling this feature will prevent from libxcb being linked to the
108//! resulting executable. Instead libxcb will be dynamically loaded at runtime.
109//! This feature adds the [`xcb_ffi::load_libxcb`] function, that allows to load
110//! libxcb and check for success or failure.
111//! * `extra-traits`: Enable some additional traits for generated code, like `Eq`, `Ord` and
112//! `Hash`. This is not needed by default and adds a large amount of code that bloats codegen
113//! time
114//! * `request-parsing`: Add the ability to parse X11 requests. Not normally needed.
115//! * `extra-traits`: Implement extra traits for X11 types. This improves the output of the `Debug`
116//! impl and adds `PartialEq`, `Eq`, `PartialOrd`, `Ord`, and `Hash` where possible.
117//!
118//! # Integrating x11rb with an Event Loop
119//!
120//! The [event_loop_integration](event_loop_integration/index.html) module contains some hints for
121//! integrating x11rb with an event loop as doc comments.
122
123// A list of lints that are only #![deny] and not the stronger #![forbid]. Each one has a comment
124// explaining why it gets the weaker treatment.
125#![deny(
126 // Contains unreachable_code and "?" generates an #[allow] for this
127 unused,
128 // #[derive] generates an #[allow] for this; not part of "unused"
129 unused_qualifications,
130 // Not everything in x11rb::protocol has doc comments
131 missing_docs,
132)]
133#![forbid(
134 missing_copy_implementations,
135 missing_debug_implementations,
136 rustdoc::private_doc_tests,
137 rust_2018_idioms,
138 //single_use_lifetimes,
139 trivial_casts,
140 trivial_numeric_casts,
141 unreachable_pub,
142 unused_must_use,
143 unused_results,
144 clippy::cast_lossless,
145 clippy::needless_pass_by_value,
146)]
147#![cfg_attr(not(feature = "allow-unsafe-code"), forbid(unsafe_code))]
148
149// Only contains documentation, but no "actual rust"
150pub mod event_loop_integration;
151
152/// Reexports of dependencies
153pub mod reexports {
154 pub use x11rb_protocol;
155}
156
157mod tracing;
158pub(crate) use crate::tracing::*;
159
160pub mod utils;
161#[cfg(feature = "allow-unsafe-code")]
162pub mod xcb_ffi;
163#[macro_use]
164pub mod x11_utils;
165pub mod connection;
166pub mod cookie;
167#[cfg(feature = "cursor")]
168pub mod cursor;
169pub mod errors;
170pub mod extension_manager;
171#[cfg(feature = "image")]
172pub mod image;
173pub mod properties;
174pub mod rust_connection;
175pub mod wrapper;
176#[rustfmt::skip]
177#[allow(missing_docs)]
178pub mod protocol;
179#[cfg(feature = "resource_manager")]
180pub mod resource_manager;
181#[cfg(test)]
182mod test;
183
184use errors::ConnectError;
185use protocol::xproto::{Keysym, Timestamp};
186use std::ffi::OsString;
187
188/// Establish a new connection to an X11 server.
189///
190/// This function is identical to
191/// [RustConnection::connect](crate::rust_connection::RustConnection::connect).
192pub fn connect(
193 dpy_name: Option<&str>,
194) -> Result<(rust_connection::RustConnection, usize), ConnectError> {
195 rust_connection::RustConnection::connect(dpy_name)
196}
197
198/// The universal null resource or null atom parameter value for many core X requests
199pub const NONE: u32 = 0;
200
201/// This constant can be used for many parameters in `create_window`
202pub const COPY_FROM_PARENT: u32 = 0;
203
204/// This constant can be used for the depth parameter in `create_window`. It indicates to use the
205/// parent window's depth.
206pub const COPY_DEPTH_FROM_PARENT: u8 = 0;
207
208/// This constant can be used for the class parameter in `create_window`. It indicates to use the
209/// parent window's class.
210pub const COPY_CLASS_FROM_PARENT: u16 = 0;
211
212/// This constant can be used in most request that take a timestamp argument
213pub const CURRENT_TIME: Timestamp = 0;
214
215/// This constant can be used to fill unused entries in `Keysym` tables
216pub const NO_SYMBOL: Keysym = 0;
217
218#[cfg(not(unix))]
219fn hostname() -> OsString {
220 gethostname::gethostname()
221}
222
223#[cfg(unix)]
224fn hostname() -> OsString {
225 use std::os::unix::ffi::OsStringExt;
226
227 OsString::from_vec(rustix::system::uname().nodename().to_bytes().to_vec())
228}