1 | //! Backend API for wayland crates |
2 | //! |
3 | //! This crate provide low-level APIs for interacting with the Wayland protocol, |
4 | //! both client-side and server-side. |
5 | //! |
6 | //! Two possible backends are provided by this crate: the system backend ([`sys`] module) |
7 | //! which relies on the system-provided wayland libraries, and the rust backend ([`rs`] module) |
8 | //! which is an alternative rust implementation of the protocol. The rust backend is always |
9 | //! available, and the system backend is controlled by the `client_system` and `server_system` |
10 | //! cargo features. The `dlopen` cargo feature ensures that the system wayland |
11 | //! libraries are loaded dynamically at runtime, so that your executable does not link them and |
12 | //! can gracefully handle their absence (for example by falling back to X11). |
13 | //! |
14 | //! Additionally the default backends are reexported as toplevel `client` and `server` modules |
15 | //! in this crate. For both client and server, the default backend is the system one if the |
16 | //! associated cargo feature is enabled, and the rust one otherwise. |
17 | //! |
18 | //! Using these reexports is the recommended way to use the crate: |
19 | //! - If you don't need the `*_system` features, an other crate enabling them will not impact your code in |
20 | //! any way as both backends have the same API (the system backend only has more methods) |
21 | //! - If your code needs to do FFI, you just need to directly depend on `wayland-backend` with the |
22 | //! appropriate `*_system` feature enabled, and all the other crates in your dependency tree will |
23 | //! automatically use the `sys` backend. |
24 | //! |
25 | //! Both the `wayland-client` and `wayland-server` crates follow this principle, so everything will "Just |
26 | //! Work" when using them. |
27 | //! |
28 | //! ## Logging |
29 | //! |
30 | //! This crate can generate some runtime error message (notably when a protocol error occurs). By default |
31 | //! those messages are printed to stderr. If you activate the `log` cargo feature, they will instead be |
32 | //! piped through the `log` crate. |
33 | //! |
34 | //! ## raw-window-handle integration |
35 | //! |
36 | //! The `rwh_06` feature activates the [`HasDisplayHandle`][raw_window_handle::HasDisplayHandle] implementation |
37 | //! for the client module [`Backend`][client::Backend]. |
38 | //! |
39 | //! ### Deprecated raw-window-handle versions |
40 | //! |
41 | //! While raw-window-handle 0.5 is supported via the `raw-window-handle` feature, it is deprecated and will be removed in the future. |
42 | //! |
43 | //! Note that the `client_system` feature must also be enabled for the implementation to be activated. |
44 | |
45 | #![forbid (improper_ctypes)] |
46 | #![deny (unsafe_op_in_unsafe_fn)] |
47 | #![warn (missing_docs, missing_debug_implementations)] |
48 | // The api modules are imported two times each, this is not accidental |
49 | #![allow (clippy::duplicate_mod)] |
50 | #![cfg_attr (coverage, feature(coverage_attribute))] |
51 | // Doc feature labels can be tested locally by running RUSTDOCFLAGS="--cfg=docsrs" cargo +nightly doc -p <crate> |
52 | #![cfg_attr (docsrs, feature(doc_auto_cfg))] |
53 | |
54 | /// Reexport of the `smallvec` crate, which is part of `wayland-backend`'s public API. |
55 | pub extern crate smallvec; |
56 | |
57 | /// Helper macro for quickly making a [`Message`][crate::protocol::Message] |
58 | #[macro_export ] |
59 | macro_rules! message { |
60 | ($sender_id: expr, $opcode: expr, [$($args: expr),* $(,)?] $(,)?) => { |
61 | $crate::protocol::Message { |
62 | sender_id: $sender_id, |
63 | opcode: $opcode, |
64 | args: $crate::smallvec::smallvec![$($args),*], |
65 | } |
66 | } |
67 | } |
68 | |
69 | // internal imports for dispatching logging depending on the `log` feature |
70 | #[cfg (feature = "log" )] |
71 | #[allow (unused_imports)] |
72 | use log::{debug as log_debug, error as log_error, info as log_info, warn as log_warn}; |
73 | #[cfg (not(feature = "log" ))] |
74 | #[allow (unused_imports)] |
75 | use std::{ |
76 | eprintln as log_error, eprintln as log_warn, eprintln as log_info, eprintln as log_debug, |
77 | }; |
78 | |
79 | #[cfg (any(test, feature = "client_system" , feature = "server_system" ))] |
80 | pub mod sys; |
81 | |
82 | pub mod rs; |
83 | |
84 | #[cfg (not(feature = "client_system" ))] |
85 | pub use rs::client; |
86 | #[cfg (feature = "client_system" )] |
87 | pub use sys::client; |
88 | |
89 | #[cfg (not(feature = "server_system" ))] |
90 | pub use rs::server; |
91 | #[cfg (feature = "server_system" )] |
92 | pub use sys::server; |
93 | |
94 | #[cfg (test)] |
95 | mod test; |
96 | |
97 | mod core_interfaces; |
98 | mod debug; |
99 | pub mod protocol; |
100 | mod types; |
101 | |
102 | /* |
103 | * These trampoline functions need to always be here because the build script cannot |
104 | * conditionally build their C counterparts on whether the crate is tested or not... |
105 | * They'll be optimized out when unused. |
106 | */ |
107 | |
108 | #[cfg (feature = "log" )] |
109 | #[no_mangle ] |
110 | extern "C" fn wl_log_rust_logger_client(msg: *const std::os::raw::c_char) { |
111 | let cstr = unsafe { std::ffi::CStr::from_ptr(msg) }; |
112 | let text = cstr.to_string_lossy(); |
113 | log::error!("{}" , text); |
114 | } |
115 | |
116 | #[cfg (feature = "log" )] |
117 | #[no_mangle ] |
118 | extern "C" fn wl_log_rust_logger_server(msg: *const std::os::raw::c_char) { |
119 | let cstr = unsafe { std::ffi::CStr::from_ptr(msg) }; |
120 | let text = cstr.to_string_lossy(); |
121 | log::error!("{}" , text); |
122 | } |
123 | |