poll_integration/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 slf: &UntypedBorrowedProxy,
351 opcode: u32,
352 args: *mut wl_argument,
353 ) {
354 // SAFETY: This function required that slf has the interface INTERFACE
355 let slf = unsafe { proxy::low_level::from_untyped_borrowed::<WlDisplayRef>(slf) };
356 match opcode {
357 0 => {
358 // SAFETY: INTERFACE requires that there are 3 arguments
359 let args = unsafe { &*args.cast::<[wl_argument; 3]>() };
360 // SAFETY: - INTERFACE requires that args[0] contains an object
361 let arg0 = unsafe {
362 if let Some(p) = NonNull::new(args[0].o.cast()) {
363 Some(UntypedBorrowedProxy::new_immutable(queue.libwayland(), p))
364 } else {
365 None
366 }
367 };
368 let arg0 = arg0.as_ref();
369 // SAFETY: - INTERFACE requires that args[1] contains a uint
370 let arg1 = unsafe { args[1].u };
371 // SAFETY: - INTERFACE requires that args[2] contains a string
372 // - if the pointer is not null, then it is a c string
373 let arg2 = unsafe { convert_string_arg("wl_display", "message", args[2].s) };
374 self.0.error(slf, arg0, arg1, arg2);
375 }
376 1 => {
377 // SAFETY: INTERFACE requires that there are 1 arguments
378 let args = unsafe { &*args.cast::<[wl_argument; 1]>() };
379 // SAFETY: - INTERFACE requires that args[0] contains a uint
380 let arg0 = unsafe { args[0].u };
381 self.0.delete_id(slf, arg0);
382 }
383 _ => {
384 invalid_opcode("wl_display", opcode);
385 }
386 }
387 }
388}
389
390impl<H> CreateEventHandler<H> for private::ProxyApi
391where
392 H: WlDisplayEventHandler,
393{
394 type EventHandler = private::EventHandler<H>;
395
396 #[inline]
397 fn create_event_handler(handler: H) -> Self::EventHandler {
398 private::EventHandler(handler)
399 }
400}
401
402impl WlDisplay {
403 /// Since when the error.invalid_object enum variant is available.
404 #[allow(dead_code)]
405 pub const ENM__ERROR_INVALID_OBJECT__SINCE: u32 = 1;
406 /// Since when the error.invalid_method enum variant is available.
407 #[allow(dead_code)]
408 pub const ENM__ERROR_INVALID_METHOD__SINCE: u32 = 1;
409 /// Since when the error.no_memory enum variant is available.
410 #[allow(dead_code)]
411 pub const ENM__ERROR_NO_MEMORY__SINCE: u32 = 1;
412 /// Since when the error.implementation enum variant is available.
413 #[allow(dead_code)]
414 pub const ENM__ERROR_IMPLEMENTATION__SINCE: u32 = 1;
415}
416
417/// global error values
418///
419/// These errors are global and can be emitted in response to any
420/// server request.
421#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
422#[allow(dead_code)]
423pub struct WlDisplayError(pub u32);
424
425impl WlDisplayError {
426 /// server couldn't find object
427 #[allow(dead_code)]
428 pub const INVALID_OBJECT: Self = Self(0);
429
430 /// method doesn't exist on the specified interface or malformed request
431 #[allow(dead_code)]
432 pub const INVALID_METHOD: Self = Self(1);
433
434 /// server is out of memory
435 #[allow(dead_code)]
436 pub const NO_MEMORY: Self = Self(2);
437
438 /// implementation error in compositor
439 #[allow(dead_code)]
440 pub const IMPLEMENTATION: Self = Self(3);
441}
442
443impl Debug for WlDisplayError {
444 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
445 let name = match *self {
446 Self::INVALID_OBJECT => "INVALID_OBJECT",
447 Self::INVALID_METHOD => "INVALID_METHOD",
448 Self::NO_MEMORY => "NO_MEMORY",
449 Self::IMPLEMENTATION => "IMPLEMENTATION",
450 _ => return Debug::fmt(&self.0, f),
451 };
452 f.write_str(name)
453 }
454}
455
456/// Functional event handlers.
457pub mod event_handlers {
458 use super::*;
459
460 /// Event handler for error events.
461 pub struct Error<F>(F);
462 impl<F> WlDisplayEventHandler for Error<F>
463 where
464 F: Fn(&WlDisplayRef, Option<&UntypedBorrowedProxy>, u32, &str),
465 {
466 #[inline]
467 fn error(
468 &self,
469 _slf: &WlDisplayRef,
470 object_id: Option<&UntypedBorrowedProxy>,
471 code: u32,
472 message: &str,
473 ) {
474 self.0(_slf, object_id, code, message)
475 }
476 }
477
478 /// Event handler for delete_id events.
479 pub struct DeleteId<F>(F);
480 impl<F> WlDisplayEventHandler for DeleteId<F>
481 where
482 F: Fn(&WlDisplayRef, u32),
483 {
484 #[inline]
485 fn delete_id(&self, _slf: &WlDisplayRef, id: u32) {
486 self.0(_slf, id)
487 }
488 }
489
490 impl WlDisplay {
491 /// Creates an event handler for error events.
492 ///
493 /// The event handler ignores all other events.
494 #[allow(dead_code)]
495 pub fn on_error<F>(f: F) -> Error<F>
496 where
497 F: Fn(&WlDisplayRef, Option<&UntypedBorrowedProxy>, u32, &str),
498 {
499 Error(f)
500 }
501
502 /// Creates an event handler for delete_id events.
503 ///
504 /// The event handler ignores all other events.
505 #[allow(dead_code)]
506 pub fn on_delete_id<F>(f: F) -> DeleteId<F>
507 where
508 F: Fn(&WlDisplayRef, u32),
509 {
510 DeleteId(f)
511 }
512 }
513}