simple_window/common/protocols/wayland/wl_registry.rs
1//! global registry object
2//!
3//! The singleton global registry object. The server has a number of
4//! global objects that are available to all clients. These objects
5//! typically represent an actual object in the server (for example,
6//! an input device) or they are singleton objects that provide
7//! extension functionality.
8//!
9//! When a client creates a registry object, the registry object
10//! will emit a global event for each global currently in the
11//! registry. Globals come and go as a result of device or
12//! monitor hotplugs, reconfiguration or other events, and the
13//! registry will send out global and global_remove events to
14//! keep the client up to date with the changes. To mark the end
15//! of the initial burst of events, the client can use the
16//! wl_display.sync request immediately after calling
17//! wl_display.get_registry.
18//!
19//! A client can bind to a global object by using the bind
20//! request. This creates a client-side handle that lets the object
21//! emit events to the client and lets the client invoke requests on
22//! the object.
23
24use {super::super::all_types::*, ::wl_client::builder::prelude::*};
25
26static INTERFACE: wl_interface = wl_interface {
27 name: c"wl_registry".as_ptr(),
28 version: 1,
29 method_count: 1,
30 methods: {
31 static MESSAGES: [wl_message; 1] = [wl_message {
32 name: c"bind".as_ptr(),
33 signature: c"usun".as_ptr(),
34 types: {
35 static TYPES: [Option<&'static wl_interface>; 4] = [None, None, None, None];
36 TYPES.as_ptr().cast()
37 },
38 }];
39 MESSAGES.as_ptr()
40 },
41 event_count: 2,
42 events: {
43 static MESSAGES: [wl_message; 2] = [
44 wl_message {
45 name: c"global".as_ptr(),
46 signature: c"usu".as_ptr(),
47 types: {
48 static TYPES: [Option<&'static wl_interface>; 3] = [None, None, None];
49 TYPES.as_ptr().cast()
50 },
51 },
52 wl_message {
53 name: c"global_remove".as_ptr(),
54 signature: c"u".as_ptr(),
55 types: {
56 static TYPES: [Option<&'static wl_interface>; 1] = [None];
57 TYPES.as_ptr().cast()
58 },
59 },
60 ];
61 MESSAGES.as_ptr()
62 },
63};
64
65/// An owned wl_registry proxy.
66///
67/// See the documentation of [the module][self] for the interface description.
68#[derive(Clone, Eq, PartialEq)]
69#[repr(transparent)]
70pub struct WlRegistry {
71 /// This proxy has the interface INTERFACE.
72 proxy: UntypedOwnedProxy,
73}
74
75/// A borrowed wl_registry proxy.
76///
77/// See the documentation of [the module][self] for the interface description.
78#[derive(Eq, PartialEq)]
79#[repr(transparent)]
80pub struct WlRegistryRef {
81 /// This proxy has the interface INTERFACE.
82 proxy: UntypedBorrowedProxy,
83}
84
85// SAFETY: WlRegistry is a transparent wrapper around UntypedOwnedProxy
86unsafe impl UntypedOwnedProxyWrapper for WlRegistry {}
87
88// SAFETY: - INTERFACE is a valid wl_interface
89// - The only invariant is that self.proxy has a compatible interface
90unsafe impl OwnedProxy for WlRegistry {
91 const INTERFACE: &'static str = "wl_registry";
92 const WL_INTERFACE: &'static wl_interface = &INTERFACE;
93 const NO_OP_EVENT_HANDLER: Self::NoOpEventHandler =
94 private::EventHandler(private::NoOpEventHandler);
95 const MAX_VERSION: u32 = 1;
96
97 type Borrowed = WlRegistryRef;
98 type Api = private::ProxyApi;
99 type NoOpEventHandler = private::EventHandler<private::NoOpEventHandler>;
100}
101
102// SAFETY: WlRegistryRef is a transparent wrapper around UntypedBorrowedProxy
103unsafe impl UntypedBorrowedProxyWrapper for WlRegistryRef {}
104
105// SAFETY: - The only invariant is that self.proxy has a compatible interface
106unsafe impl BorrowedProxy for WlRegistryRef {
107 type Owned = WlRegistry;
108}
109
110impl Deref for WlRegistry {
111 type Target = WlRegistryRef;
112
113 fn deref(&self) -> &Self::Target {
114 proxy::low_level::deref(self)
115 }
116}
117
118mod private {
119 pub struct ProxyApi;
120
121 #[allow(dead_code)]
122 pub struct EventHandler<H>(pub(super) H);
123
124 #[allow(dead_code)]
125 pub struct NoOpEventHandler;
126}
127
128impl Debug for WlRegistry {
129 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
130 write!(f, "wl_registry#{}", self.proxy.id())
131 }
132}
133
134impl Debug for WlRegistryRef {
135 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
136 write!(f, "wl_registry#{}", self.proxy.id())
137 }
138}
139
140impl PartialEq<WlRegistryRef> for WlRegistry {
141 fn eq(&self, other: &WlRegistryRef) -> bool {
142 self.proxy == other.proxy
143 }
144}
145
146impl PartialEq<WlRegistry> for WlRegistryRef {
147 fn eq(&self, other: &WlRegistry) -> bool {
148 self.proxy == other.proxy
149 }
150}
151
152#[allow(dead_code)]
153impl WlRegistry {
154 /// Since when the bind request is available.
155 #[allow(dead_code)]
156 pub const REQ__BIND__SINCE: u32 = 1;
157
158 /// bind an object to the display
159 ///
160 /// Binds a new, client-created object to the server using the
161 /// specified name as the identifier.
162 ///
163 /// # Arguments
164 ///
165 /// - `name`: unique numeric name of the object
166 #[inline]
167 pub fn bind<P: OwnedProxy>(&self, name: u32, version: u32) -> P {
168 let (arg0, arg1) = (name, version);
169 let mut args = [
170 wl_argument { u: arg0 },
171 wl_argument {
172 s: P::WL_INTERFACE.name,
173 },
174 wl_argument { u: arg1 },
175 wl_argument { n: 0 },
176 ];
177 // SAFETY: - self.proxy has the interface INTERFACE
178 // - 0 < INTERFACE.method_count = 1
179 // - the request signature is `usun`
180 // - OwnedProxy::WL_INTERFACE is always a valid interface
181 let data = unsafe {
182 self.proxy
183 .send_constructor::<false>(0, &mut args, P::WL_INTERFACE, Some(version))
184 };
185 // SAFETY: data has the interface P::WL_INTERFACE
186 unsafe { proxy::low_level::from_untyped_owned(data) }
187 }
188}
189
190#[allow(dead_code)]
191impl WlRegistryRef {
192 /// bind an object to the display
193 ///
194 /// Binds a new, client-created object to the server using the
195 /// specified name as the identifier.
196 ///
197 /// # Arguments
198 ///
199 /// - `_queue`: The queue that the returned proxy is assigned to.
200 /// - `name`: unique numeric name of the object
201 #[inline]
202 pub fn bind<P: OwnedProxy>(&self, _queue: &Queue, name: u32, version: u32) -> P {
203 let (arg0, arg1) = (name, version);
204 let mut args = [
205 wl_argument { u: arg0 },
206 wl_argument {
207 s: P::WL_INTERFACE.name,
208 },
209 wl_argument { u: arg1 },
210 wl_argument { n: 0 },
211 ];
212 // SAFETY: - self.proxy has the interface INTERFACE
213 // - 0 < INTERFACE.method_count = 1
214 // - the request signature is `usun`
215 // - OwnedProxy::WL_INTERFACE is always a valid interface
216 let data = unsafe {
217 self.proxy
218 .send_constructor(_queue, 0, &mut args, P::WL_INTERFACE, Some(version))
219 };
220 // SAFETY: data has the interface P::WL_INTERFACE
221 unsafe { proxy::low_level::from_untyped_owned(data) }
222 }
223}
224
225impl WlRegistry {
226 /// Since when the global event is available.
227 #[allow(dead_code)]
228 pub const EVT__GLOBAL__SINCE: u32 = 1;
229
230 /// Since when the global_remove event is available.
231 #[allow(dead_code)]
232 pub const EVT__GLOBAL_REMOVE__SINCE: u32 = 1;
233}
234
235/// An event handler for [WlRegistry] proxies.
236#[allow(dead_code)]
237pub trait WlRegistryEventHandler {
238 /// announce global object
239 ///
240 /// Notify the client of global objects.
241 ///
242 /// The event notifies the client that a global object with
243 /// the given name is now available, and it implements the
244 /// given version of the given interface.
245 ///
246 /// # Arguments
247 ///
248 /// - `name`: numeric name of the global object
249 /// - `interface`: interface implemented by the object
250 /// - `version`: interface version
251 #[inline]
252 fn global(&self, _slf: &WlRegistryRef, name: u32, interface: &str, version: u32) {
253 let _ = name;
254 let _ = interface;
255 let _ = version;
256 }
257
258 /// announce removal of global object
259 ///
260 /// Notify the client of removed global objects.
261 ///
262 /// This event notifies the client that the global identified
263 /// by name is no longer available. If the client bound to
264 /// the global using the bind request, the client should now
265 /// destroy that object.
266 ///
267 /// The object remains valid and requests to the object will be
268 /// ignored until the client destroys it, to avoid races between
269 /// the global going away and a client sending a request to it.
270 ///
271 /// # Arguments
272 ///
273 /// - `name`: numeric name of the global object
274 #[inline]
275 fn global_remove(&self, _slf: &WlRegistryRef, name: u32) {
276 let _ = name;
277 }
278}
279
280impl WlRegistryEventHandler for private::NoOpEventHandler {}
281
282// SAFETY: - INTERFACE is a valid wl_interface
283unsafe impl<H> EventHandler for private::EventHandler<H>
284where
285 H: WlRegistryEventHandler,
286{
287 const WL_INTERFACE: &'static wl_interface = &INTERFACE;
288
289 #[allow(unused_variables)]
290 unsafe fn handle_event(
291 &self,
292 queue: &Queue,
293 data: *mut u8,
294 slf: &UntypedBorrowedProxy,
295 opcode: u32,
296 args: *mut wl_argument,
297 ) {
298 // SAFETY: This function requires that slf has the interface INTERFACE
299 let slf = unsafe { proxy::low_level::from_untyped_borrowed::<WlRegistryRef>(slf) };
300 match opcode {
301 0 => {
302 // SAFETY: INTERFACE requires that there are 3 arguments
303 let args = unsafe { &*args.cast::<[wl_argument; 3]>() };
304 // SAFETY: - INTERFACE requires that args[0] contains a uint
305 let arg0 = unsafe { args[0].u };
306 // SAFETY: - INTERFACE requires that args[1] contains a string
307 // - if the pointer is not null, then it is a c string
308 let arg1 = unsafe { convert_string_arg("wl_registry", "interface", args[1].s) };
309 // SAFETY: - INTERFACE requires that args[2] contains a uint
310 let arg2 = unsafe { args[2].u };
311 self.0.global(slf, arg0, arg1, arg2);
312 }
313 1 => {
314 // SAFETY: INTERFACE requires that there are 1 arguments
315 let args = unsafe { &*args.cast::<[wl_argument; 1]>() };
316 // SAFETY: - INTERFACE requires that args[0] contains a uint
317 let arg0 = unsafe { args[0].u };
318 self.0.global_remove(slf, arg0);
319 }
320 _ => {
321 invalid_opcode("wl_registry", opcode);
322 }
323 }
324 }
325}
326
327impl<H> CreateEventHandler<H> for private::ProxyApi
328where
329 H: WlRegistryEventHandler,
330{
331 type EventHandler = private::EventHandler<H>;
332
333 #[inline]
334 fn create_event_handler(handler: H) -> Self::EventHandler {
335 private::EventHandler(handler)
336 }
337}
338
339/// Functional event handlers.
340pub mod event_handlers {
341 use super::*;
342
343 /// Event handler for global events.
344 pub struct Global<F>(F);
345 impl<F> WlRegistryEventHandler for Global<F>
346 where
347 F: Fn(&WlRegistryRef, u32, &str, u32),
348 {
349 #[inline]
350 fn global(&self, _slf: &WlRegistryRef, name: u32, interface: &str, version: u32) {
351 self.0(_slf, name, interface, version)
352 }
353 }
354
355 /// Event handler for global_remove events.
356 pub struct GlobalRemove<F>(F);
357 impl<F> WlRegistryEventHandler for GlobalRemove<F>
358 where
359 F: Fn(&WlRegistryRef, u32),
360 {
361 #[inline]
362 fn global_remove(&self, _slf: &WlRegistryRef, name: u32) {
363 self.0(_slf, name)
364 }
365 }
366
367 impl WlRegistry {
368 /// Creates an event handler for global events.
369 ///
370 /// The event handler ignores all other events.
371 #[allow(dead_code)]
372 pub fn on_global<F>(f: F) -> Global<F>
373 where
374 F: Fn(&WlRegistryRef, u32, &str, u32),
375 {
376 Global(f)
377 }
378
379 /// Creates an event handler for global_remove events.
380 ///
381 /// The event handler ignores all other events.
382 #[allow(dead_code)]
383 pub fn on_global_remove<F>(f: F) -> GlobalRemove<F>
384 where
385 F: Fn(&WlRegistryRef, u32),
386 {
387 GlobalRemove(f)
388 }
389 }
390}