async_roundtrip/common/protocols/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 /// fatal error event
290 ///
291 /// The error event is sent out when a fatal (non-recoverable)
292 /// error has occurred. The object_id argument is the object
293 /// where the error occurred, most often in response to a request
294 /// to that object. The code identifies the error and is defined
295 /// by the object interface. As such, each interface defines its
296 /// own set of error codes. The message is a brief description
297 /// of the error, for (debugging) convenience.
298 ///
299 /// # Arguments
300 ///
301 /// - `object_id`: object where the error occurred
302 /// - `code`: error code
303 /// - `message`: error description
304 ///
305 /// All borrowed proxies passed to this function are guaranteed to be
306 /// immutable and non-null.
307 #[inline]
308 fn error(
309 &self,
310 _slf: &WlDisplayRef,
311 object_id: Option<&UntypedBorrowedProxy>,
312 code: u32,
313 message: &str,
314 ) {
315 let _ = object_id;
316 let _ = code;
317 let _ = message;
318 }
319
320 /// acknowledge object ID deletion
321 ///
322 /// This event is used internally by the object ID management
323 /// logic. When a client deletes an object that it had created,
324 /// the server will send this event to acknowledge that it has
325 /// seen the delete request. When the client receives this event,
326 /// it will know that it can safely reuse the object ID.
327 ///
328 /// # Arguments
329 ///
330 /// - `id`: deleted object ID
331 #[inline]
332 fn delete_id(&self, _slf: &WlDisplayRef, id: u32) {
333 let _ = id;
334 }
335}
336
337impl WlDisplayEventHandler for private::NoOpEventHandler {}
338
339// SAFETY: - INTERFACE is a valid wl_interface
340unsafe impl<H> EventHandler for private::EventHandler<H>
341where
342 H: WlDisplayEventHandler,
343{
344 const WL_INTERFACE: &'static wl_interface = &INTERFACE;
345
346 #[allow(unused_variables)]
347 unsafe fn handle_event(
348 &self,
349 queue: &Queue,
350 data: *mut u8,
351 slf: &UntypedBorrowedProxy,
352 opcode: u32,
353 args: *mut wl_argument,
354 ) {
355 // SAFETY: This function requires that slf has the interface INTERFACE
356 let slf = unsafe { proxy::low_level::from_untyped_borrowed::<WlDisplayRef>(slf) };
357 match opcode {
358 0 => {
359 // SAFETY: INTERFACE requires that there are 3 arguments
360 let args = unsafe { &*args.cast::<[wl_argument; 3]>() };
361 // SAFETY: - INTERFACE requires that args[0] contains an object
362 let arg0 = unsafe {
363 if let Some(p) = NonNull::new(args[0].o.cast()) {
364 Some(UntypedBorrowedProxy::new_immutable(queue.libwayland(), p))
365 } else {
366 None
367 }
368 };
369 let arg0 = arg0.as_ref();
370 // SAFETY: - INTERFACE requires that args[1] contains a uint
371 let arg1 = unsafe { args[1].u };
372 // SAFETY: - INTERFACE requires that args[2] contains a string
373 // - if the pointer is not null, then it is a c string
374 let arg2 = unsafe { convert_string_arg("wl_display", "message", args[2].s) };
375 self.0.error(slf, arg0, arg1, arg2);
376 }
377 1 => {
378 // SAFETY: INTERFACE requires that there are 1 arguments
379 let args = unsafe { &*args.cast::<[wl_argument; 1]>() };
380 // SAFETY: - INTERFACE requires that args[0] contains a uint
381 let arg0 = unsafe { args[0].u };
382 self.0.delete_id(slf, arg0);
383 }
384 _ => {
385 invalid_opcode("wl_display", opcode);
386 }
387 }
388 }
389}
390
391impl<H> CreateEventHandler<H> for private::ProxyApi
392where
393 H: WlDisplayEventHandler,
394{
395 type EventHandler = private::EventHandler<H>;
396
397 #[inline]
398 fn create_event_handler(handler: H) -> Self::EventHandler {
399 private::EventHandler(handler)
400 }
401}
402
403impl WlDisplay {
404 /// Since when the error.invalid_object enum variant is available.
405 #[allow(dead_code)]
406 pub const ENM__ERROR_INVALID_OBJECT__SINCE: u32 = 1;
407 /// Since when the error.invalid_method enum variant is available.
408 #[allow(dead_code)]
409 pub const ENM__ERROR_INVALID_METHOD__SINCE: u32 = 1;
410 /// Since when the error.no_memory enum variant is available.
411 #[allow(dead_code)]
412 pub const ENM__ERROR_NO_MEMORY__SINCE: u32 = 1;
413 /// Since when the error.implementation enum variant is available.
414 #[allow(dead_code)]
415 pub const ENM__ERROR_IMPLEMENTATION__SINCE: u32 = 1;
416}
417
418/// global error values
419///
420/// These errors are global and can be emitted in response to any
421/// server request.
422#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
423#[allow(dead_code)]
424pub struct WlDisplayError(pub u32);
425
426impl WlDisplayError {
427 /// server couldn't find object
428 #[allow(dead_code)]
429 pub const INVALID_OBJECT: Self = Self(0);
430
431 /// method doesn't exist on the specified interface or malformed request
432 #[allow(dead_code)]
433 pub const INVALID_METHOD: Self = Self(1);
434
435 /// server is out of memory
436 #[allow(dead_code)]
437 pub const NO_MEMORY: Self = Self(2);
438
439 /// implementation error in compositor
440 #[allow(dead_code)]
441 pub const IMPLEMENTATION: Self = Self(3);
442}
443
444impl Debug for WlDisplayError {
445 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
446 let name = match *self {
447 Self::INVALID_OBJECT => "INVALID_OBJECT",
448 Self::INVALID_METHOD => "INVALID_METHOD",
449 Self::NO_MEMORY => "NO_MEMORY",
450 Self::IMPLEMENTATION => "IMPLEMENTATION",
451 _ => return Debug::fmt(&self.0, f),
452 };
453 f.write_str(name)
454 }
455}
456
457/// Functional event handlers.
458pub mod event_handlers {
459 use super::*;
460
461 /// Event handler for error events.
462 pub struct Error<F>(F);
463 impl<F> WlDisplayEventHandler for Error<F>
464 where
465 F: Fn(&WlDisplayRef, Option<&UntypedBorrowedProxy>, u32, &str),
466 {
467 #[inline]
468 fn error(
469 &self,
470 _slf: &WlDisplayRef,
471 object_id: Option<&UntypedBorrowedProxy>,
472 code: u32,
473 message: &str,
474 ) {
475 self.0(_slf, object_id, code, message)
476 }
477 }
478
479 /// Event handler for delete_id events.
480 pub struct DeleteId<F>(F);
481 impl<F> WlDisplayEventHandler for DeleteId<F>
482 where
483 F: Fn(&WlDisplayRef, u32),
484 {
485 #[inline]
486 fn delete_id(&self, _slf: &WlDisplayRef, id: u32) {
487 self.0(_slf, id)
488 }
489 }
490
491 impl WlDisplay {
492 /// Creates an event handler for error events.
493 ///
494 /// The event handler ignores all other events.
495 #[allow(dead_code)]
496 pub fn on_error<F>(f: F) -> Error<F>
497 where
498 F: Fn(&WlDisplayRef, Option<&UntypedBorrowedProxy>, u32, &str),
499 {
500 Error(f)
501 }
502
503 /// Creates an event handler for delete_id events.
504 ///
505 /// The event handler ignores all other events.
506 #[allow(dead_code)]
507 pub fn on_delete_id<F>(f: F) -> DeleteId<F>
508 where
509 F: Fn(&WlDisplayRef, u32),
510 {
511 DeleteId(f)
512 }
513 }
514}