async_roundtrip/common/protocols/wayland/wl_surface.rs
1//! an onscreen surface
2//!
3//! A surface is a rectangular area that may be displayed on zero
4//! or more outputs, and shown any number of times at the compositor's
5//! discretion. They can present wl_buffers, receive user input, and
6//! define a local coordinate system.
7//!
8//! The size of a surface (and relative positions on it) is described
9//! in surface-local coordinates, which may differ from the buffer
10//! coordinates of the pixel content, in case a buffer_transform
11//! or a buffer_scale is used.
12//!
13//! A surface without a "role" is fairly useless: a compositor does
14//! not know where, when or how to present it. The role is the
15//! purpose of a wl_surface. Examples of roles are a cursor for a
16//! pointer (as set by wl_pointer.set_cursor), a drag icon
17//! (wl_data_device.start_drag), a sub-surface
18//! (wl_subcompositor.get_subsurface), and a window as defined by a
19//! shell protocol (e.g. wl_shell.get_shell_surface).
20//!
21//! A surface can have only one role at a time. Initially a
22//! wl_surface does not have a role. Once a wl_surface is given a
23//! role, it is set permanently for the whole lifetime of the
24//! wl_surface object. Giving the current role again is allowed,
25//! unless explicitly forbidden by the relevant interface
26//! specification.
27//!
28//! Surface roles are given by requests in other interfaces such as
29//! wl_pointer.set_cursor. The request should explicitly mention
30//! that this request gives a role to a wl_surface. Often, this
31//! request also creates a new protocol object that represents the
32//! role and adds additional functionality to wl_surface. When a
33//! client wants to destroy a wl_surface, they must destroy this role
34//! object before the wl_surface, otherwise a defunct_role_object error is
35//! sent.
36//!
37//! Destroying the role object does not remove the role from the
38//! wl_surface, but it may stop the wl_surface from "playing the role".
39//! For instance, if a wl_subsurface object is destroyed, the wl_surface
40//! it was created for will be unmapped and forget its position and
41//! z-order. It is allowed to create a wl_subsurface for the same
42//! wl_surface again, but it is not allowed to use the wl_surface as
43//! a cursor (cursor is a different role than sub-surface, and role
44//! switching is not allowed).
45
46use {super::super::all_types::*, ::wl_client::builder::prelude::*};
47
48static INTERFACE: wl_interface = wl_interface {
49 name: c"wl_surface".as_ptr(),
50 version: 6,
51 method_count: 11,
52 methods: {
53 static MESSAGES: [wl_message; 11] = [
54 wl_message {
55 name: c"destroy".as_ptr(),
56 signature: c"".as_ptr(),
57 types: {
58 static TYPES: [Option<&'static wl_interface>; 0] = [];
59 TYPES.as_ptr().cast()
60 },
61 },
62 wl_message {
63 name: c"attach".as_ptr(),
64 signature: c"?oii".as_ptr(),
65 types: {
66 static TYPES: [Option<&'static wl_interface>; 3] =
67 [Some(WlBuffer::WL_INTERFACE), None, None];
68 TYPES.as_ptr().cast()
69 },
70 },
71 wl_message {
72 name: c"damage".as_ptr(),
73 signature: c"iiii".as_ptr(),
74 types: {
75 static TYPES: [Option<&'static wl_interface>; 4] = [None, None, None, None];
76 TYPES.as_ptr().cast()
77 },
78 },
79 wl_message {
80 name: c"frame".as_ptr(),
81 signature: c"n".as_ptr(),
82 types: {
83 static TYPES: [Option<&'static wl_interface>; 1] =
84 [Some(WlCallback::WL_INTERFACE)];
85 TYPES.as_ptr().cast()
86 },
87 },
88 wl_message {
89 name: c"set_opaque_region".as_ptr(),
90 signature: c"?o".as_ptr(),
91 types: {
92 static TYPES: [Option<&'static wl_interface>; 1] =
93 [Some(WlRegion::WL_INTERFACE)];
94 TYPES.as_ptr().cast()
95 },
96 },
97 wl_message {
98 name: c"set_input_region".as_ptr(),
99 signature: c"?o".as_ptr(),
100 types: {
101 static TYPES: [Option<&'static wl_interface>; 1] =
102 [Some(WlRegion::WL_INTERFACE)];
103 TYPES.as_ptr().cast()
104 },
105 },
106 wl_message {
107 name: c"commit".as_ptr(),
108 signature: c"".as_ptr(),
109 types: {
110 static TYPES: [Option<&'static wl_interface>; 0] = [];
111 TYPES.as_ptr().cast()
112 },
113 },
114 wl_message {
115 name: c"set_buffer_transform".as_ptr(),
116 signature: c"i".as_ptr(),
117 types: {
118 static TYPES: [Option<&'static wl_interface>; 1] = [None];
119 TYPES.as_ptr().cast()
120 },
121 },
122 wl_message {
123 name: c"set_buffer_scale".as_ptr(),
124 signature: c"i".as_ptr(),
125 types: {
126 static TYPES: [Option<&'static wl_interface>; 1] = [None];
127 TYPES.as_ptr().cast()
128 },
129 },
130 wl_message {
131 name: c"damage_buffer".as_ptr(),
132 signature: c"iiii".as_ptr(),
133 types: {
134 static TYPES: [Option<&'static wl_interface>; 4] = [None, None, None, None];
135 TYPES.as_ptr().cast()
136 },
137 },
138 wl_message {
139 name: c"offset".as_ptr(),
140 signature: c"ii".as_ptr(),
141 types: {
142 static TYPES: [Option<&'static wl_interface>; 2] = [None, None];
143 TYPES.as_ptr().cast()
144 },
145 },
146 ];
147 MESSAGES.as_ptr()
148 },
149 event_count: 4,
150 events: {
151 static MESSAGES: [wl_message; 4] = [
152 wl_message {
153 name: c"enter".as_ptr(),
154 signature: c"o".as_ptr(),
155 types: {
156 static TYPES: [Option<&'static wl_interface>; 1] =
157 [Some(WlOutput::WL_INTERFACE)];
158 TYPES.as_ptr().cast()
159 },
160 },
161 wl_message {
162 name: c"leave".as_ptr(),
163 signature: c"o".as_ptr(),
164 types: {
165 static TYPES: [Option<&'static wl_interface>; 1] =
166 [Some(WlOutput::WL_INTERFACE)];
167 TYPES.as_ptr().cast()
168 },
169 },
170 wl_message {
171 name: c"preferred_buffer_scale".as_ptr(),
172 signature: c"i".as_ptr(),
173 types: {
174 static TYPES: [Option<&'static wl_interface>; 1] = [None];
175 TYPES.as_ptr().cast()
176 },
177 },
178 wl_message {
179 name: c"preferred_buffer_transform".as_ptr(),
180 signature: c"u".as_ptr(),
181 types: {
182 static TYPES: [Option<&'static wl_interface>; 1] = [None];
183 TYPES.as_ptr().cast()
184 },
185 },
186 ];
187 MESSAGES.as_ptr()
188 },
189};
190
191/// An owned wl_surface proxy.
192///
193/// See the documentation of [the module][self] for the interface description.
194#[derive(Clone, Eq, PartialEq)]
195#[repr(transparent)]
196pub struct WlSurface {
197 /// This proxy has the interface INTERFACE.
198 proxy: UntypedOwnedProxy,
199}
200
201/// A borrowed wl_surface proxy.
202///
203/// See the documentation of [the module][self] for the interface description.
204#[derive(Eq, PartialEq)]
205#[repr(transparent)]
206pub struct WlSurfaceRef {
207 /// This proxy has the interface INTERFACE.
208 proxy: UntypedBorrowedProxy,
209}
210
211// SAFETY: WlSurface is a transparent wrapper around UntypedOwnedProxy
212unsafe impl UntypedOwnedProxyWrapper for WlSurface {}
213
214// SAFETY: - INTERFACE is a valid wl_interface
215// - The only invariant is that self.proxy has a compatible interface
216unsafe impl OwnedProxy for WlSurface {
217 const INTERFACE: &'static str = "wl_surface";
218 const WL_INTERFACE: &'static wl_interface = &INTERFACE;
219 const NO_OP_EVENT_HANDLER: Self::NoOpEventHandler =
220 private::EventHandler(private::NoOpEventHandler);
221 const MAX_VERSION: u32 = 6;
222
223 type Borrowed = WlSurfaceRef;
224 type Api = private::ProxyApi;
225 type NoOpEventHandler = private::EventHandler<private::NoOpEventHandler>;
226}
227
228// SAFETY: WlSurfaceRef is a transparent wrapper around UntypedBorrowedProxy
229unsafe impl UntypedBorrowedProxyWrapper for WlSurfaceRef {}
230
231// SAFETY: - The only invariant is that self.proxy has a compatible interface
232unsafe impl BorrowedProxy for WlSurfaceRef {
233 type Owned = WlSurface;
234}
235
236impl Deref for WlSurface {
237 type Target = WlSurfaceRef;
238
239 fn deref(&self) -> &Self::Target {
240 proxy::low_level::deref(self)
241 }
242}
243
244mod private {
245 pub struct ProxyApi;
246
247 #[allow(dead_code)]
248 pub struct EventHandler<H>(pub(super) H);
249
250 #[allow(dead_code)]
251 pub struct NoOpEventHandler;
252}
253
254impl Debug for WlSurface {
255 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
256 write!(f, "wl_surface#{}", self.proxy.id())
257 }
258}
259
260impl Debug for WlSurfaceRef {
261 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
262 write!(f, "wl_surface#{}", self.proxy.id())
263 }
264}
265
266impl PartialEq<WlSurfaceRef> for WlSurface {
267 fn eq(&self, other: &WlSurfaceRef) -> bool {
268 self.proxy == other.proxy
269 }
270}
271
272impl PartialEq<WlSurface> for WlSurfaceRef {
273 fn eq(&self, other: &WlSurface) -> bool {
274 self.proxy == other.proxy
275 }
276}
277
278#[allow(dead_code)]
279impl WlSurface {
280 /// Since when the destroy request is available.
281 #[allow(dead_code)]
282 pub const REQ__DESTROY__SINCE: u32 = 1;
283
284 /// delete surface
285 ///
286 /// Deletes the surface and invalidates its object ID.
287 #[inline]
288 pub fn destroy(&self) {
289 let mut args = [];
290 // SAFETY: - self.proxy has the interface INTERFACE
291 // - 0 < INTERFACE.method_count = 11
292 // - the request signature is ``
293 unsafe {
294 self.proxy.send_destructor(0, &mut args);
295 }
296 }
297
298 /// Since when the frame request is available.
299 #[allow(dead_code)]
300 pub const REQ__FRAME__SINCE: u32 = 1;
301
302 /// request a frame throttling hint
303 ///
304 /// Request a notification when it is a good time to start drawing a new
305 /// frame, by creating a frame callback. This is useful for throttling
306 /// redrawing operations, and driving animations.
307 ///
308 /// When a client is animating on a wl_surface, it can use the 'frame'
309 /// request to get notified when it is a good time to draw and commit the
310 /// next frame of animation. If the client commits an update earlier than
311 /// that, it is likely that some updates will not make it to the display,
312 /// and the client is wasting resources by drawing too often.
313 ///
314 /// The frame request will take effect on the next wl_surface.commit.
315 /// The notification will only be posted for one frame unless
316 /// requested again. For a wl_surface, the notifications are posted in
317 /// the order the frame requests were committed.
318 ///
319 /// The server must send the notifications so that a client
320 /// will not send excessive updates, while still allowing
321 /// the highest possible update rate for clients that wait for the reply
322 /// before drawing again. The server should give some time for the client
323 /// to draw and commit after sending the frame callback events to let it
324 /// hit the next output refresh.
325 ///
326 /// A server should avoid signaling the frame callbacks if the
327 /// surface is not visible in any way, e.g. the surface is off-screen,
328 /// or completely obscured by other opaque surfaces.
329 ///
330 /// The object returned by this request will be destroyed by the
331 /// compositor after the callback is fired and as such the client must not
332 /// attempt to use it after that point.
333 ///
334 /// The callback_data passed in the callback is the current time, in
335 /// milliseconds, with an undefined base.
336 #[inline]
337 pub fn frame(&self) -> WlCallback {
338 let mut args = [wl_argument { n: 0 }];
339 // SAFETY: - self.proxy has the interface INTERFACE
340 // - 3 < INTERFACE.method_count = 11
341 // - the request signature is `n`
342 // - OwnedProxy::WL_INTERFACE is always a valid interface
343 let data = unsafe {
344 self.proxy
345 .send_constructor::<false>(3, &mut args, WlCallback::WL_INTERFACE, None)
346 };
347 // SAFETY: data has the interface WlCallback::WL_INTERFACE
348 unsafe { proxy::low_level::from_untyped_owned(data) }
349 }
350}
351
352#[allow(dead_code)]
353impl WlSurfaceRef {
354 /// set the surface contents
355 ///
356 /// Set a buffer as the content of this surface.
357 ///
358 /// The new size of the surface is calculated based on the buffer
359 /// size transformed by the inverse buffer_transform and the
360 /// inverse buffer_scale. This means that at commit time the supplied
361 /// buffer size must be an integer multiple of the buffer_scale. If
362 /// that's not the case, an invalid_size error is sent.
363 ///
364 /// The x and y arguments specify the location of the new pending
365 /// buffer's upper left corner, relative to the current buffer's upper
366 /// left corner, in surface-local coordinates. In other words, the
367 /// x and y, combined with the new surface size define in which
368 /// directions the surface's size changes. Setting anything other than 0
369 /// as x and y arguments is discouraged, and should instead be replaced
370 /// with using the separate wl_surface.offset request.
371 ///
372 /// When the bound wl_surface version is 5 or higher, passing any
373 /// non-zero x or y is a protocol violation, and will result in an
374 /// 'invalid_offset' error being raised. The x and y arguments are ignored
375 /// and do not change the pending state. To achieve equivalent semantics,
376 /// use wl_surface.offset.
377 ///
378 /// Surface contents are double-buffered state, see wl_surface.commit.
379 ///
380 /// The initial surface contents are void; there is no content.
381 /// wl_surface.attach assigns the given wl_buffer as the pending
382 /// wl_buffer. wl_surface.commit makes the pending wl_buffer the new
383 /// surface contents, and the size of the surface becomes the size
384 /// calculated from the wl_buffer, as described above. After commit,
385 /// there is no pending buffer until the next attach.
386 ///
387 /// Committing a pending wl_buffer allows the compositor to read the
388 /// pixels in the wl_buffer. The compositor may access the pixels at
389 /// any time after the wl_surface.commit request. When the compositor
390 /// will not access the pixels anymore, it will send the
391 /// wl_buffer.release event. Only after receiving wl_buffer.release,
392 /// the client may reuse the wl_buffer. A wl_buffer that has been
393 /// attached and then replaced by another attach instead of committed
394 /// will not receive a release event, and is not used by the
395 /// compositor.
396 ///
397 /// If a pending wl_buffer has been committed to more than one wl_surface,
398 /// the delivery of wl_buffer.release events becomes undefined. A well
399 /// behaved client should not rely on wl_buffer.release events in this
400 /// case. Alternatively, a client could create multiple wl_buffer objects
401 /// from the same backing storage or use wp_linux_buffer_release.
402 ///
403 /// Destroying the wl_buffer after wl_buffer.release does not change
404 /// the surface contents. Destroying the wl_buffer before wl_buffer.release
405 /// is allowed as long as the underlying buffer storage isn't re-used (this
406 /// can happen e.g. on client process termination). However, if the client
407 /// destroys the wl_buffer before receiving the wl_buffer.release event and
408 /// mutates the underlying buffer storage, the surface contents become
409 /// undefined immediately.
410 ///
411 /// If wl_surface.attach is sent with a NULL wl_buffer, the
412 /// following wl_surface.commit will remove the surface content.
413 ///
414 /// If a pending wl_buffer has been destroyed, the result is not specified.
415 /// Many compositors are known to remove the surface content on the following
416 /// wl_surface.commit, but this behaviour is not universal. Clients seeking to
417 /// maximise compatibility should not destroy pending buffers and should
418 /// ensure that they explicitly remove content from surfaces, even after
419 /// destroying buffers.
420 ///
421 /// # Arguments
422 ///
423 /// - `buffer`: buffer of surface contents
424 /// - `x`: surface-local x coordinate
425 /// - `y`: surface-local y coordinate
426 #[inline]
427 pub fn attach(&self, buffer: Option<&WlBufferRef>, x: i32, y: i32) {
428 let (arg0, arg1, arg2) = (buffer, x, y);
429 let obj0_lock = arg0.map(|arg0| proxy::lock(arg0));
430 let obj0 = obj0_lock
431 .map(|obj0_lock| check_argument_proxy("buffer", obj0_lock.wl_proxy()))
432 .unwrap_or(ptr::null_mut());
433 let mut args = [
434 wl_argument { o: obj0 },
435 wl_argument { i: arg1 },
436 wl_argument { i: arg2 },
437 ];
438 // SAFETY: - self.proxy has the interface INTERFACE
439 // - 1 < INTERFACE.method_count = 11
440 // - the request signature is `?oii`
441 unsafe {
442 self.proxy.send_request(1, &mut args);
443 }
444 }
445
446 /// mark part of the surface damaged
447 ///
448 /// This request is used to describe the regions where the pending
449 /// buffer is different from the current surface contents, and where
450 /// the surface therefore needs to be repainted. The compositor
451 /// ignores the parts of the damage that fall outside of the surface.
452 ///
453 /// Damage is double-buffered state, see wl_surface.commit.
454 ///
455 /// The damage rectangle is specified in surface-local coordinates,
456 /// where x and y specify the upper left corner of the damage rectangle.
457 ///
458 /// The initial value for pending damage is empty: no damage.
459 /// wl_surface.damage adds pending damage: the new pending damage
460 /// is the union of old pending damage and the given rectangle.
461 ///
462 /// wl_surface.commit assigns pending damage as the current damage,
463 /// and clears pending damage. The server will clear the current
464 /// damage as it repaints the surface.
465 ///
466 /// Note! New clients should not use this request. Instead damage can be
467 /// posted with wl_surface.damage_buffer which uses buffer coordinates
468 /// instead of surface coordinates.
469 ///
470 /// # Arguments
471 ///
472 /// - `x`: surface-local x coordinate
473 /// - `y`: surface-local y coordinate
474 /// - `width`: width of damage rectangle
475 /// - `height`: height of damage rectangle
476 #[inline]
477 pub fn damage(&self, x: i32, y: i32, width: i32, height: i32) {
478 let (arg0, arg1, arg2, arg3) = (x, y, width, height);
479 let mut args = [
480 wl_argument { i: arg0 },
481 wl_argument { i: arg1 },
482 wl_argument { i: arg2 },
483 wl_argument { i: arg3 },
484 ];
485 // SAFETY: - self.proxy has the interface INTERFACE
486 // - 2 < INTERFACE.method_count = 11
487 // - the request signature is `iiii`
488 unsafe {
489 self.proxy.send_request(2, &mut args);
490 }
491 }
492
493 /// request a frame throttling hint
494 ///
495 /// Request a notification when it is a good time to start drawing a new
496 /// frame, by creating a frame callback. This is useful for throttling
497 /// redrawing operations, and driving animations.
498 ///
499 /// When a client is animating on a wl_surface, it can use the 'frame'
500 /// request to get notified when it is a good time to draw and commit the
501 /// next frame of animation. If the client commits an update earlier than
502 /// that, it is likely that some updates will not make it to the display,
503 /// and the client is wasting resources by drawing too often.
504 ///
505 /// The frame request will take effect on the next wl_surface.commit.
506 /// The notification will only be posted for one frame unless
507 /// requested again. For a wl_surface, the notifications are posted in
508 /// the order the frame requests were committed.
509 ///
510 /// The server must send the notifications so that a client
511 /// will not send excessive updates, while still allowing
512 /// the highest possible update rate for clients that wait for the reply
513 /// before drawing again. The server should give some time for the client
514 /// to draw and commit after sending the frame callback events to let it
515 /// hit the next output refresh.
516 ///
517 /// A server should avoid signaling the frame callbacks if the
518 /// surface is not visible in any way, e.g. the surface is off-screen,
519 /// or completely obscured by other opaque surfaces.
520 ///
521 /// The object returned by this request will be destroyed by the
522 /// compositor after the callback is fired and as such the client must not
523 /// attempt to use it after that point.
524 ///
525 /// The callback_data passed in the callback is the current time, in
526 /// milliseconds, with an undefined base.
527 ///
528 /// # Arguments
529 ///
530 /// - `_queue`: The queue that the returned proxy is assigned to.
531 #[inline]
532 pub fn frame(&self, _queue: &Queue) -> WlCallback {
533 let mut args = [wl_argument { n: 0 }];
534 // SAFETY: - self.proxy has the interface INTERFACE
535 // - 3 < INTERFACE.method_count = 11
536 // - the request signature is `n`
537 // - OwnedProxy::WL_INTERFACE is always a valid interface
538 let data = unsafe {
539 self.proxy
540 .send_constructor(_queue, 3, &mut args, WlCallback::WL_INTERFACE, None)
541 };
542 // SAFETY: data has the interface WlCallback::WL_INTERFACE
543 unsafe { proxy::low_level::from_untyped_owned(data) }
544 }
545
546 /// set opaque region
547 ///
548 /// This request sets the region of the surface that contains
549 /// opaque content.
550 ///
551 /// The opaque region is an optimization hint for the compositor
552 /// that lets it optimize the redrawing of content behind opaque
553 /// regions. Setting an opaque region is not required for correct
554 /// behaviour, but marking transparent content as opaque will result
555 /// in repaint artifacts.
556 ///
557 /// The opaque region is specified in surface-local coordinates.
558 ///
559 /// The compositor ignores the parts of the opaque region that fall
560 /// outside of the surface.
561 ///
562 /// Opaque region is double-buffered state, see wl_surface.commit.
563 ///
564 /// wl_surface.set_opaque_region changes the pending opaque region.
565 /// wl_surface.commit copies the pending region to the current region.
566 /// Otherwise, the pending and current regions are never changed.
567 ///
568 /// The initial value for an opaque region is empty. Setting the pending
569 /// opaque region has copy semantics, and the wl_region object can be
570 /// destroyed immediately. A NULL wl_region causes the pending opaque
571 /// region to be set to empty.
572 ///
573 /// # Arguments
574 ///
575 /// - `region`: opaque region of the surface
576 #[inline]
577 pub fn set_opaque_region(&self, region: Option<&WlRegionRef>) {
578 let (arg0,) = (region,);
579 let obj0_lock = arg0.map(|arg0| proxy::lock(arg0));
580 let obj0 = obj0_lock
581 .map(|obj0_lock| check_argument_proxy("region", obj0_lock.wl_proxy()))
582 .unwrap_or(ptr::null_mut());
583 let mut args = [wl_argument { o: obj0 }];
584 // SAFETY: - self.proxy has the interface INTERFACE
585 // - 4 < INTERFACE.method_count = 11
586 // - the request signature is `?o`
587 unsafe {
588 self.proxy.send_request(4, &mut args);
589 }
590 }
591
592 /// set input region
593 ///
594 /// This request sets the region of the surface that can receive
595 /// pointer and touch events.
596 ///
597 /// Input events happening outside of this region will try the next
598 /// surface in the server surface stack. The compositor ignores the
599 /// parts of the input region that fall outside of the surface.
600 ///
601 /// The input region is specified in surface-local coordinates.
602 ///
603 /// Input region is double-buffered state, see wl_surface.commit.
604 ///
605 /// wl_surface.set_input_region changes the pending input region.
606 /// wl_surface.commit copies the pending region to the current region.
607 /// Otherwise the pending and current regions are never changed,
608 /// except cursor and icon surfaces are special cases, see
609 /// wl_pointer.set_cursor and wl_data_device.start_drag.
610 ///
611 /// The initial value for an input region is infinite. That means the
612 /// whole surface will accept input. Setting the pending input region
613 /// has copy semantics, and the wl_region object can be destroyed
614 /// immediately. A NULL wl_region causes the input region to be set
615 /// to infinite.
616 ///
617 /// # Arguments
618 ///
619 /// - `region`: input region of the surface
620 #[inline]
621 pub fn set_input_region(&self, region: Option<&WlRegionRef>) {
622 let (arg0,) = (region,);
623 let obj0_lock = arg0.map(|arg0| proxy::lock(arg0));
624 let obj0 = obj0_lock
625 .map(|obj0_lock| check_argument_proxy("region", obj0_lock.wl_proxy()))
626 .unwrap_or(ptr::null_mut());
627 let mut args = [wl_argument { o: obj0 }];
628 // SAFETY: - self.proxy has the interface INTERFACE
629 // - 5 < INTERFACE.method_count = 11
630 // - the request signature is `?o`
631 unsafe {
632 self.proxy.send_request(5, &mut args);
633 }
634 }
635
636 /// commit pending surface state
637 ///
638 /// Surface state (input, opaque, and damage regions, attached buffers,
639 /// etc.) is double-buffered. Protocol requests modify the pending state,
640 /// as opposed to the active state in use by the compositor.
641 ///
642 /// A commit request atomically creates a content update from the pending
643 /// state, even if the pending state has not been touched. The content
644 /// update is placed in a queue until it becomes active. After commit, the
645 /// new pending state is as documented for each related request.
646 ///
647 /// When the content update is applied, the wl_buffer is applied before all
648 /// other state. This means that all coordinates in double-buffered state
649 /// are relative to the newly attached wl_buffers, except for
650 /// wl_surface.attach itself. If there is no newly attached wl_buffer, the
651 /// coordinates are relative to the previous content update.
652 ///
653 /// All requests that need a commit to become effective are documented
654 /// to affect double-buffered state.
655 ///
656 /// Other interfaces may add further double-buffered surface state.
657 #[inline]
658 pub fn commit(&self) {
659 let mut args = [];
660 // SAFETY: - self.proxy has the interface INTERFACE
661 // - 6 < INTERFACE.method_count = 11
662 // - the request signature is ``
663 unsafe {
664 self.proxy.send_request(6, &mut args);
665 }
666 }
667
668 /// sets the buffer transformation
669 ///
670 /// This request sets the transformation that the client has already applied
671 /// to the content of the buffer. The accepted values for the transform
672 /// parameter are the values for wl_output.transform.
673 ///
674 /// The compositor applies the inverse of this transformation whenever it
675 /// uses the buffer contents.
676 ///
677 /// Buffer transform is double-buffered state, see wl_surface.commit.
678 ///
679 /// A newly created surface has its buffer transformation set to normal.
680 ///
681 /// wl_surface.set_buffer_transform changes the pending buffer
682 /// transformation. wl_surface.commit copies the pending buffer
683 /// transformation to the current one. Otherwise, the pending and current
684 /// values are never changed.
685 ///
686 /// The purpose of this request is to allow clients to render content
687 /// according to the output transform, thus permitting the compositor to
688 /// use certain optimizations even if the display is rotated. Using
689 /// hardware overlays and scanning out a client buffer for fullscreen
690 /// surfaces are examples of such optimizations. Those optimizations are
691 /// highly dependent on the compositor implementation, so the use of this
692 /// request should be considered on a case-by-case basis.
693 ///
694 /// Note that if the transform value includes 90 or 270 degree rotation,
695 /// the width of the buffer will become the surface height and the height
696 /// of the buffer will become the surface width.
697 ///
698 /// If transform is not one of the values from the
699 /// wl_output.transform enum the invalid_transform protocol error
700 /// is raised.
701 ///
702 /// # Arguments
703 ///
704 /// - `transform`: transform for interpreting buffer contents
705 #[inline]
706 pub fn set_buffer_transform(&self, transform: WlOutputTransform) {
707 let (arg0,) = (transform,);
708 let mut args = [wl_argument { u: arg0.0 }];
709 // SAFETY: - self.proxy has the interface INTERFACE
710 // - 7 < INTERFACE.method_count = 11
711 // - the request signature is `i`
712 unsafe {
713 self.proxy.send_request(7, &mut args);
714 }
715 }
716
717 /// sets the buffer scaling factor
718 ///
719 /// This request sets an optional scaling factor on how the compositor
720 /// interprets the contents of the buffer attached to the window.
721 ///
722 /// Buffer scale is double-buffered state, see wl_surface.commit.
723 ///
724 /// A newly created surface has its buffer scale set to 1.
725 ///
726 /// wl_surface.set_buffer_scale changes the pending buffer scale.
727 /// wl_surface.commit copies the pending buffer scale to the current one.
728 /// Otherwise, the pending and current values are never changed.
729 ///
730 /// The purpose of this request is to allow clients to supply higher
731 /// resolution buffer data for use on high resolution outputs. It is
732 /// intended that you pick the same buffer scale as the scale of the
733 /// output that the surface is displayed on. This means the compositor
734 /// can avoid scaling when rendering the surface on that output.
735 ///
736 /// Note that if the scale is larger than 1, then you have to attach
737 /// a buffer that is larger (by a factor of scale in each dimension)
738 /// than the desired surface size.
739 ///
740 /// If scale is not greater than 0 the invalid_scale protocol error is
741 /// raised.
742 ///
743 /// # Arguments
744 ///
745 /// - `scale`: scale for interpreting buffer contents
746 #[inline]
747 pub fn set_buffer_scale(&self, scale: i32) {
748 let (arg0,) = (scale,);
749 let mut args = [wl_argument { i: arg0 }];
750 // SAFETY: - self.proxy has the interface INTERFACE
751 // - 8 < INTERFACE.method_count = 11
752 // - the request signature is `i`
753 unsafe {
754 self.proxy.send_request(8, &mut args);
755 }
756 }
757
758 /// mark part of the surface damaged using buffer coordinates
759 ///
760 /// This request is used to describe the regions where the pending
761 /// buffer is different from the current surface contents, and where
762 /// the surface therefore needs to be repainted. The compositor
763 /// ignores the parts of the damage that fall outside of the surface.
764 ///
765 /// Damage is double-buffered state, see wl_surface.commit.
766 ///
767 /// The damage rectangle is specified in buffer coordinates,
768 /// where x and y specify the upper left corner of the damage rectangle.
769 ///
770 /// The initial value for pending damage is empty: no damage.
771 /// wl_surface.damage_buffer adds pending damage: the new pending
772 /// damage is the union of old pending damage and the given rectangle.
773 ///
774 /// wl_surface.commit assigns pending damage as the current damage,
775 /// and clears pending damage. The server will clear the current
776 /// damage as it repaints the surface.
777 ///
778 /// This request differs from wl_surface.damage in only one way - it
779 /// takes damage in buffer coordinates instead of surface-local
780 /// coordinates. While this generally is more intuitive than surface
781 /// coordinates, it is especially desirable when using wp_viewport
782 /// or when a drawing library (like EGL) is unaware of buffer scale
783 /// and buffer transform.
784 ///
785 /// Note: Because buffer transformation changes and damage requests may
786 /// be interleaved in the protocol stream, it is impossible to determine
787 /// the actual mapping between surface and buffer damage until
788 /// wl_surface.commit time. Therefore, compositors wishing to take both
789 /// kinds of damage into account will have to accumulate damage from the
790 /// two requests separately and only transform from one to the other
791 /// after receiving the wl_surface.commit.
792 ///
793 /// # Arguments
794 ///
795 /// - `x`: buffer-local x coordinate
796 /// - `y`: buffer-local y coordinate
797 /// - `width`: width of damage rectangle
798 /// - `height`: height of damage rectangle
799 #[inline]
800 pub fn damage_buffer(&self, x: i32, y: i32, width: i32, height: i32) {
801 let (arg0, arg1, arg2, arg3) = (x, y, width, height);
802 let mut args = [
803 wl_argument { i: arg0 },
804 wl_argument { i: arg1 },
805 wl_argument { i: arg2 },
806 wl_argument { i: arg3 },
807 ];
808 // SAFETY: - self.proxy has the interface INTERFACE
809 // - 9 < INTERFACE.method_count = 11
810 // - the request signature is `iiii`
811 unsafe {
812 self.proxy.send_request(9, &mut args);
813 }
814 }
815
816 /// set the surface contents offset
817 ///
818 /// The x and y arguments specify the location of the new pending
819 /// buffer's upper left corner, relative to the current buffer's upper
820 /// left corner, in surface-local coordinates. In other words, the
821 /// x and y, combined with the new surface size define in which
822 /// directions the surface's size changes.
823 ///
824 /// The exact semantics of wl_surface.offset are role-specific. Refer to
825 /// the documentation of specific roles for more information.
826 ///
827 /// Surface location offset is double-buffered state, see
828 /// wl_surface.commit.
829 ///
830 /// This request is semantically equivalent to and the replaces the x and y
831 /// arguments in the wl_surface.attach request in wl_surface versions prior
832 /// to 5. See wl_surface.attach for details.
833 ///
834 /// # Arguments
835 ///
836 /// - `x`: surface-local x coordinate
837 /// - `y`: surface-local y coordinate
838 #[inline]
839 pub fn offset(&self, x: i32, y: i32) {
840 let (arg0, arg1) = (x, y);
841 let mut args = [wl_argument { i: arg0 }, wl_argument { i: arg1 }];
842 // SAFETY: - self.proxy has the interface INTERFACE
843 // - 10 < INTERFACE.method_count = 11
844 // - the request signature is `ii`
845 unsafe {
846 self.proxy.send_request(10, &mut args);
847 }
848 }
849}
850
851impl WlSurface {
852 /// Since when the enter event is available.
853 #[allow(dead_code)]
854 pub const EVT__ENTER__SINCE: u32 = 1;
855
856 /// Since when the leave event is available.
857 #[allow(dead_code)]
858 pub const EVT__LEAVE__SINCE: u32 = 1;
859
860 /// Since when the preferred_buffer_scale event is available.
861 #[allow(dead_code)]
862 pub const EVT__PREFERRED_BUFFER_SCALE__SINCE: u32 = 6;
863
864 /// Since when the preferred_buffer_transform event is available.
865 #[allow(dead_code)]
866 pub const EVT__PREFERRED_BUFFER_TRANSFORM__SINCE: u32 = 6;
867}
868
869/// An event handler for [WlSurface] proxies.
870#[allow(dead_code)]
871pub trait WlSurfaceEventHandler {
872 /// surface enters an output
873 ///
874 /// This is emitted whenever a surface's creation, movement, or resizing
875 /// results in some part of it being within the scanout region of an
876 /// output.
877 ///
878 /// Note that a surface may be overlapping with zero or more outputs.
879 ///
880 /// # Arguments
881 ///
882 /// - `output`: output entered by the surface
883 ///
884 /// All borrowed proxies passed to this function are guaranteed to be
885 /// immutable and non-null.
886 #[inline]
887 fn enter(&self, _slf: &WlSurfaceRef, output: Option<&WlOutputRef>) {
888 let _ = output;
889 }
890
891 /// surface leaves an output
892 ///
893 /// This is emitted whenever a surface's creation, movement, or resizing
894 /// results in it no longer having any part of it within the scanout region
895 /// of an output.
896 ///
897 /// Clients should not use the number of outputs the surface is on for frame
898 /// throttling purposes. The surface might be hidden even if no leave event
899 /// has been sent, and the compositor might expect new surface content
900 /// updates even if no enter event has been sent. The frame event should be
901 /// used instead.
902 ///
903 /// # Arguments
904 ///
905 /// - `output`: output left by the surface
906 ///
907 /// All borrowed proxies passed to this function are guaranteed to be
908 /// immutable and non-null.
909 #[inline]
910 fn leave(&self, _slf: &WlSurfaceRef, output: Option<&WlOutputRef>) {
911 let _ = output;
912 }
913
914 /// preferred buffer scale for the surface
915 ///
916 /// This event indicates the preferred buffer scale for this surface. It is
917 /// sent whenever the compositor's preference changes.
918 ///
919 /// Before receiving this event the preferred buffer scale for this surface
920 /// is 1.
921 ///
922 /// It is intended that scaling aware clients use this event to scale their
923 /// content and use wl_surface.set_buffer_scale to indicate the scale they
924 /// have rendered with. This allows clients to supply a higher detail
925 /// buffer.
926 ///
927 /// The compositor shall emit a scale value greater than 0.
928 ///
929 /// # Arguments
930 ///
931 /// - `factor`: preferred scaling factor
932 #[inline]
933 fn preferred_buffer_scale(&self, _slf: &WlSurfaceRef, factor: i32) {
934 let _ = factor;
935 }
936
937 /// preferred buffer transform for the surface
938 ///
939 /// This event indicates the preferred buffer transform for this surface.
940 /// It is sent whenever the compositor's preference changes.
941 ///
942 /// Before receiving this event the preferred buffer transform for this
943 /// surface is normal.
944 ///
945 /// Applying this transformation to the surface buffer contents and using
946 /// wl_surface.set_buffer_transform might allow the compositor to use the
947 /// surface buffer more efficiently.
948 ///
949 /// # Arguments
950 ///
951 /// - `transform`: preferred transform
952 #[inline]
953 fn preferred_buffer_transform(&self, _slf: &WlSurfaceRef, transform: WlOutputTransform) {
954 let _ = transform;
955 }
956}
957
958impl WlSurfaceEventHandler for private::NoOpEventHandler {}
959
960// SAFETY: - INTERFACE is a valid wl_interface
961unsafe impl<H> EventHandler for private::EventHandler<H>
962where
963 H: WlSurfaceEventHandler,
964{
965 const WL_INTERFACE: &'static wl_interface = &INTERFACE;
966
967 #[allow(unused_variables)]
968 unsafe fn handle_event(
969 &self,
970 queue: &Queue,
971 data: *mut u8,
972 slf: &UntypedBorrowedProxy,
973 opcode: u32,
974 args: *mut wl_argument,
975 ) {
976 // SAFETY: This function requires that slf has the interface INTERFACE
977 let slf = unsafe { proxy::low_level::from_untyped_borrowed::<WlSurfaceRef>(slf) };
978 match opcode {
979 0 => {
980 // SAFETY: INTERFACE requires that there are 1 arguments
981 let args = unsafe { &*args.cast::<[wl_argument; 1]>() };
982 // SAFETY: - INTERFACE requires that args[0] contains an object
983 let arg0 = unsafe {
984 if let Some(p) = NonNull::new(args[0].o.cast()) {
985 Some(UntypedBorrowedProxy::new_immutable(queue.libwayland(), p))
986 } else {
987 None
988 }
989 };
990 // SAFETY: - INTERFACE requires that the object has the interface WlOutput::WL_INTERFACE
991 let arg0 = arg0.as_ref().map(|arg0| unsafe {
992 proxy::low_level::from_untyped_borrowed::<WlOutputRef>(arg0)
993 });
994 self.0.enter(slf, arg0);
995 }
996 1 => {
997 // SAFETY: INTERFACE requires that there are 1 arguments
998 let args = unsafe { &*args.cast::<[wl_argument; 1]>() };
999 // SAFETY: - INTERFACE requires that args[0] contains an object
1000 let arg0 = unsafe {
1001 if let Some(p) = NonNull::new(args[0].o.cast()) {
1002 Some(UntypedBorrowedProxy::new_immutable(queue.libwayland(), p))
1003 } else {
1004 None
1005 }
1006 };
1007 // SAFETY: - INTERFACE requires that the object has the interface WlOutput::WL_INTERFACE
1008 let arg0 = arg0.as_ref().map(|arg0| unsafe {
1009 proxy::low_level::from_untyped_borrowed::<WlOutputRef>(arg0)
1010 });
1011 self.0.leave(slf, arg0);
1012 }
1013 2 => {
1014 // SAFETY: INTERFACE requires that there are 1 arguments
1015 let args = unsafe { &*args.cast::<[wl_argument; 1]>() };
1016 // SAFETY: - INTERFACE requires that args[0] contains an int
1017 let arg0 = unsafe { args[0].i };
1018 self.0.preferred_buffer_scale(slf, arg0);
1019 }
1020 3 => {
1021 // SAFETY: INTERFACE requires that there are 1 arguments
1022 let args = unsafe { &*args.cast::<[wl_argument; 1]>() };
1023 // SAFETY: - INTERFACE requires that args[0] contains a uint
1024 let arg0 = unsafe { WlOutputTransform(args[0].u) };
1025 self.0.preferred_buffer_transform(slf, arg0);
1026 }
1027 _ => {
1028 invalid_opcode("wl_surface", opcode);
1029 }
1030 }
1031 }
1032}
1033
1034impl<H> CreateEventHandler<H> for private::ProxyApi
1035where
1036 H: WlSurfaceEventHandler,
1037{
1038 type EventHandler = private::EventHandler<H>;
1039
1040 #[inline]
1041 fn create_event_handler(handler: H) -> Self::EventHandler {
1042 private::EventHandler(handler)
1043 }
1044}
1045
1046impl WlSurface {
1047 /// Since when the error.invalid_scale enum variant is available.
1048 #[allow(dead_code)]
1049 pub const ENM__ERROR_INVALID_SCALE__SINCE: u32 = 1;
1050 /// Since when the error.invalid_transform enum variant is available.
1051 #[allow(dead_code)]
1052 pub const ENM__ERROR_INVALID_TRANSFORM__SINCE: u32 = 1;
1053 /// Since when the error.invalid_size enum variant is available.
1054 #[allow(dead_code)]
1055 pub const ENM__ERROR_INVALID_SIZE__SINCE: u32 = 1;
1056 /// Since when the error.invalid_offset enum variant is available.
1057 #[allow(dead_code)]
1058 pub const ENM__ERROR_INVALID_OFFSET__SINCE: u32 = 1;
1059 /// Since when the error.defunct_role_object enum variant is available.
1060 #[allow(dead_code)]
1061 pub const ENM__ERROR_DEFUNCT_ROLE_OBJECT__SINCE: u32 = 1;
1062}
1063
1064/// wl_surface error values
1065///
1066/// These errors can be emitted in response to wl_surface requests.
1067#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
1068#[allow(dead_code)]
1069pub struct WlSurfaceError(pub u32);
1070
1071impl WlSurfaceError {
1072 /// buffer scale value is invalid
1073 #[allow(dead_code)]
1074 pub const INVALID_SCALE: Self = Self(0);
1075
1076 /// buffer transform value is invalid
1077 #[allow(dead_code)]
1078 pub const INVALID_TRANSFORM: Self = Self(1);
1079
1080 /// buffer size is invalid
1081 #[allow(dead_code)]
1082 pub const INVALID_SIZE: Self = Self(2);
1083
1084 /// buffer offset is invalid
1085 #[allow(dead_code)]
1086 pub const INVALID_OFFSET: Self = Self(3);
1087
1088 /// surface was destroyed before its role object
1089 #[allow(dead_code)]
1090 pub const DEFUNCT_ROLE_OBJECT: Self = Self(4);
1091}
1092
1093impl Debug for WlSurfaceError {
1094 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
1095 let name = match *self {
1096 Self::INVALID_SCALE => "INVALID_SCALE",
1097 Self::INVALID_TRANSFORM => "INVALID_TRANSFORM",
1098 Self::INVALID_SIZE => "INVALID_SIZE",
1099 Self::INVALID_OFFSET => "INVALID_OFFSET",
1100 Self::DEFUNCT_ROLE_OBJECT => "DEFUNCT_ROLE_OBJECT",
1101 _ => return Debug::fmt(&self.0, f),
1102 };
1103 f.write_str(name)
1104 }
1105}
1106
1107/// Functional event handlers.
1108pub mod event_handlers {
1109 use super::*;
1110
1111 /// Event handler for enter events.
1112 pub struct Enter<F>(F);
1113 impl<F> WlSurfaceEventHandler for Enter<F>
1114 where
1115 F: Fn(&WlSurfaceRef, Option<&WlOutputRef>),
1116 {
1117 #[inline]
1118 fn enter(&self, _slf: &WlSurfaceRef, output: Option<&WlOutputRef>) {
1119 self.0(_slf, output)
1120 }
1121 }
1122
1123 /// Event handler for leave events.
1124 pub struct Leave<F>(F);
1125 impl<F> WlSurfaceEventHandler for Leave<F>
1126 where
1127 F: Fn(&WlSurfaceRef, Option<&WlOutputRef>),
1128 {
1129 #[inline]
1130 fn leave(&self, _slf: &WlSurfaceRef, output: Option<&WlOutputRef>) {
1131 self.0(_slf, output)
1132 }
1133 }
1134
1135 /// Event handler for preferred_buffer_scale events.
1136 pub struct PreferredBufferScale<F>(F);
1137 impl<F> WlSurfaceEventHandler for PreferredBufferScale<F>
1138 where
1139 F: Fn(&WlSurfaceRef, i32),
1140 {
1141 #[inline]
1142 fn preferred_buffer_scale(&self, _slf: &WlSurfaceRef, factor: i32) {
1143 self.0(_slf, factor)
1144 }
1145 }
1146
1147 /// Event handler for preferred_buffer_transform events.
1148 pub struct PreferredBufferTransform<F>(F);
1149 impl<F> WlSurfaceEventHandler for PreferredBufferTransform<F>
1150 where
1151 F: Fn(&WlSurfaceRef, WlOutputTransform),
1152 {
1153 #[inline]
1154 fn preferred_buffer_transform(&self, _slf: &WlSurfaceRef, transform: WlOutputTransform) {
1155 self.0(_slf, transform)
1156 }
1157 }
1158
1159 impl WlSurface {
1160 /// Creates an event handler for enter events.
1161 ///
1162 /// The event handler ignores all other events.
1163 #[allow(dead_code)]
1164 pub fn on_enter<F>(f: F) -> Enter<F>
1165 where
1166 F: Fn(&WlSurfaceRef, Option<&WlOutputRef>),
1167 {
1168 Enter(f)
1169 }
1170
1171 /// Creates an event handler for leave events.
1172 ///
1173 /// The event handler ignores all other events.
1174 #[allow(dead_code)]
1175 pub fn on_leave<F>(f: F) -> Leave<F>
1176 where
1177 F: Fn(&WlSurfaceRef, Option<&WlOutputRef>),
1178 {
1179 Leave(f)
1180 }
1181
1182 /// Creates an event handler for preferred_buffer_scale events.
1183 ///
1184 /// The event handler ignores all other events.
1185 #[allow(dead_code)]
1186 pub fn on_preferred_buffer_scale<F>(f: F) -> PreferredBufferScale<F>
1187 where
1188 F: Fn(&WlSurfaceRef, i32),
1189 {
1190 PreferredBufferScale(f)
1191 }
1192
1193 /// Creates an event handler for preferred_buffer_transform events.
1194 ///
1195 /// The event handler ignores all other events.
1196 #[allow(dead_code)]
1197 pub fn on_preferred_buffer_transform<F>(f: F) -> PreferredBufferTransform<F>
1198 where
1199 F: Fn(&WlSurfaceRef, WlOutputTransform),
1200 {
1201 PreferredBufferTransform(f)
1202 }
1203 }
1204}