| 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" |
| 150 | pub mod event_loop_integration; |
| 151 | |
| 152 | /// Reexports of dependencies |
| 153 | pub mod reexports { |
| 154 | pub use x11rb_protocol; |
| 155 | } |
| 156 | |
| 157 | mod tracing; |
| 158 | pub(crate) use crate::tracing::*; |
| 159 | |
| 160 | pub mod utils; |
| 161 | #[cfg (feature = "allow-unsafe-code" )] |
| 162 | pub mod xcb_ffi; |
| 163 | #[macro_use ] |
| 164 | pub mod x11_utils; |
| 165 | pub mod connection; |
| 166 | pub mod cookie; |
| 167 | #[cfg (feature = "cursor" )] |
| 168 | pub mod cursor; |
| 169 | pub mod errors; |
| 170 | pub mod extension_manager; |
| 171 | #[cfg (feature = "image" )] |
| 172 | pub mod image; |
| 173 | pub mod properties; |
| 174 | pub mod rust_connection; |
| 175 | pub mod wrapper; |
| 176 | #[rustfmt::skip] |
| 177 | #[allow (missing_docs)] |
| 178 | pub mod protocol; |
| 179 | #[cfg (feature = "resource_manager" )] |
| 180 | pub mod resource_manager; |
| 181 | #[cfg (test)] |
| 182 | mod test; |
| 183 | |
| 184 | use errors::ConnectError; |
| 185 | use protocol::xproto::{Keysym, Timestamp}; |
| 186 | use 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). |
| 192 | pub 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 |
| 199 | pub const NONE: u32 = 0; |
| 200 | |
| 201 | /// This constant can be used for many parameters in `create_window` |
| 202 | pub 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. |
| 206 | pub 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. |
| 210 | pub const COPY_CLASS_FROM_PARENT: u16 = 0; |
| 211 | |
| 212 | /// This constant can be used in most request that take a timestamp argument |
| 213 | pub const CURRENT_TIME: Timestamp = 0; |
| 214 | |
| 215 | /// This constant can be used to fill unused entries in `Keysym` tables |
| 216 | pub const NO_SYMBOL: Keysym = 0; |
| 217 | |
| 218 | #[cfg (not(unix))] |
| 219 | fn hostname() -> OsString { |
| 220 | gethostname::gethostname() |
| 221 | } |
| 222 | |
| 223 | #[cfg (unix)] |
| 224 | fn hostname() -> OsString { |
| 225 | use std::os::unix::ffi::OsStringExt; |
| 226 | |
| 227 | OsString::from_vec(rustix::system::uname().nodename().to_bytes().to_vec()) |
| 228 | } |
| 229 | |