wl_proxy/protocols/wayland/
wl_compositor.rs

1//! the compositor singleton
2//!
3//! A compositor.  This object is a singleton global.  The
4//! compositor is in charge of combining the contents of multiple
5//! surfaces into one displayable output.
6
7use crate::protocol_helpers::prelude::*;
8use super::super::all_types::*;
9
10/// A wl_compositor object.
11///
12/// See the documentation of [the module][self] for the interface description.
13pub struct WlCompositor {
14    core: ObjectCore,
15    handler: HandlerHolder<dyn WlCompositorHandler>,
16}
17
18struct DefaultHandler;
19
20impl WlCompositorHandler for DefaultHandler { }
21
22impl ConcreteObject for WlCompositor {
23    const XML_VERSION: u32 = 6;
24    const INTERFACE: ObjectInterface = ObjectInterface::WlCompositor;
25    const INTERFACE_NAME: &str = "wl_compositor";
26}
27
28impl WlCompositor {
29    /// Sets a new handler.
30    pub fn set_handler(&self, handler: impl WlCompositorHandler) {
31        self.set_boxed_handler(Box::new(handler));
32    }
33
34    /// Sets a new, already boxed handler.
35    pub fn set_boxed_handler(&self, handler: Box<dyn WlCompositorHandler>) {
36        if self.core.state.destroyed.get() {
37            return;
38        }
39        self.handler.set(Some(handler));
40    }
41}
42
43impl Debug for WlCompositor {
44    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
45        f.debug_struct("WlCompositor")
46            .field("server_obj_id", &self.core.server_obj_id.get())
47            .field("client_id", &self.core.client_id.get())
48            .field("client_obj_id", &self.core.client_obj_id.get())
49            .finish()
50    }
51}
52
53impl WlCompositor {
54    /// Since when the create_surface message is available.
55    pub const MSG__CREATE_SURFACE__SINCE: u32 = 1;
56
57    /// create new surface
58    ///
59    /// Ask the compositor to create a new surface.
60    ///
61    /// # Arguments
62    ///
63    /// - `id`: the new surface
64    #[inline]
65    pub fn try_send_create_surface(
66        &self,
67        id: &Rc<WlSurface>,
68    ) -> Result<(), ObjectError> {
69        let (
70            arg0,
71        ) = (
72            id,
73        );
74        let arg0_obj = arg0;
75        let arg0 = arg0_obj.core();
76        let core = self.core();
77        let Some(id) = core.server_obj_id.get() else {
78            return Err(ObjectError(ObjectErrorKind::ReceiverNoServerId));
79        };
80        arg0.generate_server_id(arg0_obj.clone())
81            .map_err(|e| ObjectError(ObjectErrorKind::GenerateServerId("id", e)))?;
82        let arg0_id = arg0.server_obj_id.get().unwrap_or(0);
83        #[cfg(feature = "logging")]
84        if self.core.state.log {
85            #[cold]
86            fn log(state: &State, id: u32, arg0: u32) {
87                let (millis, micros) = time_since_epoch();
88                let prefix = &state.log_prefix;
89                let args = format_args!("[{millis:7}.{micros:03}] {prefix}server      <= wl_compositor#{}.create_surface(id: wl_surface#{})\n", id, arg0);
90                state.log(args);
91            }
92            log(&self.core.state, id, arg0_id);
93        }
94        let Some(endpoint) = &self.core.state.server else {
95            return Ok(());
96        };
97        if !endpoint.flush_queued.replace(true) {
98            self.core.state.add_flushable_endpoint(endpoint, None);
99        }
100        let mut outgoing_ref = endpoint.outgoing.borrow_mut();
101        let outgoing = &mut *outgoing_ref;
102        let mut fmt = outgoing.formatter();
103        fmt.words([
104            id,
105            0,
106            arg0_id,
107        ]);
108        Ok(())
109    }
110
111    /// create new surface
112    ///
113    /// Ask the compositor to create a new surface.
114    ///
115    /// # Arguments
116    ///
117    /// - `id`: the new surface
118    #[inline]
119    pub fn send_create_surface(
120        &self,
121        id: &Rc<WlSurface>,
122    ) {
123        let res = self.try_send_create_surface(
124            id,
125        );
126        if let Err(e) = res {
127            log_send("wl_compositor.create_surface", &e);
128        }
129    }
130
131    /// create new surface
132    ///
133    /// Ask the compositor to create a new surface.
134    #[inline]
135    pub fn new_try_send_create_surface(
136        &self,
137    ) -> Result<Rc<WlSurface>, ObjectError> {
138        let id = self.core.create_child();
139        self.try_send_create_surface(
140            &id,
141        )?;
142        Ok(id)
143    }
144
145    /// create new surface
146    ///
147    /// Ask the compositor to create a new surface.
148    #[inline]
149    pub fn new_send_create_surface(
150        &self,
151    ) -> Rc<WlSurface> {
152        let id = self.core.create_child();
153        self.send_create_surface(
154            &id,
155        );
156        id
157    }
158
159    /// Since when the create_region message is available.
160    pub const MSG__CREATE_REGION__SINCE: u32 = 1;
161
162    /// create new region
163    ///
164    /// Ask the compositor to create a new region.
165    ///
166    /// # Arguments
167    ///
168    /// - `id`: the new region
169    #[inline]
170    pub fn try_send_create_region(
171        &self,
172        id: &Rc<WlRegion>,
173    ) -> Result<(), ObjectError> {
174        let (
175            arg0,
176        ) = (
177            id,
178        );
179        let arg0_obj = arg0;
180        let arg0 = arg0_obj.core();
181        let core = self.core();
182        let Some(id) = core.server_obj_id.get() else {
183            return Err(ObjectError(ObjectErrorKind::ReceiverNoServerId));
184        };
185        arg0.generate_server_id(arg0_obj.clone())
186            .map_err(|e| ObjectError(ObjectErrorKind::GenerateServerId("id", e)))?;
187        let arg0_id = arg0.server_obj_id.get().unwrap_or(0);
188        #[cfg(feature = "logging")]
189        if self.core.state.log {
190            #[cold]
191            fn log(state: &State, id: u32, arg0: u32) {
192                let (millis, micros) = time_since_epoch();
193                let prefix = &state.log_prefix;
194                let args = format_args!("[{millis:7}.{micros:03}] {prefix}server      <= wl_compositor#{}.create_region(id: wl_region#{})\n", id, arg0);
195                state.log(args);
196            }
197            log(&self.core.state, id, arg0_id);
198        }
199        let Some(endpoint) = &self.core.state.server else {
200            return Ok(());
201        };
202        if !endpoint.flush_queued.replace(true) {
203            self.core.state.add_flushable_endpoint(endpoint, None);
204        }
205        let mut outgoing_ref = endpoint.outgoing.borrow_mut();
206        let outgoing = &mut *outgoing_ref;
207        let mut fmt = outgoing.formatter();
208        fmt.words([
209            id,
210            1,
211            arg0_id,
212        ]);
213        Ok(())
214    }
215
216    /// create new region
217    ///
218    /// Ask the compositor to create a new region.
219    ///
220    /// # Arguments
221    ///
222    /// - `id`: the new region
223    #[inline]
224    pub fn send_create_region(
225        &self,
226        id: &Rc<WlRegion>,
227    ) {
228        let res = self.try_send_create_region(
229            id,
230        );
231        if let Err(e) = res {
232            log_send("wl_compositor.create_region", &e);
233        }
234    }
235
236    /// create new region
237    ///
238    /// Ask the compositor to create a new region.
239    #[inline]
240    pub fn new_try_send_create_region(
241        &self,
242    ) -> Result<Rc<WlRegion>, ObjectError> {
243        let id = self.core.create_child();
244        self.try_send_create_region(
245            &id,
246        )?;
247        Ok(id)
248    }
249
250    /// create new region
251    ///
252    /// Ask the compositor to create a new region.
253    #[inline]
254    pub fn new_send_create_region(
255        &self,
256    ) -> Rc<WlRegion> {
257        let id = self.core.create_child();
258        self.send_create_region(
259            &id,
260        );
261        id
262    }
263}
264
265/// A message handler for [`WlCompositor`] proxies.
266pub trait WlCompositorHandler: Any {
267    /// Event handler for wl_display.delete_id messages deleting the ID of this object.
268    ///
269    /// The default handler forwards the event to the client, if any.
270    #[inline]
271    fn delete_id(&mut self, slf: &Rc<WlCompositor>) {
272        slf.core.delete_id();
273    }
274
275    /// create new surface
276    ///
277    /// Ask the compositor to create a new surface.
278    ///
279    /// # Arguments
280    ///
281    /// - `id`: the new surface
282    #[inline]
283    fn handle_create_surface(
284        &mut self,
285        slf: &Rc<WlCompositor>,
286        id: &Rc<WlSurface>,
287    ) {
288        if !slf.core.forward_to_server.get() {
289            return;
290        }
291        let res = slf.try_send_create_surface(
292            id,
293        );
294        if let Err(e) = res {
295            log_forward("wl_compositor.create_surface", &e);
296        }
297    }
298
299    /// create new region
300    ///
301    /// Ask the compositor to create a new region.
302    ///
303    /// # Arguments
304    ///
305    /// - `id`: the new region
306    #[inline]
307    fn handle_create_region(
308        &mut self,
309        slf: &Rc<WlCompositor>,
310        id: &Rc<WlRegion>,
311    ) {
312        if !slf.core.forward_to_server.get() {
313            return;
314        }
315        let res = slf.try_send_create_region(
316            id,
317        );
318        if let Err(e) = res {
319            log_forward("wl_compositor.create_region", &e);
320        }
321    }
322}
323
324impl ObjectPrivate for WlCompositor {
325    fn new(state: &Rc<State>, version: u32) -> Rc<Self> {
326        Rc::<Self>::new_cyclic(|slf| Self {
327            core: ObjectCore::new(state, slf.clone(), ObjectInterface::WlCompositor, version),
328            handler: Default::default(),
329        })
330    }
331
332    fn delete_id(self: Rc<Self>) -> Result<(), (ObjectError, Rc<dyn Object>)> {
333        let Some(mut handler) = self.handler.try_borrow_mut() else {
334            return Err((ObjectError(ObjectErrorKind::HandlerBorrowed), self));
335        };
336        if let Some(handler) = &mut *handler {
337            handler.delete_id(&self);
338        } else {
339            self.core.delete_id();
340        }
341        Ok(())
342    }
343
344    fn handle_request(self: Rc<Self>, client: &Rc<Client>, msg: &[u32], fds: &mut VecDeque<Rc<OwnedFd>>) -> Result<(), ObjectError> {
345        let Some(mut handler) = self.handler.try_borrow_mut() else {
346            return Err(ObjectError(ObjectErrorKind::HandlerBorrowed));
347        };
348        let handler = &mut *handler;
349        match msg[1] & 0xffff {
350            0 => {
351                let [
352                    arg0,
353                ] = msg[2..] else {
354                    return Err(ObjectError(ObjectErrorKind::WrongMessageSize(msg.len() as u32 * 4, 12)));
355                };
356                #[cfg(feature = "logging")]
357                if self.core.state.log {
358                    #[cold]
359                    fn log(state: &State, client_id: u64, id: u32, arg0: u32) {
360                        let (millis, micros) = time_since_epoch();
361                        let prefix = &state.log_prefix;
362                        let args = format_args!("[{millis:7}.{micros:03}] {prefix}client#{:<4} -> wl_compositor#{}.create_surface(id: wl_surface#{})\n", client_id, id, arg0);
363                        state.log(args);
364                    }
365                    log(&self.core.state, client.endpoint.id, msg[0], arg0);
366                }
367                let arg0_id = arg0;
368                let arg0 = WlSurface::new(&self.core.state, self.core.version);
369                arg0.core().set_client_id(client, arg0_id, arg0.clone())
370                    .map_err(|e| ObjectError(ObjectErrorKind::SetClientId(arg0_id, "id", e)))?;
371                let arg0 = &arg0;
372                if let Some(handler) = handler {
373                    (**handler).handle_create_surface(&self, arg0);
374                } else {
375                    DefaultHandler.handle_create_surface(&self, arg0);
376                }
377            }
378            1 => {
379                let [
380                    arg0,
381                ] = msg[2..] else {
382                    return Err(ObjectError(ObjectErrorKind::WrongMessageSize(msg.len() as u32 * 4, 12)));
383                };
384                #[cfg(feature = "logging")]
385                if self.core.state.log {
386                    #[cold]
387                    fn log(state: &State, client_id: u64, id: u32, arg0: u32) {
388                        let (millis, micros) = time_since_epoch();
389                        let prefix = &state.log_prefix;
390                        let args = format_args!("[{millis:7}.{micros:03}] {prefix}client#{:<4} -> wl_compositor#{}.create_region(id: wl_region#{})\n", client_id, id, arg0);
391                        state.log(args);
392                    }
393                    log(&self.core.state, client.endpoint.id, msg[0], arg0);
394                }
395                let arg0_id = arg0;
396                let arg0 = WlRegion::new(&self.core.state, self.core.version);
397                arg0.core().set_client_id(client, arg0_id, arg0.clone())
398                    .map_err(|e| ObjectError(ObjectErrorKind::SetClientId(arg0_id, "id", e)))?;
399                let arg0 = &arg0;
400                if let Some(handler) = handler {
401                    (**handler).handle_create_region(&self, arg0);
402                } else {
403                    DefaultHandler.handle_create_region(&self, arg0);
404                }
405            }
406            n => {
407                let _ = client;
408                let _ = msg;
409                let _ = fds;
410                let _ = handler;
411                return Err(ObjectError(ObjectErrorKind::UnknownMessageId(n)));
412            }
413        }
414        Ok(())
415    }
416
417    fn handle_event(self: Rc<Self>, server: &Endpoint, msg: &[u32], fds: &mut VecDeque<Rc<OwnedFd>>) -> Result<(), ObjectError> {
418        let Some(mut handler) = self.handler.try_borrow_mut() else {
419            return Err(ObjectError(ObjectErrorKind::HandlerBorrowed));
420        };
421        let handler = &mut *handler;
422        match msg[1] & 0xffff {
423            n => {
424                let _ = server;
425                let _ = msg;
426                let _ = fds;
427                let _ = handler;
428                return Err(ObjectError(ObjectErrorKind::UnknownMessageId(n)));
429            }
430        }
431    }
432
433    fn get_request_name(&self, id: u32) -> Option<&'static str> {
434        let name = match id {
435            0 => "create_surface",
436            1 => "create_region",
437            _ => return None,
438        };
439        Some(name)
440    }
441
442    fn get_event_name(&self, id: u32) -> Option<&'static str> {
443        let _ = id;
444        None
445    }
446}
447
448impl Object for WlCompositor {
449    fn core(&self) -> &ObjectCore {
450        &self.core
451    }
452
453    fn unset_handler(&self) {
454        self.handler.set(None);
455    }
456
457    fn get_handler_any_ref(&self) -> Result<HandlerRef<'_, dyn Any>, HandlerAccessError> {
458        let borrowed = self.handler.try_borrow().ok_or(HandlerAccessError::AlreadyBorrowed)?;
459        if borrowed.is_none() {
460            return Err(HandlerAccessError::NoHandler);
461        }
462        Ok(HandlerRef::map(borrowed, |handler| &**handler.as_ref().unwrap() as &dyn Any))
463    }
464
465    fn get_handler_any_mut(&self) -> Result<HandlerMut<'_, dyn Any>, HandlerAccessError> {
466        let borrowed = self.handler.try_borrow_mut().ok_or(HandlerAccessError::AlreadyBorrowed)?;
467        if borrowed.is_none() {
468            return Err(HandlerAccessError::NoHandler);
469        }
470        Ok(HandlerMut::map(borrowed, |handler| &mut **handler.as_mut().unwrap() as &mut dyn Any))
471    }
472}
473