|
| 1 | +use std::os::fd::OwnedFd; |
| 2 | +use std::sync::Arc; |
| 3 | +use wayland_client::{ |
| 4 | + backend::{self, Backend}, |
| 5 | + protocol::{wl_display, wl_registry}, |
| 6 | + Connection, Proxy, |
| 7 | +}; |
| 8 | + |
| 9 | +// This struct represents the data associated with our registry. |
| 10 | +struct RegistryData(Arc<Connection>); |
| 11 | + |
| 12 | +// Instead of implementing Dispatch on some global state, we will implement |
| 13 | +// ObjectData for our registry. This is required to receive events |
| 14 | +// (specifically, the wl_registry.global events) after our wl_registry.get_registry request. |
| 15 | +impl backend::ObjectData for RegistryData { |
| 16 | + fn event( |
| 17 | + self: Arc<Self>, |
| 18 | + _: &Backend, |
| 19 | + msg: backend::protocol::Message<backend::ObjectId, OwnedFd>, |
| 20 | + ) -> Option<Arc<dyn backend::ObjectData>> { |
| 21 | + // Here, we parse the wire message into an event using Proxy::parse_event. |
| 22 | + let (_registry, event) = wl_registry::WlRegistry::parse_event(&self.0, msg).unwrap(); |
| 23 | + |
| 24 | + // Similar to the dispatch example, we only care about the global event and |
| 25 | + // will print out the received globals. |
| 26 | + if let wl_registry::Event::Global { name, interface, version } = event { |
| 27 | + println!("[{}] {} (v{})", name, interface, version); |
| 28 | + } |
| 29 | + None |
| 30 | + } |
| 31 | + |
| 32 | + // This method is called whenever the object is destroyed. In the case of our registry, |
| 33 | + // however, there is no way to destroy it, so we will mark it as unreachable. |
| 34 | + fn destroyed(&self, _: wayland_backend::client::ObjectId) { |
| 35 | + unreachable!(); |
| 36 | + } |
| 37 | +} |
| 38 | + |
| 39 | +fn main() { |
| 40 | + // Create our connection like the Dispatch example, except we store it in an Arc |
| 41 | + // to share with our registry object data. |
| 42 | + let conn = Arc::new(Connection::connect_to_env().unwrap()); |
| 43 | + let display = conn.display(); |
| 44 | + |
| 45 | + let registry_data = Arc::new(RegistryData(conn.clone())); |
| 46 | + |
| 47 | + // Send the `wl_display.get_registry` request, which returns a `wl_registry` to us. |
| 48 | + // Since this request creates a new object, we will use the `Proxy::send_constructor` method |
| 49 | + // to send it. If it didn't, we would use `Proxy::send_request`. |
| 50 | + let _registry: wl_registry::WlRegistry = display |
| 51 | + .send_constructor(wl_display::Request::GetRegistry {}, registry_data.clone()) |
| 52 | + .unwrap(); |
| 53 | + |
| 54 | + println!("Advertised globals:"); |
| 55 | + |
| 56 | + // Invoke our roundtrip to receive the events. This essentially is the same as the |
| 57 | + // `EventQueue::roundtrip` method, except it does not have a state to dispatch methods on. |
| 58 | + conn.roundtrip().unwrap(); |
| 59 | +} |
0 commit comments