wayland-client 0.14.0

Bindings to the standard C implementation of the wayland protocol, client side.
Documentation
//! Client-side Wayland connector
//!
//! # Overview
//!
//! Connection to the Wayland compositor is achieved by
//! the `default_connect()` function, which provides you
//! with a `WlDisplay` and an `EventQueue`.
//!
//! From the display, you'll retrieve the registry, from
//! which you can instantiate the globals you need. This
//! step being really similar in most cases, this crate
//! contains an utility struct `EnvHandler` which can do
//! this job for you. See its documentation for details.
//!
//! You then register your handlers for events to the
//! event queue, and integrate it in your main event loop.
//!
//! # Implementations and event queues
//!
//! 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 queue, 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_queue.register(&my_object, implementation, impl_data);
//! ```
//!
//! A given wayland object can only be registered to a event
//! queue at a given time, re-registering it will overwrite
//! the previous configuration.
//!
//! Objects can be registered to event queues using the `&EventQueueHandle`
//! argument, available from withing an event callback.
//!
//! ## Event loop integration
//!
//! Once this setup is done, you can integrate the event queue
//! to the main event loop of your program:
//!
//! ```ignore
//! loop {
//!     // flush events to the server
//!     display.flush().unwrap();
//!     // receive events from the server and dispatch them
//!     // to handlers (might block)
//!     event_queue.dispatch().unwrap();
//! }
//! ```
//!
//! For more precise control of the flow of the event queue
//! (and importantly non-blocking options), see `EventQueue`
//! documentation.
//!
//! # 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 token_store;
#[macro_use]
extern crate wayland_sys;

pub use generated::client as protocol;
pub use generated::interfaces as protocol_interfaces;
use wayland_sys::client::wl_proxy;
use wayland_sys::common::{wl_argument, wl_interface};

mod display;
mod event_queue;
mod env;

#[cfg(feature = "egl")]
pub mod egl;

#[cfg(feature = "cursor")]
pub mod cursor;

pub use display::{connect_to, default_connect, ConnectError, FatalError};
pub use env::{EnvHandler, EnvHandlerInner, EnvNotify};
pub use event_queue::{EventQueue, EventQueueHandle, ReadEventsGuard, RegisterStatus, State, StateProxy,
                      StateToken};

/// Common routines for wayland proxy 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 Proxy {
    /// Pointer to the underlying wayland proxy object
    fn ptr(&self) -> *mut wl_proxy;
    /// Create an instance from a wayland pointer
    ///
    /// The pointer must refer to a valid wayland proxy
    /// 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_proxy) -> Self;
    /// Create an instance from a wayland pointer
    ///
    /// The pointer must refer to a valid wayland proxy
    /// of the appropriate interface. The library will detect if the
    /// proxy is already managed by it or not. If it is not, this
    /// proxy will be considered as "unmanaged", and should then
    /// be handled with care.
    unsafe fn from_ptr_initialized(*mut wl_proxy) -> 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 proxy is instantiated with
    fn version(&self) -> u32;
    /// Check if the proxy 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 proxy
    ///
    /// All proxies 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.
    ///
    /// If this proxy is not managed by wayland-client, this does nothing.
    fn set_user_data(&self, ptr: *mut ());
    /// Get the pointer associated as user data on this proxy
    ///
    /// All proxies to the same wayland object share the same user data pointer.
    ///
    /// See `set_user_data` for synchronisation guarantee.
    ///
    /// If this proxy is not managed by wayland-client, this returns a null pointer.
    fn get_user_data(&self) -> *mut ();
    /// Clone this proxy handle
    ///
    /// Will only succeed if the proxy 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 proxy handle
    ///
    /// This function is unsafe because if the proxy 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
    where
        Self: Sized;
}

/// Common trait for wayland objects that can be registered to an EventQueue
pub unsafe trait Implementable<ID: 'static>: Proxy {
    /// The type containing the implementation for the event callbacks
    type Implementation: PartialEq + Copy + 'static;
    #[doc(hidden)]
    unsafe fn __dispatch_msg(&self, opcode: u32, args: *const wl_argument) -> Result<(), ()>;
}

/// Possible outcome of the call of a request on a proxy
#[derive(Debug)]
pub enum RequestResult<T> {
    /// Message has been buffered and will be sent to server
    Sent(T),
    /// This proxy is already destroyed, request has been ignored
    Destroyed,
}

impl<T> RequestResult<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 {
            RequestResult::Sent(v) => v,
            RequestResult::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 its requests can be called
    Alive,
    /// This object is dead, calling its requests will do nothing and
    /// return and error.
    Dead,
    /// This object is not managed by `wayland-client`, you can call its methods
    /// 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 client {
        //! 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`.

        pub(crate) use super::interfaces;
        pub(crate) use {Implementable, Liveness, Proxy, RequestResult};
        pub(crate) use event_queue::EventQueueHandle;
        include!(concat!(env!("OUT_DIR"), "/wayland_api.rs"));
    }
}

pub mod sys {
    //! Reexports of types and objects from wayland-sys

    pub use wayland_sys::client::*;
    pub use wayland_sys::common::*;
}