Skip to main content

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 = 7;
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    /// Since when the release message is available.
265    pub const MSG__RELEASE__SINCE: u32 = 7;
266
267    /// destroy wl_compositor
268    ///
269    /// This request destroys the wl_compositor. This has no effect on any other objects.
270    #[inline]
271    pub fn try_send_release(
272        &self,
273    ) -> Result<(), ObjectError> {
274        let core = self.core();
275        let Some(id) = core.server_obj_id.get() else {
276            return Err(ObjectError(ObjectErrorKind::ReceiverNoServerId));
277        };
278        #[cfg(feature = "logging")]
279        if self.core.state.log {
280            #[cold]
281            fn log(state: &State, id: u32) {
282                let (millis, micros) = time_since_epoch();
283                let prefix = &state.log_prefix;
284                let args = format_args!("[{millis:7}.{micros:03}] {prefix}server      <= wl_compositor#{}.release()\n", id);
285                state.log(args);
286            }
287            log(&self.core.state, id);
288        }
289        let Some(endpoint) = &self.core.state.server else {
290            return Ok(());
291        };
292        if !endpoint.flush_queued.replace(true) {
293            self.core.state.add_flushable_endpoint(endpoint, None);
294        }
295        let mut outgoing_ref = endpoint.outgoing.borrow_mut();
296        let outgoing = &mut *outgoing_ref;
297        let mut fmt = outgoing.formatter();
298        fmt.words([
299            id,
300            2,
301        ]);
302        self.core.handle_server_destroy();
303        Ok(())
304    }
305
306    /// destroy wl_compositor
307    ///
308    /// This request destroys the wl_compositor. This has no effect on any other objects.
309    #[inline]
310    pub fn send_release(
311        &self,
312    ) {
313        let res = self.try_send_release(
314        );
315        if let Err(e) = res {
316            log_send("wl_compositor.release", &e);
317        }
318    }
319}
320
321/// A message handler for [`WlCompositor`] proxies.
322pub trait WlCompositorHandler: Any {
323    /// Event handler for wl_display.delete_id messages deleting the ID of this object.
324    ///
325    /// The default handler forwards the event to the client, if any.
326    #[inline]
327    fn delete_id(&mut self, slf: &Rc<WlCompositor>) {
328        slf.core.delete_id();
329    }
330
331    /// create new surface
332    ///
333    /// Ask the compositor to create a new surface.
334    ///
335    /// # Arguments
336    ///
337    /// - `id`: the new surface
338    #[inline]
339    fn handle_create_surface(
340        &mut self,
341        slf: &Rc<WlCompositor>,
342        id: &Rc<WlSurface>,
343    ) {
344        if !slf.core.forward_to_server.get() {
345            return;
346        }
347        let res = slf.try_send_create_surface(
348            id,
349        );
350        if let Err(e) = res {
351            log_forward("wl_compositor.create_surface", &e);
352        }
353    }
354
355    /// create new region
356    ///
357    /// Ask the compositor to create a new region.
358    ///
359    /// # Arguments
360    ///
361    /// - `id`: the new region
362    #[inline]
363    fn handle_create_region(
364        &mut self,
365        slf: &Rc<WlCompositor>,
366        id: &Rc<WlRegion>,
367    ) {
368        if !slf.core.forward_to_server.get() {
369            return;
370        }
371        let res = slf.try_send_create_region(
372            id,
373        );
374        if let Err(e) = res {
375            log_forward("wl_compositor.create_region", &e);
376        }
377    }
378
379    /// destroy wl_compositor
380    ///
381    /// This request destroys the wl_compositor. This has no effect on any other objects.
382    #[inline]
383    fn handle_release(
384        &mut self,
385        slf: &Rc<WlCompositor>,
386    ) {
387        if !slf.core.forward_to_server.get() {
388            return;
389        }
390        let res = slf.try_send_release(
391        );
392        if let Err(e) = res {
393            log_forward("wl_compositor.release", &e);
394        }
395    }
396}
397
398impl ObjectPrivate for WlCompositor {
399    fn new(state: &Rc<State>, version: u32) -> Rc<Self> {
400        Rc::<Self>::new_cyclic(|slf| Self {
401            core: ObjectCore::new(state, slf.clone(), ObjectInterface::WlCompositor, version),
402            handler: Default::default(),
403        })
404    }
405
406    fn delete_id(self: Rc<Self>) -> Result<(), (ObjectError, Rc<dyn Object>)> {
407        let Some(mut handler) = self.handler.try_borrow_mut() else {
408            return Err((ObjectError(ObjectErrorKind::HandlerBorrowed), self));
409        };
410        if let Some(handler) = &mut *handler {
411            handler.delete_id(&self);
412        } else {
413            self.core.delete_id();
414        }
415        Ok(())
416    }
417
418    fn handle_request(self: Rc<Self>, client: &Rc<Client>, msg: &[u32], fds: &mut VecDeque<Rc<OwnedFd>>) -> Result<(), ObjectError> {
419        let Some(mut handler) = self.handler.try_borrow_mut() else {
420            return Err(ObjectError(ObjectErrorKind::HandlerBorrowed));
421        };
422        let handler = &mut *handler;
423        match msg[1] & 0xffff {
424            0 => {
425                let [
426                    arg0,
427                ] = msg[2..] else {
428                    return Err(ObjectError(ObjectErrorKind::WrongMessageSize(msg.len() as u32 * 4, 12)));
429                };
430                #[cfg(feature = "logging")]
431                if self.core.state.log {
432                    #[cold]
433                    fn log(state: &State, client_id: u64, id: u32, arg0: u32) {
434                        let (millis, micros) = time_since_epoch();
435                        let prefix = &state.log_prefix;
436                        let args = format_args!("[{millis:7}.{micros:03}] {prefix}client#{:<4} -> wl_compositor#{}.create_surface(id: wl_surface#{})\n", client_id, id, arg0);
437                        state.log(args);
438                    }
439                    log(&self.core.state, client.endpoint.id, msg[0], arg0);
440                }
441                let arg0_id = arg0;
442                let arg0 = WlSurface::new(&self.core.state, self.core.version);
443                arg0.core().set_client_id(client, arg0_id, arg0.clone())
444                    .map_err(|e| ObjectError(ObjectErrorKind::SetClientId(arg0_id, "id", e)))?;
445                let arg0 = &arg0;
446                if let Some(handler) = handler {
447                    (**handler).handle_create_surface(&self, arg0);
448                } else {
449                    DefaultHandler.handle_create_surface(&self, arg0);
450                }
451            }
452            1 => {
453                let [
454                    arg0,
455                ] = msg[2..] else {
456                    return Err(ObjectError(ObjectErrorKind::WrongMessageSize(msg.len() as u32 * 4, 12)));
457                };
458                #[cfg(feature = "logging")]
459                if self.core.state.log {
460                    #[cold]
461                    fn log(state: &State, client_id: u64, id: u32, arg0: u32) {
462                        let (millis, micros) = time_since_epoch();
463                        let prefix = &state.log_prefix;
464                        let args = format_args!("[{millis:7}.{micros:03}] {prefix}client#{:<4} -> wl_compositor#{}.create_region(id: wl_region#{})\n", client_id, id, arg0);
465                        state.log(args);
466                    }
467                    log(&self.core.state, client.endpoint.id, msg[0], arg0);
468                }
469                let arg0_id = arg0;
470                let arg0 = WlRegion::new(&self.core.state, self.core.version);
471                arg0.core().set_client_id(client, arg0_id, arg0.clone())
472                    .map_err(|e| ObjectError(ObjectErrorKind::SetClientId(arg0_id, "id", e)))?;
473                let arg0 = &arg0;
474                if let Some(handler) = handler {
475                    (**handler).handle_create_region(&self, arg0);
476                } else {
477                    DefaultHandler.handle_create_region(&self, arg0);
478                }
479            }
480            2 => {
481                if msg.len() != 2 {
482                    return Err(ObjectError(ObjectErrorKind::WrongMessageSize(msg.len() as u32 * 4, 8)));
483                }
484                #[cfg(feature = "logging")]
485                if self.core.state.log {
486                    #[cold]
487                    fn log(state: &State, client_id: u64, id: u32) {
488                        let (millis, micros) = time_since_epoch();
489                        let prefix = &state.log_prefix;
490                        let args = format_args!("[{millis:7}.{micros:03}] {prefix}client#{:<4} -> wl_compositor#{}.release()\n", client_id, id);
491                        state.log(args);
492                    }
493                    log(&self.core.state, client.endpoint.id, msg[0]);
494                }
495                self.core.handle_client_destroy();
496                if let Some(handler) = handler {
497                    (**handler).handle_release(&self);
498                } else {
499                    DefaultHandler.handle_release(&self);
500                }
501            }
502            n => {
503                let _ = client;
504                let _ = msg;
505                let _ = fds;
506                let _ = handler;
507                return Err(ObjectError(ObjectErrorKind::UnknownMessageId(n)));
508            }
509        }
510        Ok(())
511    }
512
513    fn handle_event(self: Rc<Self>, server: &Endpoint, msg: &[u32], fds: &mut VecDeque<Rc<OwnedFd>>) -> Result<(), ObjectError> {
514        let Some(mut handler) = self.handler.try_borrow_mut() else {
515            return Err(ObjectError(ObjectErrorKind::HandlerBorrowed));
516        };
517        let handler = &mut *handler;
518        match msg[1] & 0xffff {
519            n => {
520                let _ = server;
521                let _ = msg;
522                let _ = fds;
523                let _ = handler;
524                return Err(ObjectError(ObjectErrorKind::UnknownMessageId(n)));
525            }
526        }
527    }
528
529    fn get_request_name(&self, id: u32) -> Option<&'static str> {
530        let name = match id {
531            0 => "create_surface",
532            1 => "create_region",
533            2 => "release",
534            _ => return None,
535        };
536        Some(name)
537    }
538
539    fn get_event_name(&self, id: u32) -> Option<&'static str> {
540        let _ = id;
541        None
542    }
543}
544
545impl Object for WlCompositor {
546    fn core(&self) -> &ObjectCore {
547        &self.core
548    }
549
550    fn unset_handler(&self) {
551        self.handler.set(None);
552    }
553
554    fn get_handler_any_ref(&self) -> Result<HandlerRef<'_, dyn Any>, HandlerAccessError> {
555        let borrowed = self.handler.try_borrow().ok_or(HandlerAccessError::AlreadyBorrowed)?;
556        if borrowed.is_none() {
557            return Err(HandlerAccessError::NoHandler);
558        }
559        Ok(HandlerRef::map(borrowed, |handler| &**handler.as_ref().unwrap() as &dyn Any))
560    }
561
562    fn get_handler_any_mut(&self) -> Result<HandlerMut<'_, dyn Any>, HandlerAccessError> {
563        let borrowed = self.handler.try_borrow_mut().ok_or(HandlerAccessError::AlreadyBorrowed)?;
564        if borrowed.is_none() {
565            return Err(HandlerAccessError::NoHandler);
566        }
567        Ok(HandlerMut::map(borrowed, |handler| &mut **handler.as_mut().unwrap() as &mut dyn Any))
568    }
569}
570