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, Proxy, 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..=3, 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 Drop for Shm {
56    fn drop(&mut self) {
57        if self.wl_shm.version() > wl_shm::REQ_RELEASE_SINCE {
58            self.wl_shm.release();
59        }
60    }
61}
62
63impl ProvidesBoundGlobal<wl_shm::WlShm, 1> for Shm {
64    fn bound_global(&self) -> Result<wl_shm::WlShm, GlobalError> {
65        Ok(self.wl_shm.clone())
66    }
67}
68
69/// An error that may occur when creating a pool.
70#[derive(Debug, thiserror::Error)]
71pub enum CreatePoolError {
72    /// The wl_shm global is not bound.
73    #[error(transparent)]
74    Global(#[from] GlobalError),
75
76    /// Error while allocating the shared memory.
77    #[error(transparent)]
78    Create(#[from] io::Error),
79}
80
81impl<D> Dispatch2<wl_shm::WlShm, D> for GlobalData
82where
83    D: ShmHandler,
84{
85    fn event(
86        &self,
87        state: &mut D,
88        _proxy: &wl_shm::WlShm,
89        event: wl_shm::Event,
90        _: &Connection,
91        _: &QueueHandle<D>,
92    ) {
93        match event {
94            wl_shm::Event::Format { format } => {
95                match format {
96                    WEnum::Value(format) => {
97                        state.shm_state().formats.push(format);
98                        log::debug!(target: "sctk", "supported wl_shm format {:?}", format);
99                    }
100
101                    // Ignore formats we don't know about.
102                    WEnum::Unknown(raw) => {
103                        log::debug!(target: "sctk", "Unknown supported wl_shm format {:x}", raw);
104                    }
105                };
106            }
107
108            _ => unreachable!(),
109        }
110    }
111}