simple_window/common/
singletons.rs

1use {
2    crate::common::protocols::wayland::{
3        wl_display::WlDisplay, wl_fixes::WlFixes, wl_registry::WlRegistry,
4    },
5    parking_lot::Mutex,
6    std::collections::HashMap,
7    wl_client::{proxy, proxy::OwnedProxy},
8};
9
10pub struct Singletons {
11    wl_registry: WlRegistry,
12    map: HashMap<String, (u32, u32)>,
13}
14
15impl Singletons {
16    pub fn get<P>(&self, min: u32, max: u32) -> P
17    where
18        P: OwnedProxy,
19    {
20        match self.get_opt(min, max) {
21            Some(p) => p,
22            _ => {
23                panic!(
24                    "Compositor does not support {} ({}..={}) but it is required for this example",
25                    P::INTERFACE,
26                    min,
27                    max,
28                );
29            }
30        }
31    }
32
33    pub fn get_opt<P>(&self, min: u32, max: u32) -> Option<P>
34    where
35        P: OwnedProxy,
36    {
37        let &(name, comp_max) = self.map.get(P::INTERFACE)?;
38        let version = comp_max.min(max);
39        if version < min {
40            return None;
41        }
42        Some(self.wl_registry.bind(name, version))
43    }
44}
45
46impl Drop for Singletons {
47    fn drop(&mut self) {
48        if let Some(fixes) = self.get_opt::<WlFixes>(1, 1) {
49            fixes.destroy_registry(&self.wl_registry);
50            fixes.destroy();
51        }
52        proxy::destroy(&self.wl_registry);
53    }
54}
55
56pub fn get_singletons(display: &WlDisplay) -> Singletons {
57    let map = Mutex::new(HashMap::new());
58
59    let queue = proxy::queue(display);
60    let wl_registry = display.get_registry();
61
62    queue.dispatch_scope_blocking(|scope| {
63        scope.set_event_handler(
64            &wl_registry,
65            WlRegistry::on_global(|_, name, interface, version| {
66                map.lock().insert(interface.to_owned(), (name, version));
67            }),
68        );
69        queue.dispatch_roundtrip_blocking().unwrap();
70    });
71
72    Singletons {
73        wl_registry,
74        map: map.into_inner(),
75    }
76}
77
78pub async fn get_singletons_async(display: &WlDisplay) -> Singletons {
79    let map = Mutex::new(HashMap::new());
80
81    let queue = proxy::queue(display);
82    let wl_registry = display.get_registry();
83
84    queue
85        .dispatch_scope_async(async |scope| {
86            scope.set_event_handler(
87                &wl_registry,
88                WlRegistry::on_global(|_, name, interface, version| {
89                    map.lock().insert(interface.to_owned(), (name, version));
90                }),
91            );
92            queue.dispatch_roundtrip_async().await.unwrap();
93        })
94        .await;
95
96    Singletons {
97        wl_registry,
98        map: map.into_inner(),
99    }
100}