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 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324
//! Server-side Wayland connector //! //! # Overview //! //! Setting up the listening socket is done by the `create_display` //! function, providing you a `Display` object and an `EventLoop`. //! //! On the event loop, you'll be able to register the globals //! you want to advertize, as well as handlers for all ressources //! created by the clients. //! //! You then integrate the wayland event loop in your main event //! loop to run your compositor. //! //! # Implementation and event loop //! //! This crate mirrors the callback-oriented design of the //! Wayland C library by using implementation structs: each wayland //! type defines an `Implementation` struct in its module, with //! one function field for each possible event this object can receive. //! //! When registering an object on an event loop, you need to provide an //! implementation for this object. You can also provide some //! "implementation data": a value that will be provided as second //! argument to all the callback methods of your implementation. //! //! A typical use of implementation data is to store here one or more //! state tokens to access some part of the shared state from your //! callback. //! //! ## Example of implementation //! //! You can register your wayland objects to an event queue: //! //! ```ignore //! event_loop.register(&my_object, implementation, impl_data); //! ``` //! //! A given wayland object can only be registered to an event //! loop at a given time, re-registering it will overwrite //! the previous configuration. //! //! Objects can be registered to event loop using the `&EventLoopHandle` //! argument, available from withing an event callback. //! //! ## Globals definition //! //! Some wayland objects are special and can be directly created by the //! clients from their registry. To handle them your must declare //! which globals you want to make available to your clients, like this: //! //! ```ignore //! event_loop.register_global(version, callback, idata); //! ``` //! //! Where `callback` is a function or non-capturing closure, provided as //! an implementation for when this global is instanciated by a client. //! See the method documentation for details. //! //! ## Event loop integration //! //! Once the setup phase is done, you can integrate the //! event loop in the main event loop of your program. //! //! Either all you need is for it to run indefinitely (external //! events are checked in an other thread?): //! //! ```ignore //! event_loop.run(); //! ``` //! //! Or you can integrate it with more control: //! //! ```ignore //! loop { //! // flush events to client sockets //! display.flush_clients(); //! // receive request from clients and dispatch them //! // blocking if no request is pending for at most //! // 10ms //! event_loop.dispatch(Some(10)).unwrap(); //! // then you can check events from other sources if //! // you need to //! } //! ``` //! //! # Protocols integration //! //! This crate provides the basic primitives as well as the //! core wayland protocol (in the `protocol` module), but //! other protocols can be integrated from XML descriptions. //! //! The the crate `wayland_scanner` and its documentation for //! details about how to do so. #![warn(missing_docs)] #[macro_use] extern crate bitflags; extern crate libc; extern crate nix; extern crate token_store; #[macro_use] extern crate wayland_sys; pub use client::Client; pub use display::{create_display, Display}; pub use event_loop::{resource_is_registered, EventLoop, EventLoopHandle, Global, GlobalCallback, RegisterStatus, State, StateProxy, StateToken}; pub use generated::interfaces as protocol_interfaces; pub use generated::server as protocol; use wayland_sys::common::{wl_argument, wl_interface}; use wayland_sys::server::*; mod client; mod display; mod event_loop; mod event_sources; pub mod sources { //! Secondary event sources // This module contains the types & traits to work with // different kind of event sources that can be registered to and // event loop, other than the wayland protocol sockets. pub use event_sources::{FdEventSource, FdEventSourceImpl, FdInterest}; pub use event_sources::{IdleEventSource, IdleEventSourceImpl}; pub use event_sources::{SignalEventSource, SignalEventSourceImpl}; pub use event_sources::{TimerEventSource, TimerEventSourceImpl}; } /// Common routines for wayland resource objects. /// /// All wayland objects automatically implement this trait /// as generated by the scanner. /// /// It is mostly used for internal use by the library, and you /// should only need these methods for interfacing with C library /// working on wayland objects. pub unsafe trait Resource { /// Pointer to the underlying wayland proxy object fn ptr(&self) -> *mut wl_resource; /// Create an instance from a wayland pointer /// /// The pointer must refer to a valid wayland resource /// of the appropriate interface, but that have not yet /// been seen by the library. /// /// The library will take control of the object (notably /// overwrite its user_data). unsafe fn from_ptr_new(*mut wl_resource) -> Self; /// Create an instance from a wayland pointer /// /// The pointer must refer to a valid wayland resource /// of the appropriate interface. The library will detect if the /// resource is already managed by it or not. If it is not, this /// resource will be considered as "unmanaged", and should then /// be handled with care. unsafe fn from_ptr_initialized(*mut wl_resource) -> Self; /// Pointer to the interface representation fn interface_ptr() -> *const wl_interface; /// Internal wayland name of this interface fn interface_name() -> &'static str; /// Max version of this interface supported fn supported_version() -> u32; /// Current version of the interface this resource is instantiated with fn version(&self) -> i32; /// Check if the resource behind this handle is actually still alive fn status(&self) -> Liveness; /// Check of two handles are actually the same wayland object /// /// Returns `false` if any of the objects has already been destroyed fn equals(&self, &Self) -> bool; /// Set a pointer associated as user data on this resource /// /// All handles to the same wayland object share the same user data pointer. /// /// The get/set operations are atomic, no more guarantee is given. If you need /// to synchronise access to this data, it is your responsibility to add a Mutex /// or any other similar mechanism. fn set_user_data(&self, ptr: *mut ()); /// Get the pointer associated as user data on this resource /// /// All handles to the same wayland object share the same user data pointer. /// /// See `set_user_data` for synchronisation guarantee. fn get_user_data(&self) -> *mut (); /// Posts a protocol error to this resource /// /// The error code can be obtained from the various `Error` enums of the protocols. /// /// An error is fatal to the client that caused it. fn post_error(&self, error_code: u32, msg: String) { // If `str` contains an interior null, the actuall transmitted message will // be truncated at this point. unsafe { let cstring = ::std::ffi::CString::from_vec_unchecked(msg.into()); ffi_dispatch!( WAYLAND_SERVER_HANDLE, wl_resource_post_error, self.ptr(), error_code, cstring.as_ptr() ) } } /// Clone this resource handle /// /// Will only succeed if the resource is managed by this library and /// is still alive. fn clone(&self) -> Option<Self> where Self: Sized, { if self.status() == Liveness::Alive { Some(unsafe { self.clone_unchecked() }) } else { None } } /// Unsafely clone this resource handle /// /// This function is unsafe because if the resource is unmanaged, the lib /// has no knowledge of its lifetime, and cannot ensure that the new handle /// will not outlive the object. unsafe fn clone_unchecked(&self) -> Self; /// Checks wether this resource and the other are from the same client /// /// Returns `true` if both are alive and belong to the same client, `false` /// otherwise. fn same_client_as<R: Resource>(&self, other: &R) -> bool { // comparing client pointers for equality is only meaningfull // if resources are alive if !(self.status() == Liveness::Alive && other.status() == Liveness::Alive) { false } else { let my_client = unsafe { ffi_dispatch!(WAYLAND_SERVER_HANDLE, wl_resource_get_client, self.ptr()) }; let other_client = unsafe { ffi_dispatch!(WAYLAND_SERVER_HANDLE, wl_resource_get_client, other.ptr()) }; my_client == other_client } } } /// Common trait for wayland objects that can be registered to an EventQueue pub unsafe trait Implementable<ID: 'static>: Resource { /// The type containing the implementation for the event callbacks type Implementation: PartialEq + Copy + 'static; #[doc(hidden)] unsafe fn __dispatch_msg(&self, client: &Client, opcode: u32, args: *const wl_argument) -> Result<(), ()>; } /// Possible outcome of the call of a event on a resource #[derive(Debug)] pub enum EventResult<T> { /// Message has been buffered and will be sent to client Sent(T), /// This resource is already destroyed, request has been ignored Destroyed, } impl<T> EventResult<T> { /// Assert that result is successfull and extract the value. /// /// Panics with provided error message if the result was `Destroyed`. pub fn expect(self, error: &str) -> T { match self { EventResult::Sent(v) => v, EventResult::Destroyed => panic!("{}", error), } } } /// Represents the state of liveness of a wayland object #[derive(Copy, Clone, PartialEq, Eq)] pub enum Liveness { /// This object is alive and events can be sent to it Alive, /// This object is dead, sending it events will do nothing and /// return and error. Dead, /// This object is not managed by `wayland-server`, you can send it events /// but this might crash the program if it was actually dead. Unmanaged, } mod generated { #![allow(dead_code, non_camel_case_types, unused_unsafe, unused_variables)] #![allow(non_upper_case_globals, non_snake_case, unused_imports)] #![allow(missing_docs)] pub mod interfaces { //! Interfaces for the core protocol // You might need them for the bindings generated for protocol extensions include!(concat!(env!("OUT_DIR"), "/wayland_interfaces.rs")); } pub mod server { //! The wayland core protocol // This module contains all objects of the core wayland protocol. // // It has been generated from the `wayland.xml` protocol file // using `wayland_scanner`. // Imports that need to be available to submodules // but should not be in public API. // Will be fixable with pub(restricted). #[doc(hidden)] pub use super::interfaces; #[doc(hidden)] pub use {Client, EventLoopHandle, EventResult, Implementable, Liveness, Resource}; include!(concat!(env!("OUT_DIR"), "/wayland_api.rs")); } } pub mod sys { //! Reexports of types and objects from wayland-sys pub use wayland_sys::common::*; pub use wayland_sys::server::*; }