async_roundtrip/common/protocols_data/wayland/wl_display.rs
1//! core global object
2//!
3//! The core global object. This is a special singleton object. It
4//! is used for internal Wayland protocol features.
5
6use {super::super::all_types::*, ::wl_client::builder::prelude::*};
7
8static INTERFACE: wl_interface = wl_interface {
9 name: c"wl_display".as_ptr(),
10 version: 1,
11 method_count: 2,
12 methods: {
13 static MESSAGES: [wl_message; 2] = [
14 wl_message {
15 name: c"sync".as_ptr(),
16 signature: c"n".as_ptr(),
17 types: {
18 static TYPES: [Option<&'static wl_interface>; 1] =
19 [Some(WlCallback::WL_INTERFACE)];
20 TYPES.as_ptr().cast()
21 },
22 },
23 wl_message {
24 name: c"get_registry".as_ptr(),
25 signature: c"n".as_ptr(),
26 types: {
27 static TYPES: [Option<&'static wl_interface>; 1] =
28 [Some(WlRegistry::WL_INTERFACE)];
29 TYPES.as_ptr().cast()
30 },
31 },
32 ];
33 MESSAGES.as_ptr()
34 },
35 event_count: 2,
36 events: {
37 static MESSAGES: [wl_message; 2] = [
38 wl_message {
39 name: c"error".as_ptr(),
40 signature: c"ous".as_ptr(),
41 types: {
42 static TYPES: [Option<&'static wl_interface>; 3] = [None, None, None];
43 TYPES.as_ptr().cast()
44 },
45 },
46 wl_message {
47 name: c"delete_id".as_ptr(),
48 signature: c"u".as_ptr(),
49 types: {
50 static TYPES: [Option<&'static wl_interface>; 1] = [None];
51 TYPES.as_ptr().cast()
52 },
53 },
54 ];
55 MESSAGES.as_ptr()
56 },
57};
58
59/// An owned wl_display proxy.
60///
61/// See the documentation of [the module][self] for the interface description.
62#[derive(Clone, Eq, PartialEq)]
63#[repr(transparent)]
64pub struct WlDisplay {
65 /// This proxy has the interface INTERFACE.
66 proxy: UntypedOwnedProxy,
67}
68
69/// A borrowed wl_display proxy.
70///
71/// See the documentation of [the module][self] for the interface description.
72#[derive(Eq, PartialEq)]
73#[repr(transparent)]
74pub struct WlDisplayRef {
75 /// This proxy has the interface INTERFACE.
76 proxy: UntypedBorrowedProxy,
77}
78
79// SAFETY: WlDisplay is a transparent wrapper around UntypedOwnedProxy
80unsafe impl UntypedOwnedProxyWrapper for WlDisplay {}
81
82// SAFETY: - INTERFACE is a valid wl_interface
83// - The only invariant is that self.proxy has a compatible interface
84unsafe impl OwnedProxy for WlDisplay {
85 const INTERFACE: &'static str = "wl_display";
86 const WL_INTERFACE: &'static wl_interface = &INTERFACE;
87 const NO_OP_EVENT_HANDLER: Self::NoOpEventHandler =
88 private::EventHandler(private::NoOpEventHandler);
89 const MAX_VERSION: u32 = 1;
90
91 type Borrowed = WlDisplayRef;
92 type Api = private::ProxyApi;
93 type NoOpEventHandler = private::EventHandler<private::NoOpEventHandler>;
94}
95
96// SAFETY: WlDisplayRef is a transparent wrapper around UntypedBorrowedProxy
97unsafe impl UntypedBorrowedProxyWrapper for WlDisplayRef {}
98
99// SAFETY: - The only invariant is that self.proxy has a compatible interface
100unsafe impl BorrowedProxy for WlDisplayRef {
101 type Owned = WlDisplay;
102}
103
104impl Deref for WlDisplay {
105 type Target = WlDisplayRef;
106
107 fn deref(&self) -> &Self::Target {
108 proxy::low_level::deref(self)
109 }
110}
111
112mod private {
113 pub struct ProxyApi;
114
115 #[allow(dead_code)]
116 pub struct EventHandler<H>(pub(super) H);
117
118 #[allow(dead_code)]
119 pub struct NoOpEventHandler;
120}
121
122impl Debug for WlDisplay {
123 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
124 write!(f, "wl_display#{}", self.proxy.id())
125 }
126}
127
128impl Debug for WlDisplayRef {
129 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
130 write!(f, "wl_display#{}", self.proxy.id())
131 }
132}
133
134impl PartialEq<WlDisplayRef> for WlDisplay {
135 fn eq(&self, other: &WlDisplayRef) -> bool {
136 self.proxy == other.proxy
137 }
138}
139
140impl PartialEq<WlDisplay> for WlDisplayRef {
141 fn eq(&self, other: &WlDisplay) -> bool {
142 self.proxy == other.proxy
143 }
144}
145
146#[allow(dead_code)]
147impl WlDisplay {
148 /// Since when the sync request is available.
149 #[allow(dead_code)]
150 pub const REQ__SYNC__SINCE: u32 = 1;
151
152 /// asynchronous roundtrip
153 ///
154 /// The sync request asks the server to emit the 'done' event
155 /// on the returned wl_callback object. Since requests are
156 /// handled in-order and events are delivered in-order, this can
157 /// be used as a barrier to ensure all previous requests and the
158 /// resulting events have been handled.
159 ///
160 /// The object returned by this request will be destroyed by the
161 /// compositor after the callback is fired and as such the client must not
162 /// attempt to use it after that point.
163 ///
164 /// The callback_data passed in the callback is undefined and should be ignored.
165 #[inline]
166 pub fn sync(&self) -> WlCallback {
167 let mut args = [wl_argument { n: 0 }];
168 // SAFETY: - self.proxy has the interface INTERFACE
169 // - 0 < INTERFACE.method_count = 2
170 // - the request signature is `n`
171 // - OwnedProxy::WL_INTERFACE is always a valid interface
172 let data = unsafe {
173 self.proxy
174 .send_constructor::<false>(0, &mut args, WlCallback::WL_INTERFACE, None)
175 };
176 // SAFETY: data has the interface WlCallback::WL_INTERFACE
177 unsafe { proxy::low_level::from_untyped_owned(data) }
178 }
179
180 /// Since when the get_registry request is available.
181 #[allow(dead_code)]
182 pub const REQ__GET_REGISTRY__SINCE: u32 = 1;
183
184 /// get global registry object
185 ///
186 /// This request creates a registry object that allows the client
187 /// to list and bind the global objects available from the
188 /// compositor.
189 ///
190 /// It should be noted that the server side resources consumed in
191 /// response to a get_registry request can only be released when the
192 /// client disconnects, not when the client side proxy is destroyed.
193 /// Therefore, clients should invoke get_registry as infrequently as
194 /// possible to avoid wasting memory.
195 #[inline]
196 pub fn get_registry(&self) -> WlRegistry {
197 let mut args = [wl_argument { n: 0 }];
198 // SAFETY: - self.proxy has the interface INTERFACE
199 // - 1 < INTERFACE.method_count = 2
200 // - the request signature is `n`
201 // - OwnedProxy::WL_INTERFACE is always a valid interface
202 let data = unsafe {
203 self.proxy
204 .send_constructor::<false>(1, &mut args, WlRegistry::WL_INTERFACE, None)
205 };
206 // SAFETY: data has the interface WlRegistry::WL_INTERFACE
207 unsafe { proxy::low_level::from_untyped_owned(data) }
208 }
209}
210
211#[allow(dead_code)]
212impl WlDisplayRef {
213 /// asynchronous roundtrip
214 ///
215 /// The sync request asks the server to emit the 'done' event
216 /// on the returned wl_callback object. Since requests are
217 /// handled in-order and events are delivered in-order, this can
218 /// be used as a barrier to ensure all previous requests and the
219 /// resulting events have been handled.
220 ///
221 /// The object returned by this request will be destroyed by the
222 /// compositor after the callback is fired and as such the client must not
223 /// attempt to use it after that point.
224 ///
225 /// The callback_data passed in the callback is undefined and should be ignored.
226 ///
227 /// # Arguments
228 ///
229 /// - `_queue`: The queue that the returned proxy is assigned to.
230 #[inline]
231 pub fn sync(&self, _queue: &Queue) -> WlCallback {
232 let mut args = [wl_argument { n: 0 }];
233 // SAFETY: - self.proxy has the interface INTERFACE
234 // - 0 < INTERFACE.method_count = 2
235 // - the request signature is `n`
236 // - OwnedProxy::WL_INTERFACE is always a valid interface
237 let data = unsafe {
238 self.proxy
239 .send_constructor(_queue, 0, &mut args, WlCallback::WL_INTERFACE, None)
240 };
241 // SAFETY: data has the interface WlCallback::WL_INTERFACE
242 unsafe { proxy::low_level::from_untyped_owned(data) }
243 }
244
245 /// get global registry object
246 ///
247 /// This request creates a registry object that allows the client
248 /// to list and bind the global objects available from the
249 /// compositor.
250 ///
251 /// It should be noted that the server side resources consumed in
252 /// response to a get_registry request can only be released when the
253 /// client disconnects, not when the client side proxy is destroyed.
254 /// Therefore, clients should invoke get_registry as infrequently as
255 /// possible to avoid wasting memory.
256 ///
257 /// # Arguments
258 ///
259 /// - `_queue`: The queue that the returned proxy is assigned to.
260 #[inline]
261 pub fn get_registry(&self, _queue: &Queue) -> WlRegistry {
262 let mut args = [wl_argument { n: 0 }];
263 // SAFETY: - self.proxy has the interface INTERFACE
264 // - 1 < INTERFACE.method_count = 2
265 // - the request signature is `n`
266 // - OwnedProxy::WL_INTERFACE is always a valid interface
267 let data = unsafe {
268 self.proxy
269 .send_constructor(_queue, 1, &mut args, WlRegistry::WL_INTERFACE, None)
270 };
271 // SAFETY: data has the interface WlRegistry::WL_INTERFACE
272 unsafe { proxy::low_level::from_untyped_owned(data) }
273 }
274}
275
276impl WlDisplay {
277 /// Since when the error event is available.
278 #[allow(dead_code)]
279 pub const EVT__ERROR__SINCE: u32 = 1;
280
281 /// Since when the delete_id event is available.
282 #[allow(dead_code)]
283 pub const EVT__DELETE_ID__SINCE: u32 = 1;
284}
285
286/// An event handler for [WlDisplay] proxies.
287#[allow(dead_code)]
288pub trait WlDisplayEventHandler {
289 type Data: 'static;
290
291 /// fatal error event
292 ///
293 /// The error event is sent out when a fatal (non-recoverable)
294 /// error has occurred. The object_id argument is the object
295 /// where the error occurred, most often in response to a request
296 /// to that object. The code identifies the error and is defined
297 /// by the object interface. As such, each interface defines its
298 /// own set of error codes. The message is a brief description
299 /// of the error, for (debugging) convenience.
300 ///
301 /// # Arguments
302 ///
303 /// - `object_id`: object where the error occurred
304 /// - `code`: error code
305 /// - `message`: error description
306 ///
307 /// All borrowed proxies passed to this function are guaranteed to be
308 /// immutable and non-null.
309 #[inline]
310 fn error(
311 &self,
312 _data: &mut Self::Data,
313 _slf: &WlDisplayRef,
314 object_id: Option<&UntypedBorrowedProxy>,
315 code: u32,
316 message: &str,
317 ) {
318 let _ = object_id;
319 let _ = code;
320 let _ = message;
321 }
322
323 /// acknowledge object ID deletion
324 ///
325 /// This event is used internally by the object ID management
326 /// logic. When a client deletes an object that it had created,
327 /// the server will send this event to acknowledge that it has
328 /// seen the delete request. When the client receives this event,
329 /// it will know that it can safely reuse the object ID.
330 ///
331 /// # Arguments
332 ///
333 /// - `id`: deleted object ID
334 #[inline]
335 fn delete_id(&self, _data: &mut Self::Data, _slf: &WlDisplayRef, id: u32) {
336 let _ = id;
337 }
338}
339
340impl WlDisplayEventHandler for private::NoOpEventHandler {
341 type Data = ();
342}
343
344// SAFETY: - INTERFACE is a valid wl_interface
345// - mutable_type always returns the same value
346unsafe impl<H> EventHandler for private::EventHandler<H>
347where
348 H: WlDisplayEventHandler,
349{
350 const WL_INTERFACE: &'static wl_interface = &INTERFACE;
351
352 #[inline]
353 fn mutable_type() -> Option<(TypeId, &'static str)> {
354 let id = TypeId::of::<H::Data>();
355 let name = std::any::type_name::<H::Data>();
356 Some((id, name))
357 }
358
359 #[allow(unused_variables)]
360 unsafe fn handle_event(
361 &self,
362 queue: &Queue,
363 data: *mut u8,
364 slf: &UntypedBorrowedProxy,
365 opcode: u32,
366 args: *mut wl_argument,
367 ) {
368 // SAFETY: This function requires that slf has the interface INTERFACE
369 let slf = unsafe { proxy::low_level::from_untyped_borrowed::<WlDisplayRef>(slf) };
370 // SAFETY: This function requires that data is `&mut T` where `T`
371 // has the type id returned by `Self::mutable_type`, i.e.,
372 // `T = H::Data`.
373 let data: &mut H::Data = unsafe { &mut *data.cast() };
374 match opcode {
375 0 => {
376 // SAFETY: INTERFACE requires that there are 3 arguments
377 let args = unsafe { &*args.cast::<[wl_argument; 3]>() };
378 // SAFETY: - INTERFACE requires that args[0] contains an object
379 let arg0 = unsafe {
380 if let Some(p) = NonNull::new(args[0].o.cast()) {
381 Some(UntypedBorrowedProxy::new_immutable(queue.libwayland(), p))
382 } else {
383 None
384 }
385 };
386 let arg0 = arg0.as_ref();
387 // SAFETY: - INTERFACE requires that args[1] contains a uint
388 let arg1 = unsafe { args[1].u };
389 // SAFETY: - INTERFACE requires that args[2] contains a string
390 // - if the pointer is not null, then it is a c string
391 let arg2 = unsafe { convert_string_arg("wl_display", "message", args[2].s) };
392 self.0.error(data, slf, arg0, arg1, arg2);
393 }
394 1 => {
395 // SAFETY: INTERFACE requires that there are 1 arguments
396 let args = unsafe { &*args.cast::<[wl_argument; 1]>() };
397 // SAFETY: - INTERFACE requires that args[0] contains a uint
398 let arg0 = unsafe { args[0].u };
399 self.0.delete_id(data, slf, arg0);
400 }
401 _ => {
402 invalid_opcode("wl_display", opcode);
403 }
404 }
405 }
406}
407
408impl<H> CreateEventHandler<H> for private::ProxyApi
409where
410 H: WlDisplayEventHandler,
411{
412 type EventHandler = private::EventHandler<H>;
413
414 #[inline]
415 fn create_event_handler(handler: H) -> Self::EventHandler {
416 private::EventHandler(handler)
417 }
418}
419
420impl WlDisplay {
421 /// Since when the error.invalid_object enum variant is available.
422 #[allow(dead_code)]
423 pub const ENM__ERROR_INVALID_OBJECT__SINCE: u32 = 1;
424 /// Since when the error.invalid_method enum variant is available.
425 #[allow(dead_code)]
426 pub const ENM__ERROR_INVALID_METHOD__SINCE: u32 = 1;
427 /// Since when the error.no_memory enum variant is available.
428 #[allow(dead_code)]
429 pub const ENM__ERROR_NO_MEMORY__SINCE: u32 = 1;
430 /// Since when the error.implementation enum variant is available.
431 #[allow(dead_code)]
432 pub const ENM__ERROR_IMPLEMENTATION__SINCE: u32 = 1;
433}
434
435/// global error values
436///
437/// These errors are global and can be emitted in response to any
438/// server request.
439#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
440#[allow(dead_code)]
441pub struct WlDisplayError(pub u32);
442
443impl WlDisplayError {
444 /// server couldn't find object
445 #[allow(dead_code)]
446 pub const INVALID_OBJECT: Self = Self(0);
447
448 /// method doesn't exist on the specified interface or malformed request
449 #[allow(dead_code)]
450 pub const INVALID_METHOD: Self = Self(1);
451
452 /// server is out of memory
453 #[allow(dead_code)]
454 pub const NO_MEMORY: Self = Self(2);
455
456 /// implementation error in compositor
457 #[allow(dead_code)]
458 pub const IMPLEMENTATION: Self = Self(3);
459}
460
461impl Debug for WlDisplayError {
462 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
463 let name = match *self {
464 Self::INVALID_OBJECT => "INVALID_OBJECT",
465 Self::INVALID_METHOD => "INVALID_METHOD",
466 Self::NO_MEMORY => "NO_MEMORY",
467 Self::IMPLEMENTATION => "IMPLEMENTATION",
468 _ => return Debug::fmt(&self.0, f),
469 };
470 f.write_str(name)
471 }
472}
473
474/// Functional event handlers.
475pub mod event_handlers {
476 use super::*;
477
478 /// Event handler for error events.
479 pub struct Error<T, F>(F, PhantomData<fn(&mut T)>);
480 impl<T, F> WlDisplayEventHandler for Error<T, F>
481 where
482 T: 'static,
483 F: Fn(&mut T, &WlDisplayRef, Option<&UntypedBorrowedProxy>, u32, &str),
484 {
485 type Data = T;
486
487 #[inline]
488 fn error(
489 &self,
490 _data: &mut T,
491 _slf: &WlDisplayRef,
492 object_id: Option<&UntypedBorrowedProxy>,
493 code: u32,
494 message: &str,
495 ) {
496 self.0(_data, _slf, object_id, code, message)
497 }
498 }
499
500 /// Event handler for delete_id events.
501 pub struct DeleteId<T, F>(F, PhantomData<fn(&mut T)>);
502 impl<T, F> WlDisplayEventHandler for DeleteId<T, F>
503 where
504 T: 'static,
505 F: Fn(&mut T, &WlDisplayRef, u32),
506 {
507 type Data = T;
508
509 #[inline]
510 fn delete_id(&self, _data: &mut T, _slf: &WlDisplayRef, id: u32) {
511 self.0(_data, _slf, id)
512 }
513 }
514
515 impl WlDisplay {
516 /// Creates an event handler for error events.
517 ///
518 /// The event handler ignores all other events.
519 #[allow(dead_code)]
520 pub fn on_error<T, F>(f: F) -> Error<T, F>
521 where
522 T: 'static,
523 F: Fn(&mut T, &WlDisplayRef, Option<&UntypedBorrowedProxy>, u32, &str),
524 {
525 Error(f, PhantomData)
526 }
527
528 /// Creates an event handler for delete_id events.
529 ///
530 /// The event handler ignores all other events.
531 #[allow(dead_code)]
532 pub fn on_delete_id<T, F>(f: F) -> DeleteId<T, F>
533 where
534 T: 'static,
535 F: Fn(&mut T, &WlDisplayRef, u32),
536 {
537 DeleteId(f, PhantomData)
538 }
539 }
540}