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 | |