Skip to main content

smithay_client_toolkit/shm/
mod.rs

1pub mod multi;
2pub mod raw;
3pub mod slot;
4
5use std::io;
6
7use wayland_client::{
8    globals::{BindError, GlobalList},
9    protocol::wl_shm,
10    Connection, Dispatch, QueueHandle, WEnum,
11};
12
13use crate::{
14    dispatch2::Dispatch2,
15    error::GlobalError,
16    globals::{GlobalData, ProvidesBoundGlobal},
17};
18
19pub trait ShmHandler {
20    fn shm_state(&mut self) -> &mut Shm;
21}
22
23#[derive(Debug)]
24pub struct Shm {
25    wl_shm: wl_shm::WlShm,
26    formats: Vec<wl_shm::Format>,
27}
28
29impl From<wl_shm::WlShm> for Shm {
30    fn from(wl_shm: wl_shm::WlShm) -> Self {
31        Self { wl_shm, formats: Vec::new() }
32    }
33}
34
35impl Shm {
36    pub fn bind<State>(globals: &GlobalList, qh: &QueueHandle<State>) -> Result<Shm, BindError>
37    where
38        State: Dispatch<wl_shm::WlShm, GlobalData, State> + ShmHandler + 'static,
39    {
40        let wl_shm = globals.bind(qh, 1..=1, GlobalData)?;
41        // Compositors must advertise Argb8888 and Xrgb8888, so let's reserve space for those formats.
42        Ok(Shm { wl_shm, formats: Vec::with_capacity(2) })
43    }
44
45    pub fn wl_shm(&self) -> &wl_shm::WlShm {
46        &self.wl_shm
47    }
48
49    /// Returns the formats supported in memory pools.
50    pub fn formats(&self) -> &[wl_shm::Format] {
51        &self.formats[..]
52    }
53}
54
55impl ProvidesBoundGlobal<wl_shm::WlShm, 1> for Shm {
56    fn bound_global(&self) -> Result<wl_shm::WlShm, GlobalError> {
57        Ok(self.wl_shm.clone())
58    }
59}
60
61/// An error that may occur when creating a pool.
62#[derive(Debug, thiserror::Error)]
63pub enum CreatePoolError {
64    /// The wl_shm global is not bound.
65    #[error(transparent)]
66    Global(#[from] GlobalError),
67
68    /// Error while allocating the shared memory.
69    #[error(transparent)]
70    Create(#[from] io::Error),
71}
72
73impl<D> Dispatch2<wl_shm::WlShm, D> for GlobalData
74where
75    D: ShmHandler,
76{
77    fn event(
78        &self,
79        state: &mut D,
80        _proxy: &wl_shm::WlShm,
81        event: wl_shm::Event,
82        _: &Connection,
83        _: &QueueHandle<D>,
84    ) {
85        match event {
86            wl_shm::Event::Format { format } => {
87                match format {
88                    WEnum::Value(format) => {
89                        state.shm_state().formats.push(format);
90                        log::debug!(target: "sctk", "supported wl_shm format {:?}", format);
91                    }
92
93                    // Ignore formats we don't know about.
94                    WEnum::Unknown(raw) => {
95                        log::debug!(target: "sctk", "Unknown supported wl_shm format {:x}", raw);
96                    }
97                };
98            }
99
100            _ => unreachable!(),
101        }
102    }
103}