Module shm

Module shm 

Source
Available on crate feature wayland_frontend only.
Expand description

SHM handling helpers

This module provides helpers to handle SHM-based buffers from wayland clients.

SHM (Shared Memory) is the most basic way wayland clients can send content to the compositor: by sending a file descriptor to some (likely RAM-backed) storage containing the actual data. This helper handles for you most of the logic for handling these file descriptor and accessing their contents as simple &[u8] slices.

This module is heavily inspired from the similar helpers of the wayland C libraries.

To use it, first add a ShmGlobal to your display, specifying the formats you want to support (ARGB8888 and XRGB8888 are always considered as supported, as specified by the wayland protocol).

extern crate wayland_server;
extern crate smithay;

use smithay::wayland::buffer::BufferHandler;
use smithay::wayland::shm::{ShmState, ShmHandler};
use smithay::delegate_shm;
use wayland_server::protocol::wl_shm::Format;

// Create the ShmState.
// Here, we specify that Yuyv and C8 format are supported
// additionally to the standard Argb8888 and Xrgb8888.
let state = ShmState::new::<State>(
    &display.handle(),
    vec![Format::Yuyv, Format::C8],
);

// insert the shmstate into your compositor state.
// ..

// provide the necessary trait implementations
impl BufferHandler for State {
    fn buffer_destroyed(&mut self, buffer: &wayland_server::protocol::wl_buffer::WlBuffer) {
        // All renderers can handle buffer destruction at this point.
        // Some parts of window management may also use this function.
    }
}
impl ShmHandler for State {
    fn shm_state(&self) -> &ShmState {
        &self.shm_state
    }
}
delegate_shm!(State);

Then, when you have a WlBuffer and need to retrieve its contents, use the with_buffer_contents function to do it:

use smithay::wayland::shm::{with_buffer_contents, BufferData, BufferAccessError};

let content = with_buffer_contents(&buffer,
    |ptr: *const u8, len: usize, buffer_metadata: BufferData| {
        // do something to extract the contents of the buffer
    }
);

match content {
    Ok(something) =>  {
        /* `something` is the value you returned from the closure */
    },
    Err(BufferAccessError::NotManaged) => {
        /* This buffer is not managed by the SHM global, but by something else */
    },
    Err(BufferAccessError::BadMap) => {
        /* The client supplied invalid content specification for this buffer,
           and was killed.
         */
    },
    Err(BufferAccessError::NotReadable) => {
        /* The client has not allowed reads to this buffer */
    },
    Err(BufferAccessError::NotWritable) => unreachable!("cannot be triggered by with_buffer_contents"),
}

Note

This handler makes itself safe regarding the client providing a wrong size for the memory pool by using a SIGBUS handler.

If you are already using an handler for this signal, you probably don’t want to use this handler.

Structs§

BufferData
Details of the contents of a buffer relative to its pool
ShmBufferUserData
User data of shm WlBuffer
ShmPoolUserData
User data of WlShmPool
ShmState
State of SHM module

Enums§

BufferAccessError
Error that can occur when accessing an SHM buffer

Traits§

ShmHandler
Shm global handler

Functions§

fourcc_to_shm_format
Convert from a Fourcc format to a wl_shm format
shm_format_to_fourcc
Convert from a wl_shm format to a Fourcc format
with_buffer_contents
Call given closure with the contents of the given buffer
with_buffer_contents_mut
Call given closure with the contents of the given buffer for mutable access
wl_bytes_per_pixel
Returns the bpp of the format