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
//! This crate contains bindings for libxcb, libxcb-xinput, etc.
//! Symbols are loaded dynamically at runtime; linking at compile time is not supported.
//!
//! # Features
//!
//! Only bindings for libxcb are available by default.
//! Enable the appropriately named features to enable bindings for libxcb-xinput etc.
//!
//! # Handling Missing Symbols
//!
//! Symbols are loaded lazily when they are accessed.
//! If this fails, we panic.
//! Enable the `has_symbol` feature to handle missing symbols more gracefully.
//! This enables methods of the form `has_X` that return whether a symbol can be loaded.
//!
//! ```
//! # unsafe {
//! let lib = xcb_dl::Xcb::load().unwrap();
//! if !lib.has_xcb_total_written() {
//!     eprintln!("Cannot monitor total number of bytes written.");
//! }
//! # }
//! ```
//!
//! # Constructing Structs
//!
//! Future versions of this crate might add new fields to structs or remove padding fields.
//! This is not considered a breaking change.
//! Construct objects using `Default::default()` to ensure that your code remains valid:
//!
//! ```
//! let format = xcb_dl::ffi::xcb_format_t {
//!     depth: 0,
//!     bits_per_pixel: 0,
//!     scanline_pad: 0,
//!     ..Default::default()
//! };
//! ```
//!
//! # Semantic Documentation
//!
//! This crate contains almost no semantic documentation.
//! Documentation of the X core protocol and extensions is available at [freedesktop] and [x.org].
//! Documentation of the libxcb functions that are not auto-generated from the protocols is available
//!     in the [libxcb] repository. Check `src/xcb.h` and `src/xcbext.h`.
//!
//! [freedesktop]:  https://gitlab.freedesktop.org/xorg/proto/xorgproto
//! [x.org]: https://www.x.org/releases/X11R7.7/doc/
//! [libxcb]: https://gitlab.freedesktop.org/xorg/lib/libxcb
//!
//! # libxcb Architecture
//!
//! This sections provides a brief overview of the auto-generated functions in libxcb.
//! Consult the [libxcb][libxcb2] documentation for more details.
//!
//! [libxcb2]: https://xcb.freedesktop.org/
//!
//! The terminology in this section is not the official libxcb terminology.
//!
//! libxcb sends **requests** to and receives **messages** from the X server.
//! There are three types of messages:
//!
//! - **value replies**: A success message sent in response to a request.
//! - **error replies**: An error sent in response to a request.
//! - **events**: An event such as a key press.
//!
//! The code that sends a request can specify that replies should automatically be discarded by calling
//!     `xcb_discard_reply`.
//!
//! libxcb maintains two queues for incoming messages:
//!
//! - the **event queue**: Contains messages that can be retrieved via `xcb_poll_for_event` etc.
//! - the **reply queue**: Contains messages that can only be retrieved by the code that sent the request.
//!
//! Events are always placed in the event queue.
//!
//! Value replies are placed in the reply queue unless they are being discarded.
//!
//! Each request has two variants:
//!
//! - **checked**: Error replies are placed in the reply queue unless they are being discarded.
//! - **unchecked**: Error replies are placed in the event queue unless they are being discarded.
//!
//! There are two types of requests:
//!
//! - **void requests**: These do not generate value replies but can generate error replies.
//! - **value requests**: These can generate either value replies or error replies.
//!
//! The default variant of void requests is unchecked.
//! For each such request libxcb provides a function with the suffix `_checked` that uses the checked variant.
//!
//! The default variant of value requests is checked.
//! For each such request libxcb provides a function with the suffix `_unchecked` that uses the unchecked variant.
//!
//! Messages placed in the reply queue must be retrieved by the user.
//! Otherwise they will never be discarded.
//!
//! For void requests, error replies can be retrieved by calling `xcb_request_check`.
//!
//! For every value request libxcb provides a function with the suffix `_reply` that can
//!     be used to retrieve the value or error reply.
//!
//! ## Memory Management
//!
//! libxcb never takes ownership of memory passed to it.
//!
//! The functions that return messages pass ownership of the message to the caller.
//! These messages can be freed with `libc::free`.
//!
//! ## Non-homogeneous Requests
//!
//! Some requests contain variably sized data and possibly non-homogeneous arrays.
//! To simplify creating such requests, libxcb provides auxiliary functions with the suffix `_aux`.
//! These functions take fixed-sized arguments and internally create a serialized request.
//!
//! ## Non-homogeneous Replies
//!
//! Some replies contain variably sized data and possibly non-homogeneous arrays.
//!
//! The data structures of libxcb do not contain fields for this data.
//! Instead, libxcb provides accessor functions to retrieve pointers to these fields.
//!
//! If the fields are non-homogeneous arrays, these accessor functions return iterators.
//! The pointer in these iterators can be advanced by calling an appropriately named `_next` function.
//!
//! If the fields are homogeneous arrays, libxcb provides `_length` functions that return the number
//!     of elements in the array.
//!
//! In some cases these accessor functions return `*mut c_void`.
//! In these cases libxcb usually provides an `_unpack` function that deserializes the data into
//!     a struct.
#![allow(
    non_camel_case_types,
    non_snake_case,
    clippy::missing_safety_doc,
    clippy::type_complexity,
    clippy::too_many_arguments
)]

pub use libs::*;

#[macro_use]
mod macros;
mod headers;
mod lazy;
mod libs;

pub mod ffi {
    pub use crate::headers::*;
    use std::fmt::{Debug, Formatter};

    impl Debug for xcb_client_message_data_t {
        fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
            unsafe {
                f.debug_struct("xcb_client_message_data_t")
                    .field("data8", &self.data8)
                    .finish()
            }
        }
    }

    #[cfg(feature = "xcb_xinput_types")]
    impl Debug for xcb_input_event_for_send_t {
        fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
            unsafe {
                f.debug_struct("xcb_input_event_for_send_t")
                    .field("response_type", &self.event_header.response_type)
                    .finish_non_exhaustive()
            }
        }
    }

    #[cfg(feature = "xcb_xkb_types")]
    impl Debug for xcb_xkb_action_t {
        fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
            unsafe {
                f.debug_struct("xcb_xkb_action_t")
                    .field("type", &self.type_)
                    .finish_non_exhaustive()
            }
        }
    }

    #[cfg(feature = "xcb_xkb_types")]
    impl Debug for xcb_xkb_behavior_t {
        fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
            unsafe {
                f.debug_struct("xcb_xkb_behavior_t")
                    .field("type", &self.type_)
                    .finish_non_exhaustive()
            }
        }
    }

    #[cfg(feature = "xcb_randr_types")]
    impl Debug for xcb_randr_notify_data_t {
        fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
            f.debug_struct("xcb_randr_notify_data_t")
                .finish_non_exhaustive()
        }
    }
}