1#[allow(clippy::module_inception)]
2pub mod linux_dmabuf_v1 {
3 #[doc = ""]
4 #[doc = "This interface offers ways to create generic dmabuf-based wl_buffers."]
5 #[doc = ""]
6 #[doc = "For more information about dmabuf, see:"]
7 #[doc = "https://www.kernel.org/doc/html/next/userspace-api/dma-buf-alloc-exchange.html"]
8 #[doc = ""]
9 #[doc = "Clients can use the get_surface_feedback request to get dmabuf feedback"]
10 #[doc = "for a particular surface. If the client wants to retrieve feedback not"]
11 #[doc = "tied to a surface, they can use the get_default_feedback request."]
12 #[doc = ""]
13 #[doc = "The following are required from clients:"]
14 #[doc = ""]
15 #[doc = "- Clients must ensure that either all data in the dma-buf is"]
16 #[doc = "coherent for all subsequent read access or that coherency is"]
17 #[doc = "correctly handled by the underlying kernel-side dma-buf"]
18 #[doc = "implementation."]
19 #[doc = ""]
20 #[doc = "- Don't make any more attachments after sending the buffer to the"]
21 #[doc = "compositor. Making more attachments later increases the risk of"]
22 #[doc = "the compositor not being able to use (re-import) an existing"]
23 #[doc = "dmabuf-based wl_buffer."]
24 #[doc = ""]
25 #[doc = "The underlying graphics stack must ensure the following:"]
26 #[doc = ""]
27 #[doc = "- The dmabuf file descriptors relayed to the server will stay valid"]
28 #[doc = "for the whole lifetime of the wl_buffer. This means the server may"]
29 #[doc = "at any time use those fds to import the dmabuf into any kernel"]
30 #[doc = "sub-system that might accept it."]
31 #[doc = ""]
32 #[doc = "However, when the underlying graphics stack fails to deliver the"]
33 #[doc = "promise, because of e.g. a device hot-unplug which raises internal"]
34 #[doc = "errors, after the wl_buffer has been successfully created the"]
35 #[doc = "compositor must not raise protocol errors to the client when dmabuf"]
36 #[doc = "import later fails."]
37 #[doc = ""]
38 #[doc = "To create a wl_buffer from one or more dmabufs, a client creates a"]
39 #[doc = "zwp_linux_dmabuf_params_v1 object with a zwp_linux_dmabuf_v1.create_params"]
40 #[doc = "request. All planes required by the intended format are added with"]
41 #[doc = "the 'add' request. Finally, a 'create' or 'create_immed' request is"]
42 #[doc = "issued, which has the following outcome depending on the import success."]
43 #[doc = ""]
44 #[doc = "The 'create' request,"]
45 #[doc = "- on success, triggers a 'created' event which provides the final"]
46 #[doc = "wl_buffer to the client."]
47 #[doc = "- on failure, triggers a 'failed' event to convey that the server"]
48 #[doc = "cannot use the dmabufs received from the client."]
49 #[doc = ""]
50 #[doc = "For the 'create_immed' request,"]
51 #[doc = "- on success, the server immediately imports the added dmabufs to"]
52 #[doc = "create a wl_buffer. No event is sent from the server in this case."]
53 #[doc = "- on failure, the server can choose to either:"]
54 #[doc = "- terminate the client by raising a fatal error."]
55 #[doc = "- mark the wl_buffer as failed, and send a 'failed' event to the"]
56 #[doc = "client. If the client uses a failed wl_buffer as an argument to any"]
57 #[doc = "request, the behaviour is compositor implementation-defined."]
58 #[doc = ""]
59 #[doc = "For all DRM formats and unless specified in another protocol extension,"]
60 #[doc = "pre-multiplied alpha is used for pixel values."]
61 #[doc = ""]
62 #[doc = "Unless specified otherwise in another protocol extension, implicit"]
63 #[doc = "synchronization is used. In other words, compositors and clients must"]
64 #[doc = "wait and signal fences implicitly passed via the DMA-BUF's reservation"]
65 #[doc = "mechanism."]
66 #[doc = ""]
67 #[allow(clippy::too_many_arguments)]
68 pub mod zwp_linux_dmabuf_v1 {
69 #[allow(unused)]
70 use futures_util::SinkExt;
71 #[allow(unused)]
72 use std::os::fd::AsRawFd;
73 #[doc = "Trait to implement the zwp_linux_dmabuf_v1 interface. See the module level documentation for more info"]
74 pub trait ZwpLinuxDmabufV1: crate::server::Dispatcher {
75 const INTERFACE: &'static str = "zwp_linux_dmabuf_v1";
76 const VERSION: u32 = 5u32;
77 fn handle_request(
78 &self,
79 client: &mut crate::server::Client,
80 sender_id: crate::wire::ObjectId,
81 message: &mut crate::wire::Message,
82 ) -> impl Future<Output = crate::server::Result<()>> + Send {
83 async move {
84 #[allow(clippy::match_single_binding)]
85 match message.opcode() {
86 0u16 => {
87 tracing::debug!("zwp_linux_dmabuf_v1#{}.destroy()", sender_id,);
88 let result = self.destroy(client, sender_id).await;
89 client.remove(sender_id);
90 result
91 }
92 1u16 => {
93 let params_id = message
94 .object()?
95 .ok_or(crate::wire::DecodeError::MalformedPayload)?;
96 tracing::debug!(
97 "zwp_linux_dmabuf_v1#{}.create_params({})",
98 sender_id,
99 params_id
100 );
101 self.create_params(client, sender_id, params_id).await
102 }
103 2u16 => {
104 let id = message
105 .object()?
106 .ok_or(crate::wire::DecodeError::MalformedPayload)?;
107 tracing::debug!(
108 "zwp_linux_dmabuf_v1#{}.get_default_feedback({})",
109 sender_id,
110 id
111 );
112 self.get_default_feedback(client, sender_id, id).await
113 }
114 3u16 => {
115 let id = message
116 .object()?
117 .ok_or(crate::wire::DecodeError::MalformedPayload)?;
118 let surface = message
119 .object()?
120 .ok_or(crate::wire::DecodeError::MalformedPayload)?;
121 tracing::debug!(
122 "zwp_linux_dmabuf_v1#{}.get_surface_feedback({}, {})",
123 sender_id,
124 id,
125 surface
126 );
127 self.get_surface_feedback(client, sender_id, id, surface)
128 .await
129 }
130 opcode => Err(crate::server::error::Error::UnknownOpcode(opcode)),
131 }
132 }
133 }
134 #[doc = ""]
135 #[doc = "Objects created through this interface, especially wl_buffers, will"]
136 #[doc = "remain valid."]
137 #[doc = ""]
138 fn destroy(
139 &self,
140 client: &mut crate::server::Client,
141 sender_id: crate::wire::ObjectId,
142 ) -> impl Future<Output = crate::server::Result<()>> + Send;
143 #[doc = ""]
144 #[doc = "This temporary object is used to collect multiple dmabuf handles into"]
145 #[doc = "a single batch to create a wl_buffer. It can only be used once and"]
146 #[doc = "should be destroyed after a 'created' or 'failed' event has been"]
147 #[doc = "received."]
148 #[doc = ""]
149 fn create_params(
150 &self,
151 client: &mut crate::server::Client,
152 sender_id: crate::wire::ObjectId,
153 params_id: crate::wire::ObjectId,
154 ) -> impl Future<Output = crate::server::Result<()>> + Send;
155 #[doc = ""]
156 #[doc = "This request creates a new wp_linux_dmabuf_feedback object not bound"]
157 #[doc = "to a particular surface. This object will deliver feedback about dmabuf"]
158 #[doc = "parameters to use if the client doesn't support per-surface feedback"]
159 #[doc = "(see get_surface_feedback)."]
160 #[doc = ""]
161 fn get_default_feedback(
162 &self,
163 client: &mut crate::server::Client,
164 sender_id: crate::wire::ObjectId,
165 id: crate::wire::ObjectId,
166 ) -> impl Future<Output = crate::server::Result<()>> + Send;
167 #[doc = ""]
168 #[doc = "This request creates a new wp_linux_dmabuf_feedback object for the"]
169 #[doc = "specified wl_surface. This object will deliver feedback about dmabuf"]
170 #[doc = "parameters to use for buffers attached to this surface."]
171 #[doc = ""]
172 #[doc = "If the surface is destroyed before the wp_linux_dmabuf_feedback object,"]
173 #[doc = "the feedback object becomes inert."]
174 #[doc = ""]
175 fn get_surface_feedback(
176 &self,
177 client: &mut crate::server::Client,
178 sender_id: crate::wire::ObjectId,
179 id: crate::wire::ObjectId,
180 surface: crate::wire::ObjectId,
181 ) -> impl Future<Output = crate::server::Result<()>> + Send;
182 #[doc = ""]
183 #[doc = "This event advertises one buffer format that the server supports."]
184 #[doc = "All the supported formats are advertised once when the client"]
185 #[doc = "binds to this interface. A roundtrip after binding guarantees"]
186 #[doc = "that the client has received all supported formats."]
187 #[doc = ""]
188 #[doc = "For the definition of the format codes, see the"]
189 #[doc = "zwp_linux_buffer_params_v1::create request."]
190 #[doc = ""]
191 #[doc = "Starting version 4, the format event is deprecated and must not be"]
192 #[doc = "sent by compositors. Instead, use get_default_feedback or"]
193 #[doc = "get_surface_feedback."]
194 #[doc = ""]
195 fn format(
196 &self,
197 client: &mut crate::server::Client,
198 sender_id: crate::wire::ObjectId,
199 format: u32,
200 ) -> impl Future<Output = crate::server::Result<()>> + Send {
201 async move {
202 tracing::debug!("-> zwp_linux_dmabuf_v1#{}.format({})", sender_id, format);
203 let (payload, fds) =
204 crate::wire::PayloadBuilder::new().put_uint(format).build();
205 client
206 .send_message(crate::wire::Message::new(sender_id, 0u16, payload, fds))
207 .await
208 .map_err(crate::server::error::Error::IoError)
209 }
210 }
211 #[doc = ""]
212 #[doc = "This event advertises the formats that the server supports, along with"]
213 #[doc = "the modifiers supported for each format. All the supported modifiers"]
214 #[doc = "for all the supported formats are advertised once when the client"]
215 #[doc = "binds to this interface. A roundtrip after binding guarantees that"]
216 #[doc = "the client has received all supported format-modifier pairs."]
217 #[doc = ""]
218 #[doc = "For legacy support, DRM_FORMAT_MOD_INVALID (that is, modifier_hi =="]
219 #[doc = "0x00ffffff and modifier_lo == 0xffffffff) is allowed in this event."]
220 #[doc = "It indicates that the server can support the format with an implicit"]
221 #[doc = "modifier. When a plane has DRM_FORMAT_MOD_INVALID as its modifier, it"]
222 #[doc = "is as if no explicit modifier is specified. The effective modifier"]
223 #[doc = "will be derived from the dmabuf."]
224 #[doc = ""]
225 #[doc = "A compositor that sends valid modifiers and DRM_FORMAT_MOD_INVALID for"]
226 #[doc = "a given format supports both explicit modifiers and implicit modifiers."]
227 #[doc = ""]
228 #[doc = "For the definition of the format and modifier codes, see the"]
229 #[doc = "zwp_linux_buffer_params_v1::create and zwp_linux_buffer_params_v1::add"]
230 #[doc = "requests."]
231 #[doc = ""]
232 #[doc = "Starting version 4, the modifier event is deprecated and must not be"]
233 #[doc = "sent by compositors. Instead, use get_default_feedback or"]
234 #[doc = "get_surface_feedback."]
235 #[doc = ""]
236 fn modifier(
237 &self,
238 client: &mut crate::server::Client,
239 sender_id: crate::wire::ObjectId,
240 format: u32,
241 modifier_hi: u32,
242 modifier_lo: u32,
243 ) -> impl Future<Output = crate::server::Result<()>> + Send {
244 async move {
245 tracing::debug!(
246 "-> zwp_linux_dmabuf_v1#{}.modifier({}, {}, {})",
247 sender_id,
248 format,
249 modifier_hi,
250 modifier_lo
251 );
252 let (payload, fds) = crate::wire::PayloadBuilder::new()
253 .put_uint(format)
254 .put_uint(modifier_hi)
255 .put_uint(modifier_lo)
256 .build();
257 client
258 .send_message(crate::wire::Message::new(sender_id, 1u16, payload, fds))
259 .await
260 .map_err(crate::server::error::Error::IoError)
261 }
262 }
263 }
264 }
265 #[doc = ""]
266 #[doc = "This temporary object is a collection of dmabufs and other"]
267 #[doc = "parameters that together form a single logical buffer. The temporary"]
268 #[doc = "object may eventually create one wl_buffer unless cancelled by"]
269 #[doc = "destroying it before requesting 'create'."]
270 #[doc = ""]
271 #[doc = "Single-planar formats only require one dmabuf, however"]
272 #[doc = "multi-planar formats may require more than one dmabuf. For all"]
273 #[doc = "formats, an 'add' request must be called once per plane (even if the"]
274 #[doc = "underlying dmabuf fd is identical)."]
275 #[doc = ""]
276 #[doc = "You must use consecutive plane indices ('plane_idx' argument for 'add')"]
277 #[doc = "from zero to the number of planes used by the drm_fourcc format code."]
278 #[doc = "All planes required by the format must be given exactly once, but can"]
279 #[doc = "be given in any order. Each plane index can only be set once; subsequent"]
280 #[doc = "calls with a plane index which has already been set will result in a"]
281 #[doc = "plane_set error being generated."]
282 #[doc = ""]
283 #[allow(clippy::too_many_arguments)]
284 pub mod zwp_linux_buffer_params_v1 {
285 #[allow(unused)]
286 use futures_util::SinkExt;
287 #[allow(unused)]
288 use std::os::fd::AsRawFd;
289 #[repr(u32)]
290 #[non_exhaustive]
291 #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy)]
292 pub enum Error {
293 #[doc = "the dmabuf_batch object has already been used to create a wl_buffer"]
294 AlreadyUsed = 0u32,
295 #[doc = "plane index out of bounds"]
296 PlaneIdx = 1u32,
297 #[doc = "the plane index was already set"]
298 PlaneSet = 2u32,
299 #[doc = "missing or too many planes to create a buffer"]
300 Incomplete = 3u32,
301 #[doc = "format not supported"]
302 InvalidFormat = 4u32,
303 #[doc = "invalid width or height"]
304 InvalidDimensions = 5u32,
305 #[doc = "offset + stride * height goes out of dmabuf bounds"]
306 OutOfBounds = 6u32,
307 #[doc = "invalid wl_buffer resulted from importing dmabufs via"]
308 #[doc = "the create_immed request on given buffer_params"]
309 InvalidWlBuffer = 7u32,
310 }
311 impl TryFrom<u32> for Error {
312 type Error = crate::wire::DecodeError;
313 fn try_from(v: u32) -> Result<Self, Self::Error> {
314 match v {
315 0u32 => Ok(Self::AlreadyUsed),
316 1u32 => Ok(Self::PlaneIdx),
317 2u32 => Ok(Self::PlaneSet),
318 3u32 => Ok(Self::Incomplete),
319 4u32 => Ok(Self::InvalidFormat),
320 5u32 => Ok(Self::InvalidDimensions),
321 6u32 => Ok(Self::OutOfBounds),
322 7u32 => Ok(Self::InvalidWlBuffer),
323 _ => Err(crate::wire::DecodeError::MalformedPayload),
324 }
325 }
326 }
327 impl std::fmt::Display for Error {
328 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
329 (*self as u32).fmt(f)
330 }
331 }
332 bitflags::bitflags! { # [derive (Debug , PartialEq , Eq , PartialOrd , Ord , Hash , Clone , Copy)] pub struct Flags : u32 { # [doc = "contents are y-inverted"] const YInvert = 1u32 ; # [doc = "content is interlaced"] const Interlaced = 2u32 ; # [doc = "bottom field first"] const BottomFirst = 4u32 ; } }
333 impl TryFrom<u32> for Flags {
334 type Error = crate::wire::DecodeError;
335 fn try_from(v: u32) -> Result<Self, Self::Error> {
336 Self::from_bits(v).ok_or(crate::wire::DecodeError::MalformedPayload)
337 }
338 }
339 impl std::fmt::Display for Flags {
340 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
341 self.bits().fmt(f)
342 }
343 }
344 #[doc = "Trait to implement the zwp_linux_buffer_params_v1 interface. See the module level documentation for more info"]
345 pub trait ZwpLinuxBufferParamsV1: crate::server::Dispatcher {
346 const INTERFACE: &'static str = "zwp_linux_buffer_params_v1";
347 const VERSION: u32 = 5u32;
348 fn handle_request(
349 &self,
350 client: &mut crate::server::Client,
351 sender_id: crate::wire::ObjectId,
352 message: &mut crate::wire::Message,
353 ) -> impl Future<Output = crate::server::Result<()>> + Send {
354 async move {
355 #[allow(clippy::match_single_binding)]
356 match message.opcode() {
357 0u16 => {
358 tracing::debug!("zwp_linux_buffer_params_v1#{}.destroy()", sender_id,);
359 let result = self.destroy(client, sender_id).await;
360 client.remove(sender_id);
361 result
362 }
363 1u16 => {
364 let fd = message.fd()?;
365 let plane_idx = message.uint()?;
366 let offset = message.uint()?;
367 let stride = message.uint()?;
368 let modifier_hi = message.uint()?;
369 let modifier_lo = message.uint()?;
370 tracing::debug!(
371 "zwp_linux_buffer_params_v1#{}.add({}, {}, {}, {}, {}, {})",
372 sender_id,
373 fd.as_raw_fd(),
374 plane_idx,
375 offset,
376 stride,
377 modifier_hi,
378 modifier_lo
379 );
380 self.add(
381 client,
382 sender_id,
383 fd,
384 plane_idx,
385 offset,
386 stride,
387 modifier_hi,
388 modifier_lo,
389 )
390 .await
391 }
392 2u16 => {
393 let width = message.int()?;
394 let height = message.int()?;
395 let format = message.uint()?;
396 let flags = message.uint()?;
397 tracing::debug!(
398 "zwp_linux_buffer_params_v1#{}.create({}, {}, {}, {})",
399 sender_id,
400 width,
401 height,
402 format,
403 flags
404 );
405 self.create(client, sender_id, width, height, format, flags.try_into()?)
406 .await
407 }
408 3u16 => {
409 let buffer_id = message
410 .object()?
411 .ok_or(crate::wire::DecodeError::MalformedPayload)?;
412 let width = message.int()?;
413 let height = message.int()?;
414 let format = message.uint()?;
415 let flags = message.uint()?;
416 tracing::debug!(
417 "zwp_linux_buffer_params_v1#{}.create_immed({}, {}, {}, {}, {})",
418 sender_id,
419 buffer_id,
420 width,
421 height,
422 format,
423 flags
424 );
425 self.create_immed(
426 client,
427 sender_id,
428 buffer_id,
429 width,
430 height,
431 format,
432 flags.try_into()?,
433 )
434 .await
435 }
436 opcode => Err(crate::server::error::Error::UnknownOpcode(opcode)),
437 }
438 }
439 }
440 #[doc = ""]
441 #[doc = "Cleans up the temporary data sent to the server for dmabuf-based"]
442 #[doc = "wl_buffer creation."]
443 #[doc = ""]
444 fn destroy(
445 &self,
446 client: &mut crate::server::Client,
447 sender_id: crate::wire::ObjectId,
448 ) -> impl Future<Output = crate::server::Result<()>> + Send;
449 #[doc = ""]
450 #[doc = "This request adds one dmabuf to the set in this"]
451 #[doc = "zwp_linux_buffer_params_v1."]
452 #[doc = ""]
453 #[doc = "The 64-bit unsigned value combined from modifier_hi and modifier_lo"]
454 #[doc = "is the dmabuf layout modifier. DRM AddFB2 ioctl calls this the"]
455 #[doc = "fb modifier, which is defined in drm_mode.h of Linux UAPI."]
456 #[doc = "This is an opaque token. Drivers use this token to express tiling,"]
457 #[doc = "compression, etc. driver-specific modifications to the base format"]
458 #[doc = "defined by the DRM fourcc code."]
459 #[doc = ""]
460 #[doc = "Starting from version 4, the invalid_format protocol error is sent if"]
461 #[doc = "the format + modifier pair was not advertised as supported."]
462 #[doc = ""]
463 #[doc = "Starting from version 5, the invalid_format protocol error is sent if"]
464 #[doc = "all planes don't use the same modifier."]
465 #[doc = ""]
466 #[doc = "This request raises the PLANE_IDX error if plane_idx is too large."]
467 #[doc = "The error PLANE_SET is raised if attempting to set a plane that"]
468 #[doc = "was already set."]
469 #[doc = ""]
470 fn add(
471 &self,
472 client: &mut crate::server::Client,
473 sender_id: crate::wire::ObjectId,
474 fd: rustix::fd::OwnedFd,
475 plane_idx: u32,
476 offset: u32,
477 stride: u32,
478 modifier_hi: u32,
479 modifier_lo: u32,
480 ) -> impl Future<Output = crate::server::Result<()>> + Send;
481 #[doc = ""]
482 #[doc = "This asks for creation of a wl_buffer from the added dmabuf"]
483 #[doc = "buffers. The wl_buffer is not created immediately but returned via"]
484 #[doc = "the 'created' event if the dmabuf sharing succeeds. The sharing"]
485 #[doc = "may fail at runtime for reasons a client cannot predict, in"]
486 #[doc = "which case the 'failed' event is triggered."]
487 #[doc = ""]
488 #[doc = "The 'format' argument is a DRM_FORMAT code, as defined by the"]
489 #[doc = "libdrm's drm_fourcc.h. The Linux kernel's DRM sub-system is the"]
490 #[doc = "authoritative source on how the format codes should work."]
491 #[doc = ""]
492 #[doc = "The 'flags' is a bitfield of the flags defined in enum \"flags\"."]
493 #[doc = "'y_invert' means the that the image needs to be y-flipped."]
494 #[doc = ""]
495 #[doc = "Flag 'interlaced' means that the frame in the buffer is not"]
496 #[doc = "progressive as usual, but interlaced. An interlaced buffer as"]
497 #[doc = "supported here must always contain both top and bottom fields."]
498 #[doc = "The top field always begins on the first pixel row. The temporal"]
499 #[doc = "ordering between the two fields is top field first, unless"]
500 #[doc = "'bottom_first' is specified. It is undefined whether 'bottom_first'"]
501 #[doc = "is ignored if 'interlaced' is not set."]
502 #[doc = ""]
503 #[doc = "This protocol does not convey any information about field rate,"]
504 #[doc = "duration, or timing, other than the relative ordering between the"]
505 #[doc = "two fields in one buffer. A compositor may have to estimate the"]
506 #[doc = "intended field rate from the incoming buffer rate. It is undefined"]
507 #[doc = "whether the time of receiving wl_surface.commit with a new buffer"]
508 #[doc = "attached, applying the wl_surface state, wl_surface.frame callback"]
509 #[doc = "trigger, presentation, or any other point in the compositor cycle"]
510 #[doc = "is used to measure the frame or field times. There is no support"]
511 #[doc = "for detecting missed or late frames/fields/buffers either, and"]
512 #[doc = "there is no support whatsoever for cooperating with interlaced"]
513 #[doc = "compositor output."]
514 #[doc = ""]
515 #[doc = "The composited image quality resulting from the use of interlaced"]
516 #[doc = "buffers is explicitly undefined. A compositor may use elaborate"]
517 #[doc = "hardware features or software to deinterlace and create progressive"]
518 #[doc = "output frames from a sequence of interlaced input buffers, or it"]
519 #[doc = "may produce substandard image quality. However, compositors that"]
520 #[doc = "cannot guarantee reasonable image quality in all cases are recommended"]
521 #[doc = "to just reject all interlaced buffers."]
522 #[doc = ""]
523 #[doc = "Any argument errors, including non-positive width or height,"]
524 #[doc = "mismatch between the number of planes and the format, bad"]
525 #[doc = "format, bad offset or stride, may be indicated by fatal protocol"]
526 #[doc = "errors: INCOMPLETE, INVALID_FORMAT, INVALID_DIMENSIONS,"]
527 #[doc = "OUT_OF_BOUNDS."]
528 #[doc = ""]
529 #[doc = "Dmabuf import errors in the server that are not obvious client"]
530 #[doc = "bugs are returned via the 'failed' event as non-fatal. This"]
531 #[doc = "allows attempting dmabuf sharing and falling back in the client"]
532 #[doc = "if it fails."]
533 #[doc = ""]
534 #[doc = "This request can be sent only once in the object's lifetime, after"]
535 #[doc = "which the only legal request is destroy. This object should be"]
536 #[doc = "destroyed after issuing a 'create' request. Attempting to use this"]
537 #[doc = "object after issuing 'create' raises ALREADY_USED protocol error."]
538 #[doc = ""]
539 #[doc = "It is not mandatory to issue 'create'. If a client wants to"]
540 #[doc = "cancel the buffer creation, it can just destroy this object."]
541 #[doc = ""]
542 fn create(
543 &self,
544 client: &mut crate::server::Client,
545 sender_id: crate::wire::ObjectId,
546 width: i32,
547 height: i32,
548 format: u32,
549 flags: Flags,
550 ) -> impl Future<Output = crate::server::Result<()>> + Send;
551 #[doc = ""]
552 #[doc = "This asks for immediate creation of a wl_buffer by importing the"]
553 #[doc = "added dmabufs."]
554 #[doc = ""]
555 #[doc = "In case of import success, no event is sent from the server, and the"]
556 #[doc = "wl_buffer is ready to be used by the client."]
557 #[doc = ""]
558 #[doc = "Upon import failure, either of the following may happen, as seen fit"]
559 #[doc = "by the implementation:"]
560 #[doc = "- the client is terminated with one of the following fatal protocol"]
561 #[doc = "errors:"]
562 #[doc = "- INCOMPLETE, INVALID_FORMAT, INVALID_DIMENSIONS, OUT_OF_BOUNDS,"]
563 #[doc = "in case of argument errors such as mismatch between the number"]
564 #[doc = "of planes and the format, bad format, non-positive width or"]
565 #[doc = "height, or bad offset or stride."]
566 #[doc = "- INVALID_WL_BUFFER, in case the cause for failure is unknown or"]
567 #[doc = "platform specific."]
568 #[doc = "- the server creates an invalid wl_buffer, marks it as failed and"]
569 #[doc = "sends a 'failed' event to the client. The result of using this"]
570 #[doc = "invalid wl_buffer as an argument in any request by the client is"]
571 #[doc = "defined by the compositor implementation."]
572 #[doc = ""]
573 #[doc = "This takes the same arguments as a 'create' request, and obeys the"]
574 #[doc = "same restrictions."]
575 #[doc = ""]
576 fn create_immed(
577 &self,
578 client: &mut crate::server::Client,
579 sender_id: crate::wire::ObjectId,
580 buffer_id: crate::wire::ObjectId,
581 width: i32,
582 height: i32,
583 format: u32,
584 flags: Flags,
585 ) -> impl Future<Output = crate::server::Result<()>> + Send;
586 #[doc = ""]
587 #[doc = "This event indicates that the attempted buffer creation was"]
588 #[doc = "successful. It provides the new wl_buffer referencing the dmabuf(s)."]
589 #[doc = ""]
590 #[doc = "Upon receiving this event, the client should destroy the"]
591 #[doc = "zwp_linux_buffer_params_v1 object."]
592 #[doc = ""]
593 fn created(
594 &self,
595 client: &mut crate::server::Client,
596 sender_id: crate::wire::ObjectId,
597 buffer: crate::wire::ObjectId,
598 ) -> impl Future<Output = crate::server::Result<()>> + Send {
599 async move {
600 tracing::debug!(
601 "-> zwp_linux_buffer_params_v1#{}.created({})",
602 sender_id,
603 buffer
604 );
605 let (payload, fds) = crate::wire::PayloadBuilder::new()
606 .put_object(Some(buffer))
607 .build();
608 client
609 .send_message(crate::wire::Message::new(sender_id, 0u16, payload, fds))
610 .await
611 .map_err(crate::server::error::Error::IoError)
612 }
613 }
614 #[doc = ""]
615 #[doc = "This event indicates that the attempted buffer creation has"]
616 #[doc = "failed. It usually means that one of the dmabuf constraints"]
617 #[doc = "has not been fulfilled."]
618 #[doc = ""]
619 #[doc = "Upon receiving this event, the client should destroy the"]
620 #[doc = "zwp_linux_buffer_params_v1 object."]
621 #[doc = ""]
622 fn failed(
623 &self,
624 client: &mut crate::server::Client,
625 sender_id: crate::wire::ObjectId,
626 ) -> impl Future<Output = crate::server::Result<()>> + Send {
627 async move {
628 tracing::debug!("-> zwp_linux_buffer_params_v1#{}.failed()", sender_id,);
629 let (payload, fds) = crate::wire::PayloadBuilder::new().build();
630 client
631 .send_message(crate::wire::Message::new(sender_id, 1u16, payload, fds))
632 .await
633 .map_err(crate::server::error::Error::IoError)
634 }
635 }
636 }
637 }
638 #[doc = ""]
639 #[doc = "This object advertises dmabuf parameters feedback. This includes the"]
640 #[doc = "preferred devices and the supported formats/modifiers."]
641 #[doc = ""]
642 #[doc = "The parameters are sent once when this object is created and whenever they"]
643 #[doc = "change. The done event is always sent once after all parameters have been"]
644 #[doc = "sent. When a single parameter changes, all parameters are re-sent by the"]
645 #[doc = "compositor."]
646 #[doc = ""]
647 #[doc = "Compositors can re-send the parameters when the current client buffer"]
648 #[doc = "allocations are sub-optimal. Compositors should not re-send the"]
649 #[doc = "parameters if re-allocating the buffers would not result in a more optimal"]
650 #[doc = "configuration. In particular, compositors should avoid sending the exact"]
651 #[doc = "same parameters multiple times in a row."]
652 #[doc = ""]
653 #[doc = "The tranche_target_device and tranche_formats events are grouped by"]
654 #[doc = "tranches of preference. For each tranche, a tranche_target_device, one"]
655 #[doc = "tranche_flags and one or more tranche_formats events are sent, followed"]
656 #[doc = "by a tranche_done event finishing the list. The tranches are sent in"]
657 #[doc = "descending order of preference. All formats and modifiers in the same"]
658 #[doc = "tranche have the same preference."]
659 #[doc = ""]
660 #[doc = "To send parameters, the compositor sends one main_device event, tranches"]
661 #[doc = "(each consisting of one tranche_target_device event, one tranche_flags"]
662 #[doc = "event, tranche_formats events and then a tranche_done event), then one"]
663 #[doc = "done event."]
664 #[doc = ""]
665 #[allow(clippy::too_many_arguments)]
666 pub mod zwp_linux_dmabuf_feedback_v1 {
667 #[allow(unused)]
668 use futures_util::SinkExt;
669 #[allow(unused)]
670 use std::os::fd::AsRawFd;
671 bitflags::bitflags! { # [derive (Debug , PartialEq , Eq , PartialOrd , Ord , Hash , Clone , Copy)] pub struct TrancheFlags : u32 { # [doc = "direct scan-out tranche"] const Scanout = 1u32 ; } }
672 impl TryFrom<u32> for TrancheFlags {
673 type Error = crate::wire::DecodeError;
674 fn try_from(v: u32) -> Result<Self, Self::Error> {
675 Self::from_bits(v).ok_or(crate::wire::DecodeError::MalformedPayload)
676 }
677 }
678 impl std::fmt::Display for TrancheFlags {
679 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
680 self.bits().fmt(f)
681 }
682 }
683 #[doc = "Trait to implement the zwp_linux_dmabuf_feedback_v1 interface. See the module level documentation for more info"]
684 pub trait ZwpLinuxDmabufFeedbackV1: crate::server::Dispatcher {
685 const INTERFACE: &'static str = "zwp_linux_dmabuf_feedback_v1";
686 const VERSION: u32 = 5u32;
687 fn handle_request(
688 &self,
689 client: &mut crate::server::Client,
690 sender_id: crate::wire::ObjectId,
691 message: &mut crate::wire::Message,
692 ) -> impl Future<Output = crate::server::Result<()>> + Send {
693 async move {
694 #[allow(clippy::match_single_binding)]
695 match message.opcode() {
696 0u16 => {
697 tracing::debug!("zwp_linux_dmabuf_feedback_v1#{}.destroy()", sender_id,);
698 let result = self.destroy(client, sender_id).await;
699 client.remove(sender_id);
700 result
701 }
702 opcode => Err(crate::server::error::Error::UnknownOpcode(opcode)),
703 }
704 }
705 }
706 #[doc = ""]
707 #[doc = "Using this request a client can tell the server that it is not going to"]
708 #[doc = "use the wp_linux_dmabuf_feedback object anymore."]
709 #[doc = ""]
710 fn destroy(
711 &self,
712 client: &mut crate::server::Client,
713 sender_id: crate::wire::ObjectId,
714 ) -> impl Future<Output = crate::server::Result<()>> + Send;
715 #[doc = ""]
716 #[doc = "This event is sent after all parameters of a wp_linux_dmabuf_feedback"]
717 #[doc = "object have been sent."]
718 #[doc = ""]
719 #[doc = "This allows changes to the wp_linux_dmabuf_feedback parameters to be"]
720 #[doc = "seen as atomic, even if they happen via multiple events."]
721 #[doc = ""]
722 fn done(
723 &self,
724 client: &mut crate::server::Client,
725 sender_id: crate::wire::ObjectId,
726 ) -> impl Future<Output = crate::server::Result<()>> + Send {
727 async move {
728 tracing::debug!("-> zwp_linux_dmabuf_feedback_v1#{}.done()", sender_id,);
729 let (payload, fds) = crate::wire::PayloadBuilder::new().build();
730 client
731 .send_message(crate::wire::Message::new(sender_id, 0u16, payload, fds))
732 .await
733 .map_err(crate::server::error::Error::IoError)
734 }
735 }
736 #[doc = ""]
737 #[doc = "This event provides a file descriptor which can be memory-mapped to"]
738 #[doc = "access the format and modifier table."]
739 #[doc = ""]
740 #[doc = "The table contains a tightly packed array of consecutive format +"]
741 #[doc = "modifier pairs. Each pair is 16 bytes wide. It contains a format as a"]
742 #[doc = "32-bit unsigned integer, followed by 4 bytes of unused padding, and a"]
743 #[doc = "modifier as a 64-bit unsigned integer. The native endianness is used."]
744 #[doc = ""]
745 #[doc = "The client must map the file descriptor in read-only private mode."]
746 #[doc = ""]
747 #[doc = "Compositors are not allowed to mutate the table file contents once this"]
748 #[doc = "event has been sent. Instead, compositors must create a new, separate"]
749 #[doc = "table file and re-send feedback parameters. Compositors are allowed to"]
750 #[doc = "store duplicate format + modifier pairs in the table."]
751 #[doc = ""]
752 fn format_table(
753 &self,
754 client: &mut crate::server::Client,
755 sender_id: crate::wire::ObjectId,
756 fd: rustix::fd::OwnedFd,
757 size: u32,
758 ) -> impl Future<Output = crate::server::Result<()>> + Send {
759 async move {
760 tracing::debug!(
761 "-> zwp_linux_dmabuf_feedback_v1#{}.format_table({}, {})",
762 sender_id,
763 fd.as_raw_fd(),
764 size
765 );
766 let (payload, fds) = crate::wire::PayloadBuilder::new()
767 .put_fd(fd)
768 .put_uint(size)
769 .build();
770 client
771 .send_message(crate::wire::Message::new(sender_id, 1u16, payload, fds))
772 .await
773 .map_err(crate::server::error::Error::IoError)
774 }
775 }
776 #[doc = ""]
777 #[doc = "This event advertises the main device that the server prefers to use"]
778 #[doc = "when direct scan-out to the target device isn't possible. The"]
779 #[doc = "advertised main device may be different for each"]
780 #[doc = "wp_linux_dmabuf_feedback object, and may change over time."]
781 #[doc = ""]
782 #[doc = "There is exactly one main device. The compositor must send at least"]
783 #[doc = "one preference tranche with tranche_target_device equal to main_device."]
784 #[doc = ""]
785 #[doc = "Clients need to create buffers that the main device can import and"]
786 #[doc = "read from, otherwise creating the dmabuf wl_buffer will fail (see the"]
787 #[doc = "wp_linux_buffer_params.create and create_immed requests for details)."]
788 #[doc = "The main device will also likely be kept active by the compositor,"]
789 #[doc = "so clients can use it instead of waking up another device for power"]
790 #[doc = "savings."]
791 #[doc = ""]
792 #[doc = "In general the device is a DRM node. The DRM node type (primary vs."]
793 #[doc = "render) is unspecified. Clients must not rely on the compositor sending"]
794 #[doc = "a particular node type. Clients cannot check two devices for equality"]
795 #[doc = "by comparing the dev_t value."]
796 #[doc = ""]
797 #[doc = "If explicit modifiers are not supported and the client performs buffer"]
798 #[doc = "allocations on a different device than the main device, then the client"]
799 #[doc = "must force the buffer to have a linear layout."]
800 #[doc = ""]
801 fn main_device(
802 &self,
803 client: &mut crate::server::Client,
804 sender_id: crate::wire::ObjectId,
805 device: Vec<u8>,
806 ) -> impl Future<Output = crate::server::Result<()>> + Send {
807 async move {
808 tracing::debug!(
809 "-> zwp_linux_dmabuf_feedback_v1#{}.main_device(array[{}])",
810 sender_id,
811 device.len()
812 );
813 let (payload, fds) =
814 crate::wire::PayloadBuilder::new().put_array(device).build();
815 client
816 .send_message(crate::wire::Message::new(sender_id, 2u16, payload, fds))
817 .await
818 .map_err(crate::server::error::Error::IoError)
819 }
820 }
821 #[doc = ""]
822 #[doc = "This event splits tranche_target_device and tranche_formats events in"]
823 #[doc = "preference tranches. It is sent after a set of tranche_target_device"]
824 #[doc = "and tranche_formats events; it represents the end of a tranche. The"]
825 #[doc = "next tranche will have a lower preference."]
826 #[doc = ""]
827 fn tranche_done(
828 &self,
829 client: &mut crate::server::Client,
830 sender_id: crate::wire::ObjectId,
831 ) -> impl Future<Output = crate::server::Result<()>> + Send {
832 async move {
833 tracing::debug!(
834 "-> zwp_linux_dmabuf_feedback_v1#{}.tranche_done()",
835 sender_id,
836 );
837 let (payload, fds) = crate::wire::PayloadBuilder::new().build();
838 client
839 .send_message(crate::wire::Message::new(sender_id, 3u16, payload, fds))
840 .await
841 .map_err(crate::server::error::Error::IoError)
842 }
843 }
844 #[doc = ""]
845 #[doc = "This event advertises the target device that the server prefers to use"]
846 #[doc = "for a buffer created given this tranche. The advertised target device"]
847 #[doc = "may be different for each preference tranche, and may change over time."]
848 #[doc = ""]
849 #[doc = "There is exactly one target device per tranche."]
850 #[doc = ""]
851 #[doc = "The target device may be a scan-out device, for example if the"]
852 #[doc = "compositor prefers to directly scan-out a buffer created given this"]
853 #[doc = "tranche. The target device may be a rendering device, for example if"]
854 #[doc = "the compositor prefers to texture from said buffer."]
855 #[doc = ""]
856 #[doc = "The client can use this hint to allocate the buffer in a way that makes"]
857 #[doc = "it accessible from the target device, ideally directly. The buffer must"]
858 #[doc = "still be accessible from the main device, either through direct import"]
859 #[doc = "or through a potentially more expensive fallback path. If the buffer"]
860 #[doc = "can't be directly imported from the main device then clients must be"]
861 #[doc = "prepared for the compositor changing the tranche priority or making"]
862 #[doc = "wl_buffer creation fail (see the wp_linux_buffer_params.create and"]
863 #[doc = "create_immed requests for details)."]
864 #[doc = ""]
865 #[doc = "If the device is a DRM node, the DRM node type (primary vs. render) is"]
866 #[doc = "unspecified. Clients must not rely on the compositor sending a"]
867 #[doc = "particular node type. Clients cannot check two devices for equality by"]
868 #[doc = "comparing the dev_t value."]
869 #[doc = ""]
870 #[doc = "This event is tied to a preference tranche, see the tranche_done event."]
871 #[doc = ""]
872 fn tranche_target_device(
873 &self,
874 client: &mut crate::server::Client,
875 sender_id: crate::wire::ObjectId,
876 device: Vec<u8>,
877 ) -> impl Future<Output = crate::server::Result<()>> + Send {
878 async move {
879 tracing::debug!(
880 "-> zwp_linux_dmabuf_feedback_v1#{}.tranche_target_device(array[{}])",
881 sender_id,
882 device.len()
883 );
884 let (payload, fds) =
885 crate::wire::PayloadBuilder::new().put_array(device).build();
886 client
887 .send_message(crate::wire::Message::new(sender_id, 4u16, payload, fds))
888 .await
889 .map_err(crate::server::error::Error::IoError)
890 }
891 }
892 #[doc = ""]
893 #[doc = "This event advertises the format + modifier combinations that the"]
894 #[doc = "compositor supports."]
895 #[doc = ""]
896 #[doc = "It carries an array of indices, each referring to a format + modifier"]
897 #[doc = "pair in the last received format table (see the format_table event)."]
898 #[doc = "Each index is a 16-bit unsigned integer in native endianness."]
899 #[doc = ""]
900 #[doc = "For legacy support, DRM_FORMAT_MOD_INVALID is an allowed modifier."]
901 #[doc = "It indicates that the server can support the format with an implicit"]
902 #[doc = "modifier. When a buffer has DRM_FORMAT_MOD_INVALID as its modifier, it"]
903 #[doc = "is as if no explicit modifier is specified. The effective modifier"]
904 #[doc = "will be derived from the dmabuf."]
905 #[doc = ""]
906 #[doc = "A compositor that sends valid modifiers and DRM_FORMAT_MOD_INVALID for"]
907 #[doc = "a given format supports both explicit modifiers and implicit modifiers."]
908 #[doc = ""]
909 #[doc = "Compositors must not send duplicate format + modifier pairs within the"]
910 #[doc = "same tranche or across two different tranches with the same target"]
911 #[doc = "device and flags."]
912 #[doc = ""]
913 #[doc = "This event is tied to a preference tranche, see the tranche_done event."]
914 #[doc = ""]
915 #[doc = "For the definition of the format and modifier codes, see the"]
916 #[doc = "wp_linux_buffer_params.create request."]
917 #[doc = ""]
918 fn tranche_formats(
919 &self,
920 client: &mut crate::server::Client,
921 sender_id: crate::wire::ObjectId,
922 indices: Vec<u8>,
923 ) -> impl Future<Output = crate::server::Result<()>> + Send {
924 async move {
925 tracing::debug!(
926 "-> zwp_linux_dmabuf_feedback_v1#{}.tranche_formats(array[{}])",
927 sender_id,
928 indices.len()
929 );
930 let (payload, fds) = crate::wire::PayloadBuilder::new()
931 .put_array(indices)
932 .build();
933 client
934 .send_message(crate::wire::Message::new(sender_id, 5u16, payload, fds))
935 .await
936 .map_err(crate::server::error::Error::IoError)
937 }
938 }
939 #[doc = ""]
940 #[doc = "This event sets tranche-specific flags."]
941 #[doc = ""]
942 #[doc = "The scanout flag is a hint that direct scan-out may be attempted by the"]
943 #[doc = "compositor on the target device if the client appropriately allocates a"]
944 #[doc = "buffer. How to allocate a buffer that can be scanned out on the target"]
945 #[doc = "device is implementation-defined."]
946 #[doc = ""]
947 #[doc = "This event is tied to a preference tranche, see the tranche_done event."]
948 #[doc = ""]
949 fn tranche_flags(
950 &self,
951 client: &mut crate::server::Client,
952 sender_id: crate::wire::ObjectId,
953 flags: TrancheFlags,
954 ) -> impl Future<Output = crate::server::Result<()>> + Send {
955 async move {
956 tracing::debug!(
957 "-> zwp_linux_dmabuf_feedback_v1#{}.tranche_flags({})",
958 sender_id,
959 flags
960 );
961 let (payload, fds) = crate::wire::PayloadBuilder::new()
962 .put_uint(flags.bits())
963 .build();
964 client
965 .send_message(crate::wire::Message::new(sender_id, 6u16, payload, fds))
966 .await
967 .map_err(crate::server::error::Error::IoError)
968 }
969 }
970 }
971 }
972}
973#[allow(clippy::module_inception)]
974pub mod presentation_time {
975 #[doc = ""]
976 #[doc = ""]
977 #[doc = ""]
978 #[doc = ""]
979 #[doc = "The main feature of this interface is accurate presentation"]
980 #[doc = "timing feedback to ensure smooth video playback while maintaining"]
981 #[doc = "audio/video synchronization. Some features use the concept of a"]
982 #[doc = "presentation clock, which is defined in the"]
983 #[doc = "presentation.clock_id event."]
984 #[doc = ""]
985 #[doc = "A content update for a wl_surface is submitted by a"]
986 #[doc = "wl_surface.commit request. Request 'feedback' associates with"]
987 #[doc = "the wl_surface.commit and provides feedback on the content"]
988 #[doc = "update, particularly the final realized presentation time."]
989 #[doc = ""]
990 #[doc = ""]
991 #[doc = ""]
992 #[doc = "When the final realized presentation time is available, e.g."]
993 #[doc = "after a framebuffer flip completes, the requested"]
994 #[doc = "presentation_feedback.presented events are sent. The final"]
995 #[doc = "presentation time can differ from the compositor's predicted"]
996 #[doc = "display update time and the update's target time, especially"]
997 #[doc = "when the compositor misses its target vertical blanking period."]
998 #[doc = ""]
999 #[allow(clippy::too_many_arguments)]
1000 pub mod wp_presentation {
1001 #[allow(unused)]
1002 use futures_util::SinkExt;
1003 #[allow(unused)]
1004 use std::os::fd::AsRawFd;
1005 #[doc = ""]
1006 #[doc = "These fatal protocol errors may be emitted in response to"]
1007 #[doc = "illegal presentation requests."]
1008 #[doc = ""]
1009 #[repr(u32)]
1010 #[non_exhaustive]
1011 #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy)]
1012 pub enum Error {
1013 #[doc = "invalid value in tv_nsec"]
1014 InvalidTimestamp = 0u32,
1015 #[doc = "invalid flag"]
1016 InvalidFlag = 1u32,
1017 }
1018 impl TryFrom<u32> for Error {
1019 type Error = crate::wire::DecodeError;
1020 fn try_from(v: u32) -> Result<Self, Self::Error> {
1021 match v {
1022 0u32 => Ok(Self::InvalidTimestamp),
1023 1u32 => Ok(Self::InvalidFlag),
1024 _ => Err(crate::wire::DecodeError::MalformedPayload),
1025 }
1026 }
1027 }
1028 impl std::fmt::Display for Error {
1029 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1030 (*self as u32).fmt(f)
1031 }
1032 }
1033 #[doc = "Trait to implement the wp_presentation interface. See the module level documentation for more info"]
1034 pub trait WpPresentation: crate::server::Dispatcher {
1035 const INTERFACE: &'static str = "wp_presentation";
1036 const VERSION: u32 = 2u32;
1037 fn handle_request(
1038 &self,
1039 client: &mut crate::server::Client,
1040 sender_id: crate::wire::ObjectId,
1041 message: &mut crate::wire::Message,
1042 ) -> impl Future<Output = crate::server::Result<()>> + Send {
1043 async move {
1044 #[allow(clippy::match_single_binding)]
1045 match message.opcode() {
1046 0u16 => {
1047 tracing::debug!("wp_presentation#{}.destroy()", sender_id,);
1048 let result = self.destroy(client, sender_id).await;
1049 client.remove(sender_id);
1050 result
1051 }
1052 1u16 => {
1053 let surface = message
1054 .object()?
1055 .ok_or(crate::wire::DecodeError::MalformedPayload)?;
1056 let callback = message
1057 .object()?
1058 .ok_or(crate::wire::DecodeError::MalformedPayload)?;
1059 tracing::debug!(
1060 "wp_presentation#{}.feedback({}, {})",
1061 sender_id,
1062 surface,
1063 callback
1064 );
1065 self.feedback(client, sender_id, surface, callback).await
1066 }
1067 opcode => Err(crate::server::error::Error::UnknownOpcode(opcode)),
1068 }
1069 }
1070 }
1071 #[doc = ""]
1072 #[doc = "Informs the server that the client will no longer be using"]
1073 #[doc = "this protocol object. Existing objects created by this object"]
1074 #[doc = "are not affected."]
1075 #[doc = ""]
1076 fn destroy(
1077 &self,
1078 client: &mut crate::server::Client,
1079 sender_id: crate::wire::ObjectId,
1080 ) -> impl Future<Output = crate::server::Result<()>> + Send;
1081 #[doc = ""]
1082 #[doc = "Request presentation feedback for the current content submission"]
1083 #[doc = "on the given surface. This creates a new presentation_feedback"]
1084 #[doc = "object, which will deliver the feedback information once. If"]
1085 #[doc = "multiple presentation_feedback objects are created for the same"]
1086 #[doc = "submission, they will all deliver the same information."]
1087 #[doc = ""]
1088 #[doc = "For details on what information is returned, see the"]
1089 #[doc = "presentation_feedback interface."]
1090 #[doc = ""]
1091 fn feedback(
1092 &self,
1093 client: &mut crate::server::Client,
1094 sender_id: crate::wire::ObjectId,
1095 surface: crate::wire::ObjectId,
1096 callback: crate::wire::ObjectId,
1097 ) -> impl Future<Output = crate::server::Result<()>> + Send;
1098 #[doc = ""]
1099 #[doc = "This event tells the client in which clock domain the"]
1100 #[doc = "compositor interprets the timestamps used by the presentation"]
1101 #[doc = "extension. This clock is called the presentation clock."]
1102 #[doc = ""]
1103 #[doc = "The compositor sends this event when the client binds to the"]
1104 #[doc = "presentation interface. The presentation clock does not change"]
1105 #[doc = "during the lifetime of the client connection."]
1106 #[doc = ""]
1107 #[doc = "The clock identifier is platform dependent. On POSIX platforms, the"]
1108 #[doc = "identifier value is one of the clockid_t values accepted by"]
1109 #[doc = "clock_gettime(). clock_gettime() is defined by POSIX.1-2001."]
1110 #[doc = ""]
1111 #[doc = "Timestamps in this clock domain are expressed as tv_sec_hi,"]
1112 #[doc = "tv_sec_lo, tv_nsec triples, each component being an unsigned"]
1113 #[doc = "32-bit value. Whole seconds are in tv_sec which is a 64-bit"]
1114 #[doc = "value combined from tv_sec_hi and tv_sec_lo, and the"]
1115 #[doc = "additional fractional part in tv_nsec as nanoseconds. Hence,"]
1116 #[doc = "for valid timestamps tv_nsec must be in [0, 999999999]."]
1117 #[doc = ""]
1118 #[doc = "Note that clock_id applies only to the presentation clock,"]
1119 #[doc = "and implies nothing about e.g. the timestamps used in the"]
1120 #[doc = "Wayland core protocol input events."]
1121 #[doc = ""]
1122 #[doc = "Compositors should prefer a clock which does not jump and is"]
1123 #[doc = "not slewed e.g. by NTP. The absolute value of the clock is"]
1124 #[doc = "irrelevant. Precision of one millisecond or better is"]
1125 #[doc = "recommended. Clients must be able to query the current clock"]
1126 #[doc = "value directly, not by asking the compositor."]
1127 #[doc = ""]
1128 fn clock_id(
1129 &self,
1130 client: &mut crate::server::Client,
1131 sender_id: crate::wire::ObjectId,
1132 clk_id: u32,
1133 ) -> impl Future<Output = crate::server::Result<()>> + Send {
1134 async move {
1135 tracing::debug!("-> wp_presentation#{}.clock_id({})", sender_id, clk_id);
1136 let (payload, fds) =
1137 crate::wire::PayloadBuilder::new().put_uint(clk_id).build();
1138 client
1139 .send_message(crate::wire::Message::new(sender_id, 0u16, payload, fds))
1140 .await
1141 .map_err(crate::server::error::Error::IoError)
1142 }
1143 }
1144 }
1145 }
1146 #[doc = ""]
1147 #[doc = "A presentation_feedback object returns an indication that a"]
1148 #[doc = "wl_surface content update has become visible to the user."]
1149 #[doc = "One object corresponds to one content update submission"]
1150 #[doc = "(wl_surface.commit). There are two possible outcomes: the"]
1151 #[doc = "content update is presented to the user, and a presentation"]
1152 #[doc = "timestamp delivered; or, the user did not see the content"]
1153 #[doc = "update because it was superseded or its surface destroyed,"]
1154 #[doc = "and the content update is discarded."]
1155 #[doc = ""]
1156 #[doc = "Once a presentation_feedback object has delivered a 'presented'"]
1157 #[doc = "or 'discarded' event it is automatically destroyed."]
1158 #[doc = ""]
1159 #[allow(clippy::too_many_arguments)]
1160 pub mod wp_presentation_feedback {
1161 #[allow(unused)]
1162 use futures_util::SinkExt;
1163 #[allow(unused)]
1164 use std::os::fd::AsRawFd;
1165 bitflags::bitflags! { # [doc = ""] # [doc = "These flags provide information about how the presentation of"] # [doc = "the related content update was done. The intent is to help"] # [doc = "clients assess the reliability of the feedback and the visual"] # [doc = "quality with respect to possible tearing and timings."] # [doc = ""] # [derive (Debug , PartialEq , Eq , PartialOrd , Ord , Hash , Clone , Copy)] pub struct Kind : u32 { const Vsync = 1u32 ; const HwClock = 2u32 ; const HwCompletion = 4u32 ; const ZeroCopy = 8u32 ; } }
1166 impl TryFrom<u32> for Kind {
1167 type Error = crate::wire::DecodeError;
1168 fn try_from(v: u32) -> Result<Self, Self::Error> {
1169 Self::from_bits(v).ok_or(crate::wire::DecodeError::MalformedPayload)
1170 }
1171 }
1172 impl std::fmt::Display for Kind {
1173 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1174 self.bits().fmt(f)
1175 }
1176 }
1177 #[doc = "Trait to implement the wp_presentation_feedback interface. See the module level documentation for more info"]
1178 pub trait WpPresentationFeedback: crate::server::Dispatcher {
1179 const INTERFACE: &'static str = "wp_presentation_feedback";
1180 const VERSION: u32 = 2u32;
1181 fn handle_request(
1182 &self,
1183 _client: &mut crate::server::Client,
1184 _sender_id: crate::wire::ObjectId,
1185 message: &mut crate::wire::Message,
1186 ) -> impl Future<Output = crate::server::Result<()>> + Send {
1187 async move {
1188 #[allow(clippy::match_single_binding)]
1189 match message.opcode() {
1190 opcode => Err(crate::server::error::Error::UnknownOpcode(opcode)),
1191 }
1192 }
1193 }
1194 #[doc = ""]
1195 #[doc = "As presentation can be synchronized to only one output at a"]
1196 #[doc = "time, this event tells which output it was. This event is only"]
1197 #[doc = "sent prior to the presented event."]
1198 #[doc = ""]
1199 #[doc = "As clients may bind to the same global wl_output multiple"]
1200 #[doc = "times, this event is sent for each bound instance that matches"]
1201 #[doc = "the synchronized output. If a client has not bound to the"]
1202 #[doc = "right wl_output global at all, this event is not sent."]
1203 #[doc = ""]
1204 fn sync_output(
1205 &self,
1206 client: &mut crate::server::Client,
1207 sender_id: crate::wire::ObjectId,
1208 output: crate::wire::ObjectId,
1209 ) -> impl Future<Output = crate::server::Result<()>> + Send {
1210 async move {
1211 tracing::debug!(
1212 "-> wp_presentation_feedback#{}.sync_output({})",
1213 sender_id,
1214 output
1215 );
1216 let (payload, fds) = crate::wire::PayloadBuilder::new()
1217 .put_object(Some(output))
1218 .build();
1219 client
1220 .send_message(crate::wire::Message::new(sender_id, 0u16, payload, fds))
1221 .await
1222 .map_err(crate::server::error::Error::IoError)
1223 }
1224 }
1225 #[doc = ""]
1226 #[doc = "The associated content update was displayed to the user at the"]
1227 #[doc = "indicated time (tv_sec_hi/lo, tv_nsec). For the interpretation of"]
1228 #[doc = "the timestamp, see presentation.clock_id event."]
1229 #[doc = ""]
1230 #[doc = "The timestamp corresponds to the time when the content update"]
1231 #[doc = "turned into light the first time on the surface's main output."]
1232 #[doc = "Compositors may approximate this from the framebuffer flip"]
1233 #[doc = "completion events from the system, and the latency of the"]
1234 #[doc = "physical display path if known."]
1235 #[doc = ""]
1236 #[doc = "This event is preceded by all related sync_output events"]
1237 #[doc = "telling which output's refresh cycle the feedback corresponds"]
1238 #[doc = "to, i.e. the main output for the surface. Compositors are"]
1239 #[doc = "recommended to choose the output containing the largest part"]
1240 #[doc = "of the wl_surface, or keeping the output they previously"]
1241 #[doc = "chose. Having a stable presentation output association helps"]
1242 #[doc = "clients predict future output refreshes (vblank)."]
1243 #[doc = ""]
1244 #[doc = "The 'refresh' argument gives the compositor's prediction of how"]
1245 #[doc = "many nanoseconds after tv_sec, tv_nsec the very next output"]
1246 #[doc = "refresh may occur. This is to further aid clients in"]
1247 #[doc = "predicting future refreshes, i.e., estimating the timestamps"]
1248 #[doc = "targeting the next few vblanks. If such prediction cannot"]
1249 #[doc = "usefully be done, the argument is zero."]
1250 #[doc = ""]
1251 #[doc = "For version 2 and later, if the output does not have a constant"]
1252 #[doc = "refresh rate, explicit video mode switches excluded, then the"]
1253 #[doc = "refresh argument must be either an appropriate rate picked by the"]
1254 #[doc = "compositor (e.g. fastest rate), or 0 if no such rate exists."]
1255 #[doc = "For version 1, if the output does not have a constant refresh rate,"]
1256 #[doc = "the refresh argument must be zero."]
1257 #[doc = ""]
1258 #[doc = "The 64-bit value combined from seq_hi and seq_lo is the value"]
1259 #[doc = "of the output's vertical retrace counter when the content"]
1260 #[doc = "update was first scanned out to the display. This value must"]
1261 #[doc = "be compatible with the definition of MSC in"]
1262 #[doc = "GLX_OML_sync_control specification. Note, that if the display"]
1263 #[doc = "path has a non-zero latency, the time instant specified by"]
1264 #[doc = "this counter may differ from the timestamp's."]
1265 #[doc = ""]
1266 #[doc = "If the output does not have a concept of vertical retrace or a"]
1267 #[doc = "refresh cycle, or the output device is self-refreshing without"]
1268 #[doc = "a way to query the refresh count, then the arguments seq_hi"]
1269 #[doc = "and seq_lo must be zero."]
1270 #[doc = ""]
1271 fn presented(
1272 &self,
1273 client: &mut crate::server::Client,
1274 sender_id: crate::wire::ObjectId,
1275 tv_sec_hi: u32,
1276 tv_sec_lo: u32,
1277 tv_nsec: u32,
1278 refresh: u32,
1279 seq_hi: u32,
1280 seq_lo: u32,
1281 flags: Kind,
1282 ) -> impl Future<Output = crate::server::Result<()>> + Send {
1283 async move {
1284 tracing::debug!(
1285 "-> wp_presentation_feedback#{}.presented({}, {}, {}, {}, {}, {}, {})",
1286 sender_id,
1287 tv_sec_hi,
1288 tv_sec_lo,
1289 tv_nsec,
1290 refresh,
1291 seq_hi,
1292 seq_lo,
1293 flags
1294 );
1295 let (payload, fds) = crate::wire::PayloadBuilder::new()
1296 .put_uint(tv_sec_hi)
1297 .put_uint(tv_sec_lo)
1298 .put_uint(tv_nsec)
1299 .put_uint(refresh)
1300 .put_uint(seq_hi)
1301 .put_uint(seq_lo)
1302 .put_uint(flags.bits())
1303 .build();
1304 client
1305 .send_message(crate::wire::Message::new(sender_id, 1u16, payload, fds))
1306 .await
1307 .map_err(crate::server::error::Error::IoError)
1308 }
1309 }
1310 #[doc = ""]
1311 #[doc = "The content update was never displayed to the user."]
1312 #[doc = ""]
1313 fn discarded(
1314 &self,
1315 client: &mut crate::server::Client,
1316 sender_id: crate::wire::ObjectId,
1317 ) -> impl Future<Output = crate::server::Result<()>> + Send {
1318 async move {
1319 tracing::debug!("-> wp_presentation_feedback#{}.discarded()", sender_id,);
1320 let (payload, fds) = crate::wire::PayloadBuilder::new().build();
1321 client
1322 .send_message(crate::wire::Message::new(sender_id, 2u16, payload, fds))
1323 .await
1324 .map_err(crate::server::error::Error::IoError)
1325 }
1326 }
1327 }
1328 }
1329}
1330#[doc = ""]
1331#[doc = "This description provides a high-level overview of the interplay between"]
1332#[doc = "the interfaces defined this protocol. For details, see the protocol"]
1333#[doc = "specification."]
1334#[doc = ""]
1335#[doc = "More than one tablet may exist, and device-specifics matter. Tablets are"]
1336#[doc = "not represented by a single virtual device like wl_pointer. A client"]
1337#[doc = "binds to the tablet manager object which is just a proxy object. From"]
1338#[doc = "that, the client requests wp_tablet_manager.get_tablet_seat(wl_seat)"]
1339#[doc = "and that returns the actual interface that has all the tablets. With"]
1340#[doc = "this indirection, we can avoid merging wp_tablet into the actual Wayland"]
1341#[doc = "protocol, a long-term benefit."]
1342#[doc = ""]
1343#[doc = "The wp_tablet_seat sends a \"tablet added\" event for each tablet"]
1344#[doc = "connected. That event is followed by descriptive events about the"]
1345#[doc = "hardware; currently that includes events for name, vid/pid and"]
1346#[doc = "a wp_tablet.path event that describes a local path. This path can be"]
1347#[doc = "used to uniquely identify a tablet or get more information through"]
1348#[doc = "libwacom. Emulated or nested tablets can skip any of those, e.g. a"]
1349#[doc = "virtual tablet may not have a vid/pid. The sequence of descriptive"]
1350#[doc = "events is terminated by a wp_tablet.done event to signal that a client"]
1351#[doc = "may now finalize any initialization for that tablet."]
1352#[doc = ""]
1353#[doc = "Events from tablets require a tool in proximity. Tools are also managed"]
1354#[doc = "by the tablet seat; a \"tool added\" event is sent whenever a tool is new"]
1355#[doc = "to the compositor. That event is followed by a number of descriptive"]
1356#[doc = "events about the hardware; currently that includes capabilities,"]
1357#[doc = "hardware id and serial number, and tool type. Similar to the tablet"]
1358#[doc = "interface, a wp_tablet_tool.done event is sent to terminate that initial"]
1359#[doc = "sequence."]
1360#[doc = ""]
1361#[doc = "Any event from a tool happens on the wp_tablet_tool interface. When the"]
1362#[doc = "tool gets into proximity of the tablet, a proximity_in event is sent on"]
1363#[doc = "the wp_tablet_tool interface, listing the tablet and the surface. That"]
1364#[doc = "event is followed by a motion event with the coordinates. After that,"]
1365#[doc = "it's the usual motion, axis, button, etc. events. The protocol's"]
1366#[doc = "serialisation means events are grouped by wp_tablet_tool.frame events."]
1367#[doc = ""]
1368#[doc = "Two special events (that don't exist in X) are down and up. They signal"]
1369#[doc = "\"tip touching the surface\". For tablets without real proximity"]
1370#[doc = "detection, the sequence is: proximity_in, motion, down, frame."]
1371#[doc = ""]
1372#[doc = "When the tool leaves proximity, a proximity_out event is sent. If any"]
1373#[doc = "button is still down, a button release event is sent before this"]
1374#[doc = "proximity event. These button events are sent in the same frame as the"]
1375#[doc = "proximity event to signal to the client that the buttons were held when"]
1376#[doc = "the tool left proximity."]
1377#[doc = ""]
1378#[doc = "If the tool moves out of the surface but stays in proximity (i.e."]
1379#[doc = "between windows), compositor-specific grab policies apply. This usually"]
1380#[doc = "means that the proximity-out is delayed until all buttons are released."]
1381#[doc = ""]
1382#[doc = "Moving a tool physically from one tablet to the other has no real effect"]
1383#[doc = "on the protocol, since we already have the tool object from the \"tool"]
1384#[doc = "added\" event. All the information is already there and the proximity"]
1385#[doc = "events on both tablets are all a client needs to reconstruct what"]
1386#[doc = "happened."]
1387#[doc = ""]
1388#[doc = "Some extra axes are normalized, i.e. the client knows the range as"]
1389#[doc = "specified in the protocol (e.g. [0, 65535]), the granularity however is"]
1390#[doc = "unknown. The current normalized axes are pressure, distance, and slider."]
1391#[doc = ""]
1392#[doc = "Other extra axes are in physical units as specified in the protocol."]
1393#[doc = "The current extra axes with physical units are tilt, rotation and"]
1394#[doc = "wheel rotation."]
1395#[doc = ""]
1396#[doc = "Since tablets work independently of the pointer controlled by the mouse,"]
1397#[doc = "the focus handling is independent too and controlled by proximity."]
1398#[doc = "The wp_tablet_tool.set_cursor request sets a tool-specific cursor."]
1399#[doc = "This cursor surface may be the same as the mouse cursor, and it may be"]
1400#[doc = "the same across tools but it is possible to be more fine-grained. For"]
1401#[doc = "example, a client may set different cursors for the pen and eraser."]
1402#[doc = ""]
1403#[doc = "Tools are generally independent of tablets and it is"]
1404#[doc = "compositor-specific policy when a tool can be removed. Common approaches"]
1405#[doc = "will likely include some form of removing a tool when all tablets the"]
1406#[doc = "tool was used on are removed."]
1407#[doc = ""]
1408#[allow(clippy::module_inception)]
1409pub mod tablet_v2 {
1410 #[doc = ""]
1411 #[doc = "An object that provides access to the graphics tablets available on this"]
1412 #[doc = "system. All tablets are associated with a seat, to get access to the"]
1413 #[doc = "actual tablets, use wp_tablet_manager.get_tablet_seat."]
1414 #[doc = ""]
1415 #[allow(clippy::too_many_arguments)]
1416 pub mod zwp_tablet_manager_v2 {
1417 #[allow(unused)]
1418 use futures_util::SinkExt;
1419 #[allow(unused)]
1420 use std::os::fd::AsRawFd;
1421 #[doc = "Trait to implement the zwp_tablet_manager_v2 interface. See the module level documentation for more info"]
1422 pub trait ZwpTabletManagerV2: crate::server::Dispatcher {
1423 const INTERFACE: &'static str = "zwp_tablet_manager_v2";
1424 const VERSION: u32 = 2u32;
1425 fn handle_request(
1426 &self,
1427 client: &mut crate::server::Client,
1428 sender_id: crate::wire::ObjectId,
1429 message: &mut crate::wire::Message,
1430 ) -> impl Future<Output = crate::server::Result<()>> + Send {
1431 async move {
1432 #[allow(clippy::match_single_binding)]
1433 match message.opcode() {
1434 0u16 => {
1435 let tablet_seat = message
1436 .object()?
1437 .ok_or(crate::wire::DecodeError::MalformedPayload)?;
1438 let seat = message
1439 .object()?
1440 .ok_or(crate::wire::DecodeError::MalformedPayload)?;
1441 tracing::debug!(
1442 "zwp_tablet_manager_v2#{}.get_tablet_seat({}, {})",
1443 sender_id,
1444 tablet_seat,
1445 seat
1446 );
1447 self.get_tablet_seat(client, sender_id, tablet_seat, seat)
1448 .await
1449 }
1450 1u16 => {
1451 tracing::debug!("zwp_tablet_manager_v2#{}.destroy()", sender_id,);
1452 let result = self.destroy(client, sender_id).await;
1453 client.remove(sender_id);
1454 result
1455 }
1456 opcode => Err(crate::server::error::Error::UnknownOpcode(opcode)),
1457 }
1458 }
1459 }
1460 #[doc = ""]
1461 #[doc = "Get the wp_tablet_seat object for the given seat. This object"]
1462 #[doc = "provides access to all graphics tablets in this seat."]
1463 #[doc = ""]
1464 fn get_tablet_seat(
1465 &self,
1466 client: &mut crate::server::Client,
1467 sender_id: crate::wire::ObjectId,
1468 tablet_seat: crate::wire::ObjectId,
1469 seat: crate::wire::ObjectId,
1470 ) -> impl Future<Output = crate::server::Result<()>> + Send;
1471 #[doc = ""]
1472 #[doc = "Destroy the wp_tablet_manager object. Objects created from this"]
1473 #[doc = "object are unaffected and should be destroyed separately."]
1474 #[doc = ""]
1475 fn destroy(
1476 &self,
1477 client: &mut crate::server::Client,
1478 sender_id: crate::wire::ObjectId,
1479 ) -> impl Future<Output = crate::server::Result<()>> + Send;
1480 }
1481 }
1482 #[doc = ""]
1483 #[doc = "An object that provides access to the graphics tablets available on this"]
1484 #[doc = "seat. After binding to this interface, the compositor sends a set of"]
1485 #[doc = "wp_tablet_seat.tablet_added and wp_tablet_seat.tool_added events."]
1486 #[doc = ""]
1487 #[allow(clippy::too_many_arguments)]
1488 pub mod zwp_tablet_seat_v2 {
1489 #[allow(unused)]
1490 use futures_util::SinkExt;
1491 #[allow(unused)]
1492 use std::os::fd::AsRawFd;
1493 #[doc = "Trait to implement the zwp_tablet_seat_v2 interface. See the module level documentation for more info"]
1494 pub trait ZwpTabletSeatV2: crate::server::Dispatcher {
1495 const INTERFACE: &'static str = "zwp_tablet_seat_v2";
1496 const VERSION: u32 = 2u32;
1497 fn handle_request(
1498 &self,
1499 client: &mut crate::server::Client,
1500 sender_id: crate::wire::ObjectId,
1501 message: &mut crate::wire::Message,
1502 ) -> impl Future<Output = crate::server::Result<()>> + Send {
1503 async move {
1504 #[allow(clippy::match_single_binding)]
1505 match message.opcode() {
1506 0u16 => {
1507 tracing::debug!("zwp_tablet_seat_v2#{}.destroy()", sender_id,);
1508 let result = self.destroy(client, sender_id).await;
1509 client.remove(sender_id);
1510 result
1511 }
1512 opcode => Err(crate::server::error::Error::UnknownOpcode(opcode)),
1513 }
1514 }
1515 }
1516 #[doc = ""]
1517 #[doc = "Destroy the wp_tablet_seat object. Objects created from this"]
1518 #[doc = "object are unaffected and should be destroyed separately."]
1519 #[doc = ""]
1520 fn destroy(
1521 &self,
1522 client: &mut crate::server::Client,
1523 sender_id: crate::wire::ObjectId,
1524 ) -> impl Future<Output = crate::server::Result<()>> + Send;
1525 #[doc = ""]
1526 #[doc = "This event is sent whenever a new tablet becomes available on this"]
1527 #[doc = "seat. This event only provides the object id of the tablet, any"]
1528 #[doc = "static information about the tablet (device name, vid/pid, etc.) is"]
1529 #[doc = "sent through the wp_tablet interface."]
1530 #[doc = ""]
1531 fn tablet_added(
1532 &self,
1533 client: &mut crate::server::Client,
1534 sender_id: crate::wire::ObjectId,
1535 id: crate::wire::ObjectId,
1536 ) -> impl Future<Output = crate::server::Result<()>> + Send {
1537 async move {
1538 tracing::debug!("-> zwp_tablet_seat_v2#{}.tablet_added({})", sender_id, id);
1539 let (payload, fds) = crate::wire::PayloadBuilder::new()
1540 .put_object(Some(id))
1541 .build();
1542 client
1543 .send_message(crate::wire::Message::new(sender_id, 0u16, payload, fds))
1544 .await
1545 .map_err(crate::server::error::Error::IoError)
1546 }
1547 }
1548 #[doc = ""]
1549 #[doc = "This event is sent whenever a tool that has not previously been used"]
1550 #[doc = "with a tablet comes into use. This event only provides the object id"]
1551 #[doc = "of the tool; any static information about the tool (capabilities,"]
1552 #[doc = "type, etc.) is sent through the wp_tablet_tool interface."]
1553 #[doc = ""]
1554 fn tool_added(
1555 &self,
1556 client: &mut crate::server::Client,
1557 sender_id: crate::wire::ObjectId,
1558 id: crate::wire::ObjectId,
1559 ) -> impl Future<Output = crate::server::Result<()>> + Send {
1560 async move {
1561 tracing::debug!("-> zwp_tablet_seat_v2#{}.tool_added({})", sender_id, id);
1562 let (payload, fds) = crate::wire::PayloadBuilder::new()
1563 .put_object(Some(id))
1564 .build();
1565 client
1566 .send_message(crate::wire::Message::new(sender_id, 1u16, payload, fds))
1567 .await
1568 .map_err(crate::server::error::Error::IoError)
1569 }
1570 }
1571 #[doc = ""]
1572 #[doc = "This event is sent whenever a new pad is known to the system. Typically,"]
1573 #[doc = "pads are physically attached to tablets and a pad_added event is"]
1574 #[doc = "sent immediately after the wp_tablet_seat.tablet_added."]
1575 #[doc = "However, some standalone pad devices logically attach to tablets at"]
1576 #[doc = "runtime, and the client must wait for wp_tablet_pad.enter to know"]
1577 #[doc = "the tablet a pad is attached to."]
1578 #[doc = ""]
1579 #[doc = "This event only provides the object id of the pad. All further"]
1580 #[doc = "features (buttons, strips, rings) are sent through the wp_tablet_pad"]
1581 #[doc = "interface."]
1582 #[doc = ""]
1583 fn pad_added(
1584 &self,
1585 client: &mut crate::server::Client,
1586 sender_id: crate::wire::ObjectId,
1587 id: crate::wire::ObjectId,
1588 ) -> impl Future<Output = crate::server::Result<()>> + Send {
1589 async move {
1590 tracing::debug!("-> zwp_tablet_seat_v2#{}.pad_added({})", sender_id, id);
1591 let (payload, fds) = crate::wire::PayloadBuilder::new()
1592 .put_object(Some(id))
1593 .build();
1594 client
1595 .send_message(crate::wire::Message::new(sender_id, 2u16, payload, fds))
1596 .await
1597 .map_err(crate::server::error::Error::IoError)
1598 }
1599 }
1600 }
1601 }
1602 #[doc = ""]
1603 #[doc = "An object that represents a physical tool that has been, or is"]
1604 #[doc = "currently in use with a tablet in this seat. Each wp_tablet_tool"]
1605 #[doc = "object stays valid until the client destroys it; the compositor"]
1606 #[doc = "reuses the wp_tablet_tool object to indicate that the object's"]
1607 #[doc = "respective physical tool has come into proximity of a tablet again."]
1608 #[doc = ""]
1609 #[doc = "A wp_tablet_tool object's relation to a physical tool depends on the"]
1610 #[doc = "tablet's ability to report serial numbers. If the tablet supports"]
1611 #[doc = "this capability, then the object represents a specific physical tool"]
1612 #[doc = "and can be identified even when used on multiple tablets."]
1613 #[doc = ""]
1614 #[doc = "A tablet tool has a number of static characteristics, e.g. tool type,"]
1615 #[doc = "hardware_serial and capabilities. These capabilities are sent in an"]
1616 #[doc = "event sequence after the wp_tablet_seat.tool_added event before any"]
1617 #[doc = "actual events from this tool. This initial event sequence is"]
1618 #[doc = "terminated by a wp_tablet_tool.done event."]
1619 #[doc = ""]
1620 #[doc = "Tablet tool events are grouped by wp_tablet_tool.frame events."]
1621 #[doc = "Any events received before a wp_tablet_tool.frame event should be"]
1622 #[doc = "considered part of the same hardware state change."]
1623 #[doc = ""]
1624 #[allow(clippy::too_many_arguments)]
1625 pub mod zwp_tablet_tool_v2 {
1626 #[allow(unused)]
1627 use futures_util::SinkExt;
1628 #[allow(unused)]
1629 use std::os::fd::AsRawFd;
1630 #[doc = ""]
1631 #[doc = "Describes the physical type of a tool. The physical type of a tool"]
1632 #[doc = "generally defines its base usage."]
1633 #[doc = ""]
1634 #[doc = "The mouse tool represents a mouse-shaped tool that is not a relative"]
1635 #[doc = "device but bound to the tablet's surface, providing absolute"]
1636 #[doc = "coordinates."]
1637 #[doc = ""]
1638 #[doc = "The lens tool is a mouse-shaped tool with an attached lens to"]
1639 #[doc = "provide precision focus."]
1640 #[doc = ""]
1641 #[repr(u32)]
1642 #[non_exhaustive]
1643 #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy)]
1644 pub enum Type {
1645 #[doc = "Pen"]
1646 Pen = 320u32,
1647 #[doc = "Eraser"]
1648 Eraser = 321u32,
1649 #[doc = "Brush"]
1650 Brush = 322u32,
1651 #[doc = "Pencil"]
1652 Pencil = 323u32,
1653 #[doc = "Airbrush"]
1654 Airbrush = 324u32,
1655 #[doc = "Finger"]
1656 Finger = 325u32,
1657 #[doc = "Mouse"]
1658 Mouse = 326u32,
1659 #[doc = "Lens"]
1660 Lens = 327u32,
1661 }
1662 impl TryFrom<u32> for Type {
1663 type Error = crate::wire::DecodeError;
1664 fn try_from(v: u32) -> Result<Self, Self::Error> {
1665 match v {
1666 320u32 => Ok(Self::Pen),
1667 321u32 => Ok(Self::Eraser),
1668 322u32 => Ok(Self::Brush),
1669 323u32 => Ok(Self::Pencil),
1670 324u32 => Ok(Self::Airbrush),
1671 325u32 => Ok(Self::Finger),
1672 326u32 => Ok(Self::Mouse),
1673 327u32 => Ok(Self::Lens),
1674 _ => Err(crate::wire::DecodeError::MalformedPayload),
1675 }
1676 }
1677 }
1678 impl std::fmt::Display for Type {
1679 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1680 (*self as u32).fmt(f)
1681 }
1682 }
1683 #[doc = ""]
1684 #[doc = "Describes extra capabilities on a tablet."]
1685 #[doc = ""]
1686 #[doc = "Any tool must provide x and y values, extra axes are"]
1687 #[doc = "device-specific."]
1688 #[doc = ""]
1689 #[repr(u32)]
1690 #[non_exhaustive]
1691 #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy)]
1692 pub enum Capability {
1693 #[doc = "Tilt axes"]
1694 Tilt = 1u32,
1695 #[doc = "Pressure axis"]
1696 Pressure = 2u32,
1697 #[doc = "Distance axis"]
1698 Distance = 3u32,
1699 #[doc = "Z-rotation axis"]
1700 Rotation = 4u32,
1701 #[doc = "Slider axis"]
1702 Slider = 5u32,
1703 #[doc = "Wheel axis"]
1704 Wheel = 6u32,
1705 }
1706 impl TryFrom<u32> for Capability {
1707 type Error = crate::wire::DecodeError;
1708 fn try_from(v: u32) -> Result<Self, Self::Error> {
1709 match v {
1710 1u32 => Ok(Self::Tilt),
1711 2u32 => Ok(Self::Pressure),
1712 3u32 => Ok(Self::Distance),
1713 4u32 => Ok(Self::Rotation),
1714 5u32 => Ok(Self::Slider),
1715 6u32 => Ok(Self::Wheel),
1716 _ => Err(crate::wire::DecodeError::MalformedPayload),
1717 }
1718 }
1719 }
1720 impl std::fmt::Display for Capability {
1721 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1722 (*self as u32).fmt(f)
1723 }
1724 }
1725 #[doc = ""]
1726 #[doc = "Describes the physical state of a button that produced the button event."]
1727 #[doc = ""]
1728 #[repr(u32)]
1729 #[non_exhaustive]
1730 #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy)]
1731 pub enum ButtonState {
1732 #[doc = "button is not pressed"]
1733 Released = 0u32,
1734 #[doc = "button is pressed"]
1735 Pressed = 1u32,
1736 }
1737 impl TryFrom<u32> for ButtonState {
1738 type Error = crate::wire::DecodeError;
1739 fn try_from(v: u32) -> Result<Self, Self::Error> {
1740 match v {
1741 0u32 => Ok(Self::Released),
1742 1u32 => Ok(Self::Pressed),
1743 _ => Err(crate::wire::DecodeError::MalformedPayload),
1744 }
1745 }
1746 }
1747 impl std::fmt::Display for ButtonState {
1748 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1749 (*self as u32).fmt(f)
1750 }
1751 }
1752 #[repr(u32)]
1753 #[non_exhaustive]
1754 #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy)]
1755 pub enum Error {
1756 #[doc = "given wl_surface has another role"]
1757 Role = 0u32,
1758 }
1759 impl TryFrom<u32> for Error {
1760 type Error = crate::wire::DecodeError;
1761 fn try_from(v: u32) -> Result<Self, Self::Error> {
1762 match v {
1763 0u32 => Ok(Self::Role),
1764 _ => Err(crate::wire::DecodeError::MalformedPayload),
1765 }
1766 }
1767 }
1768 impl std::fmt::Display for Error {
1769 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1770 (*self as u32).fmt(f)
1771 }
1772 }
1773 #[doc = "Trait to implement the zwp_tablet_tool_v2 interface. See the module level documentation for more info"]
1774 pub trait ZwpTabletToolV2: crate::server::Dispatcher {
1775 const INTERFACE: &'static str = "zwp_tablet_tool_v2";
1776 const VERSION: u32 = 2u32;
1777 fn handle_request(
1778 &self,
1779 client: &mut crate::server::Client,
1780 sender_id: crate::wire::ObjectId,
1781 message: &mut crate::wire::Message,
1782 ) -> impl Future<Output = crate::server::Result<()>> + Send {
1783 async move {
1784 #[allow(clippy::match_single_binding)]
1785 match message.opcode() {
1786 0u16 => {
1787 let serial = message.uint()?;
1788 let surface = message.object()?;
1789 let hotspot_x = message.int()?;
1790 let hotspot_y = message.int()?;
1791 tracing::debug!(
1792 "zwp_tablet_tool_v2#{}.set_cursor({}, {}, {}, {})",
1793 sender_id,
1794 serial,
1795 surface
1796 .as_ref()
1797 .map_or("null".to_string(), |v| v.to_string()),
1798 hotspot_x,
1799 hotspot_y
1800 );
1801 self.set_cursor(
1802 client, sender_id, serial, surface, hotspot_x, hotspot_y,
1803 )
1804 .await
1805 }
1806 1u16 => {
1807 tracing::debug!("zwp_tablet_tool_v2#{}.destroy()", sender_id,);
1808 let result = self.destroy(client, sender_id).await;
1809 client.remove(sender_id);
1810 result
1811 }
1812 opcode => Err(crate::server::error::Error::UnknownOpcode(opcode)),
1813 }
1814 }
1815 }
1816 #[doc = ""]
1817 #[doc = "Sets the surface of the cursor used for this tool on the given"]
1818 #[doc = "tablet. This request only takes effect if the tool is in proximity"]
1819 #[doc = "of one of the requesting client's surfaces or the surface parameter"]
1820 #[doc = "is the current pointer surface. If there was a previous surface set"]
1821 #[doc = "with this request it is replaced. If surface is NULL, the cursor"]
1822 #[doc = "image is hidden."]
1823 #[doc = ""]
1824 #[doc = "The parameters hotspot_x and hotspot_y define the position of the"]
1825 #[doc = "pointer surface relative to the pointer location. Its top-left corner"]
1826 #[doc = "is always at (x, y) - (hotspot_x, hotspot_y), where (x, y) are the"]
1827 #[doc = "coordinates of the pointer location, in surface-local coordinates."]
1828 #[doc = ""]
1829 #[doc = "On surface.attach requests to the pointer surface, hotspot_x and"]
1830 #[doc = "hotspot_y are decremented by the x and y parameters passed to the"]
1831 #[doc = "request. Attach must be confirmed by wl_surface.commit as usual."]
1832 #[doc = ""]
1833 #[doc = "The hotspot can also be updated by passing the currently set pointer"]
1834 #[doc = "surface to this request with new values for hotspot_x and hotspot_y."]
1835 #[doc = ""]
1836 #[doc = "The current and pending input regions of the wl_surface are cleared,"]
1837 #[doc = "and wl_surface.set_input_region is ignored until the wl_surface is no"]
1838 #[doc = "longer used as the cursor. When the use as a cursor ends, the current"]
1839 #[doc = "and pending input regions become undefined, and the wl_surface is"]
1840 #[doc = "unmapped."]
1841 #[doc = ""]
1842 #[doc = "This request gives the surface the role of a wp_tablet_tool cursor. A"]
1843 #[doc = "surface may only ever be used as the cursor surface for one"]
1844 #[doc = "wp_tablet_tool. If the surface already has another role or has"]
1845 #[doc = "previously been used as cursor surface for a different tool, a"]
1846 #[doc = "protocol error is raised."]
1847 #[doc = ""]
1848 fn set_cursor(
1849 &self,
1850 client: &mut crate::server::Client,
1851 sender_id: crate::wire::ObjectId,
1852 serial: u32,
1853 surface: Option<crate::wire::ObjectId>,
1854 hotspot_x: i32,
1855 hotspot_y: i32,
1856 ) -> impl Future<Output = crate::server::Result<()>> + Send;
1857 #[doc = ""]
1858 #[doc = "This destroys the client's resource for this tool object."]
1859 #[doc = ""]
1860 fn destroy(
1861 &self,
1862 client: &mut crate::server::Client,
1863 sender_id: crate::wire::ObjectId,
1864 ) -> impl Future<Output = crate::server::Result<()>> + Send;
1865 #[doc = ""]
1866 #[doc = "The tool type is the high-level type of the tool and usually decides"]
1867 #[doc = "the interaction expected from this tool."]
1868 #[doc = ""]
1869 #[doc = "This event is sent in the initial burst of events before the"]
1870 #[doc = "wp_tablet_tool.done event."]
1871 #[doc = ""]
1872 fn r#type(
1873 &self,
1874 client: &mut crate::server::Client,
1875 sender_id: crate::wire::ObjectId,
1876 tool_type: Type,
1877 ) -> impl Future<Output = crate::server::Result<()>> + Send {
1878 async move {
1879 tracing::debug!("-> zwp_tablet_tool_v2#{}.type({})", sender_id, tool_type);
1880 let (payload, fds) = crate::wire::PayloadBuilder::new()
1881 .put_uint(tool_type as u32)
1882 .build();
1883 client
1884 .send_message(crate::wire::Message::new(sender_id, 0u16, payload, fds))
1885 .await
1886 .map_err(crate::server::error::Error::IoError)
1887 }
1888 }
1889 #[doc = ""]
1890 #[doc = "If the physical tool can be identified by a unique 64-bit serial"]
1891 #[doc = "number, this event notifies the client of this serial number."]
1892 #[doc = ""]
1893 #[doc = "If multiple tablets are available in the same seat and the tool is"]
1894 #[doc = "uniquely identifiable by the serial number, that tool may move"]
1895 #[doc = "between tablets."]
1896 #[doc = ""]
1897 #[doc = "Otherwise, if the tool has no serial number and this event is"]
1898 #[doc = "missing, the tool is tied to the tablet it first comes into"]
1899 #[doc = "proximity with. Even if the physical tool is used on multiple"]
1900 #[doc = "tablets, separate wp_tablet_tool objects will be created, one per"]
1901 #[doc = "tablet."]
1902 #[doc = ""]
1903 #[doc = "This event is sent in the initial burst of events before the"]
1904 #[doc = "wp_tablet_tool.done event."]
1905 #[doc = ""]
1906 fn hardware_serial(
1907 &self,
1908 client: &mut crate::server::Client,
1909 sender_id: crate::wire::ObjectId,
1910 hardware_serial_hi: u32,
1911 hardware_serial_lo: u32,
1912 ) -> impl Future<Output = crate::server::Result<()>> + Send {
1913 async move {
1914 tracing::debug!(
1915 "-> zwp_tablet_tool_v2#{}.hardware_serial({}, {})",
1916 sender_id,
1917 hardware_serial_hi,
1918 hardware_serial_lo
1919 );
1920 let (payload, fds) = crate::wire::PayloadBuilder::new()
1921 .put_uint(hardware_serial_hi)
1922 .put_uint(hardware_serial_lo)
1923 .build();
1924 client
1925 .send_message(crate::wire::Message::new(sender_id, 1u16, payload, fds))
1926 .await
1927 .map_err(crate::server::error::Error::IoError)
1928 }
1929 }
1930 #[doc = ""]
1931 #[doc = "This event notifies the client of a hardware id available on this tool."]
1932 #[doc = ""]
1933 #[doc = "The hardware id is a device-specific 64-bit id that provides extra"]
1934 #[doc = "information about the tool in use, beyond the wl_tool.type"]
1935 #[doc = "enumeration. The format of the id is specific to tablets made by"]
1936 #[doc = "Wacom Inc. For example, the hardware id of a Wacom Grip"]
1937 #[doc = "Pen (a stylus) is 0x802."]
1938 #[doc = ""]
1939 #[doc = "This event is sent in the initial burst of events before the"]
1940 #[doc = "wp_tablet_tool.done event."]
1941 #[doc = ""]
1942 fn hardware_id_wacom(
1943 &self,
1944 client: &mut crate::server::Client,
1945 sender_id: crate::wire::ObjectId,
1946 hardware_id_hi: u32,
1947 hardware_id_lo: u32,
1948 ) -> impl Future<Output = crate::server::Result<()>> + Send {
1949 async move {
1950 tracing::debug!(
1951 "-> zwp_tablet_tool_v2#{}.hardware_id_wacom({}, {})",
1952 sender_id,
1953 hardware_id_hi,
1954 hardware_id_lo
1955 );
1956 let (payload, fds) = crate::wire::PayloadBuilder::new()
1957 .put_uint(hardware_id_hi)
1958 .put_uint(hardware_id_lo)
1959 .build();
1960 client
1961 .send_message(crate::wire::Message::new(sender_id, 2u16, payload, fds))
1962 .await
1963 .map_err(crate::server::error::Error::IoError)
1964 }
1965 }
1966 #[doc = ""]
1967 #[doc = "This event notifies the client of any capabilities of this tool,"]
1968 #[doc = "beyond the main set of x/y axes and tip up/down detection."]
1969 #[doc = ""]
1970 #[doc = "One event is sent for each extra capability available on this tool."]
1971 #[doc = ""]
1972 #[doc = "This event is sent in the initial burst of events before the"]
1973 #[doc = "wp_tablet_tool.done event."]
1974 #[doc = ""]
1975 fn capability(
1976 &self,
1977 client: &mut crate::server::Client,
1978 sender_id: crate::wire::ObjectId,
1979 capability: Capability,
1980 ) -> impl Future<Output = crate::server::Result<()>> + Send {
1981 async move {
1982 tracing::debug!(
1983 "-> zwp_tablet_tool_v2#{}.capability({})",
1984 sender_id,
1985 capability
1986 );
1987 let (payload, fds) = crate::wire::PayloadBuilder::new()
1988 .put_uint(capability as u32)
1989 .build();
1990 client
1991 .send_message(crate::wire::Message::new(sender_id, 3u16, payload, fds))
1992 .await
1993 .map_err(crate::server::error::Error::IoError)
1994 }
1995 }
1996 #[doc = ""]
1997 #[doc = "This event signals the end of the initial burst of descriptive"]
1998 #[doc = "events. A client may consider the static description of the tool to"]
1999 #[doc = "be complete and finalize initialization of the tool."]
2000 #[doc = ""]
2001 fn done(
2002 &self,
2003 client: &mut crate::server::Client,
2004 sender_id: crate::wire::ObjectId,
2005 ) -> impl Future<Output = crate::server::Result<()>> + Send {
2006 async move {
2007 tracing::debug!("-> zwp_tablet_tool_v2#{}.done()", sender_id,);
2008 let (payload, fds) = crate::wire::PayloadBuilder::new().build();
2009 client
2010 .send_message(crate::wire::Message::new(sender_id, 4u16, payload, fds))
2011 .await
2012 .map_err(crate::server::error::Error::IoError)
2013 }
2014 }
2015 #[doc = ""]
2016 #[doc = "This event is sent when the tool is removed from the system and will"]
2017 #[doc = "send no further events. Should the physical tool come back into"]
2018 #[doc = "proximity later, a new wp_tablet_tool object will be created."]
2019 #[doc = ""]
2020 #[doc = "It is compositor-dependent when a tool is removed. A compositor may"]
2021 #[doc = "remove a tool on proximity out, tablet removal or any other reason."]
2022 #[doc = "A compositor may also keep a tool alive until shutdown."]
2023 #[doc = ""]
2024 #[doc = "If the tool is currently in proximity, a proximity_out event will be"]
2025 #[doc = "sent before the removed event. See wp_tablet_tool.proximity_out for"]
2026 #[doc = "the handling of any buttons logically down."]
2027 #[doc = ""]
2028 #[doc = "When this event is received, the client must wp_tablet_tool.destroy"]
2029 #[doc = "the object."]
2030 #[doc = ""]
2031 fn removed(
2032 &self,
2033 client: &mut crate::server::Client,
2034 sender_id: crate::wire::ObjectId,
2035 ) -> impl Future<Output = crate::server::Result<()>> + Send {
2036 async move {
2037 tracing::debug!("-> zwp_tablet_tool_v2#{}.removed()", sender_id,);
2038 let (payload, fds) = crate::wire::PayloadBuilder::new().build();
2039 client
2040 .send_message(crate::wire::Message::new(sender_id, 5u16, payload, fds))
2041 .await
2042 .map_err(crate::server::error::Error::IoError)
2043 }
2044 }
2045 #[doc = ""]
2046 #[doc = "Notification that this tool is focused on a certain surface."]
2047 #[doc = ""]
2048 #[doc = "This event can be received when the tool has moved from one surface to"]
2049 #[doc = "another, or when the tool has come back into proximity above the"]
2050 #[doc = "surface."]
2051 #[doc = ""]
2052 #[doc = "If any button is logically down when the tool comes into proximity,"]
2053 #[doc = "the respective button event is sent after the proximity_in event but"]
2054 #[doc = "within the same frame as the proximity_in event."]
2055 #[doc = ""]
2056 fn proximity_in(
2057 &self,
2058 client: &mut crate::server::Client,
2059 sender_id: crate::wire::ObjectId,
2060 serial: u32,
2061 tablet: crate::wire::ObjectId,
2062 surface: crate::wire::ObjectId,
2063 ) -> impl Future<Output = crate::server::Result<()>> + Send {
2064 async move {
2065 tracing::debug!(
2066 "-> zwp_tablet_tool_v2#{}.proximity_in({}, {}, {})",
2067 sender_id,
2068 serial,
2069 tablet,
2070 surface
2071 );
2072 let (payload, fds) = crate::wire::PayloadBuilder::new()
2073 .put_uint(serial)
2074 .put_object(Some(tablet))
2075 .put_object(Some(surface))
2076 .build();
2077 client
2078 .send_message(crate::wire::Message::new(sender_id, 6u16, payload, fds))
2079 .await
2080 .map_err(crate::server::error::Error::IoError)
2081 }
2082 }
2083 #[doc = ""]
2084 #[doc = "Notification that this tool has either left proximity, or is no"]
2085 #[doc = "longer focused on a certain surface."]
2086 #[doc = ""]
2087 #[doc = "When the tablet tool leaves proximity of the tablet, button release"]
2088 #[doc = "events are sent for each button that was held down at the time of"]
2089 #[doc = "leaving proximity. These events are sent before the proximity_out"]
2090 #[doc = "event but within the same wp_tablet.frame."]
2091 #[doc = ""]
2092 #[doc = "If the tool stays within proximity of the tablet, but the focus"]
2093 #[doc = "changes from one surface to another, a button release event may not"]
2094 #[doc = "be sent until the button is actually released or the tool leaves the"]
2095 #[doc = "proximity of the tablet."]
2096 #[doc = ""]
2097 fn proximity_out(
2098 &self,
2099 client: &mut crate::server::Client,
2100 sender_id: crate::wire::ObjectId,
2101 ) -> impl Future<Output = crate::server::Result<()>> + Send {
2102 async move {
2103 tracing::debug!("-> zwp_tablet_tool_v2#{}.proximity_out()", sender_id,);
2104 let (payload, fds) = crate::wire::PayloadBuilder::new().build();
2105 client
2106 .send_message(crate::wire::Message::new(sender_id, 7u16, payload, fds))
2107 .await
2108 .map_err(crate::server::error::Error::IoError)
2109 }
2110 }
2111 #[doc = ""]
2112 #[doc = "Sent whenever the tablet tool comes in contact with the surface of the"]
2113 #[doc = "tablet."]
2114 #[doc = ""]
2115 #[doc = "If the tool is already in contact with the tablet when entering the"]
2116 #[doc = "input region, the client owning said region will receive a"]
2117 #[doc = "wp_tablet.proximity_in event, followed by a wp_tablet.down"]
2118 #[doc = "event and a wp_tablet.frame event."]
2119 #[doc = ""]
2120 #[doc = "Note that this event describes logical contact, not physical"]
2121 #[doc = "contact. On some devices, a compositor may not consider a tool in"]
2122 #[doc = "logical contact until a minimum physical pressure threshold is"]
2123 #[doc = "exceeded."]
2124 #[doc = ""]
2125 fn down(
2126 &self,
2127 client: &mut crate::server::Client,
2128 sender_id: crate::wire::ObjectId,
2129 serial: u32,
2130 ) -> impl Future<Output = crate::server::Result<()>> + Send {
2131 async move {
2132 tracing::debug!("-> zwp_tablet_tool_v2#{}.down({})", sender_id, serial);
2133 let (payload, fds) =
2134 crate::wire::PayloadBuilder::new().put_uint(serial).build();
2135 client
2136 .send_message(crate::wire::Message::new(sender_id, 8u16, payload, fds))
2137 .await
2138 .map_err(crate::server::error::Error::IoError)
2139 }
2140 }
2141 #[doc = ""]
2142 #[doc = "Sent whenever the tablet tool stops making contact with the surface of"]
2143 #[doc = "the tablet, or when the tablet tool moves out of the input region"]
2144 #[doc = "and the compositor grab (if any) is dismissed."]
2145 #[doc = ""]
2146 #[doc = "If the tablet tool moves out of the input region while in contact"]
2147 #[doc = "with the surface of the tablet and the compositor does not have an"]
2148 #[doc = "ongoing grab on the surface, the client owning said region will"]
2149 #[doc = "receive a wp_tablet.up event, followed by a wp_tablet.proximity_out"]
2150 #[doc = "event and a wp_tablet.frame event. If the compositor has an ongoing"]
2151 #[doc = "grab on this device, this event sequence is sent whenever the grab"]
2152 #[doc = "is dismissed in the future."]
2153 #[doc = ""]
2154 #[doc = "Note that this event describes logical contact, not physical"]
2155 #[doc = "contact. On some devices, a compositor may not consider a tool out"]
2156 #[doc = "of logical contact until physical pressure falls below a specific"]
2157 #[doc = "threshold."]
2158 #[doc = ""]
2159 fn up(
2160 &self,
2161 client: &mut crate::server::Client,
2162 sender_id: crate::wire::ObjectId,
2163 ) -> impl Future<Output = crate::server::Result<()>> + Send {
2164 async move {
2165 tracing::debug!("-> zwp_tablet_tool_v2#{}.up()", sender_id,);
2166 let (payload, fds) = crate::wire::PayloadBuilder::new().build();
2167 client
2168 .send_message(crate::wire::Message::new(sender_id, 9u16, payload, fds))
2169 .await
2170 .map_err(crate::server::error::Error::IoError)
2171 }
2172 }
2173 #[doc = ""]
2174 #[doc = "Sent whenever a tablet tool moves."]
2175 #[doc = ""]
2176 fn motion(
2177 &self,
2178 client: &mut crate::server::Client,
2179 sender_id: crate::wire::ObjectId,
2180 x: crate::wire::Fixed,
2181 y: crate::wire::Fixed,
2182 ) -> impl Future<Output = crate::server::Result<()>> + Send {
2183 async move {
2184 tracing::debug!("-> zwp_tablet_tool_v2#{}.motion({}, {})", sender_id, x, y);
2185 let (payload, fds) = crate::wire::PayloadBuilder::new()
2186 .put_fixed(x)
2187 .put_fixed(y)
2188 .build();
2189 client
2190 .send_message(crate::wire::Message::new(sender_id, 10u16, payload, fds))
2191 .await
2192 .map_err(crate::server::error::Error::IoError)
2193 }
2194 }
2195 #[doc = ""]
2196 #[doc = "Sent whenever the pressure axis on a tool changes. The value of this"]
2197 #[doc = "event is normalized to a value between 0 and 65535."]
2198 #[doc = ""]
2199 #[doc = "Note that pressure may be nonzero even when a tool is not in logical"]
2200 #[doc = "contact. See the down and up events for more details."]
2201 #[doc = ""]
2202 fn pressure(
2203 &self,
2204 client: &mut crate::server::Client,
2205 sender_id: crate::wire::ObjectId,
2206 pressure: u32,
2207 ) -> impl Future<Output = crate::server::Result<()>> + Send {
2208 async move {
2209 tracing::debug!("-> zwp_tablet_tool_v2#{}.pressure({})", sender_id, pressure);
2210 let (payload, fds) = crate::wire::PayloadBuilder::new()
2211 .put_uint(pressure)
2212 .build();
2213 client
2214 .send_message(crate::wire::Message::new(sender_id, 11u16, payload, fds))
2215 .await
2216 .map_err(crate::server::error::Error::IoError)
2217 }
2218 }
2219 #[doc = ""]
2220 #[doc = "Sent whenever the distance axis on a tool changes. The value of this"]
2221 #[doc = "event is normalized to a value between 0 and 65535."]
2222 #[doc = ""]
2223 #[doc = "Note that distance may be nonzero even when a tool is not in logical"]
2224 #[doc = "contact. See the down and up events for more details."]
2225 #[doc = ""]
2226 fn distance(
2227 &self,
2228 client: &mut crate::server::Client,
2229 sender_id: crate::wire::ObjectId,
2230 distance: u32,
2231 ) -> impl Future<Output = crate::server::Result<()>> + Send {
2232 async move {
2233 tracing::debug!("-> zwp_tablet_tool_v2#{}.distance({})", sender_id, distance);
2234 let (payload, fds) = crate::wire::PayloadBuilder::new()
2235 .put_uint(distance)
2236 .build();
2237 client
2238 .send_message(crate::wire::Message::new(sender_id, 12u16, payload, fds))
2239 .await
2240 .map_err(crate::server::error::Error::IoError)
2241 }
2242 }
2243 #[doc = ""]
2244 #[doc = "Sent whenever one or both of the tilt axes on a tool change. Each tilt"]
2245 #[doc = "value is in degrees, relative to the z-axis of the tablet."]
2246 #[doc = "The angle is positive when the top of a tool tilts along the"]
2247 #[doc = "positive x or y axis."]
2248 #[doc = ""]
2249 fn tilt(
2250 &self,
2251 client: &mut crate::server::Client,
2252 sender_id: crate::wire::ObjectId,
2253 tilt_x: crate::wire::Fixed,
2254 tilt_y: crate::wire::Fixed,
2255 ) -> impl Future<Output = crate::server::Result<()>> + Send {
2256 async move {
2257 tracing::debug!(
2258 "-> zwp_tablet_tool_v2#{}.tilt({}, {})",
2259 sender_id,
2260 tilt_x,
2261 tilt_y
2262 );
2263 let (payload, fds) = crate::wire::PayloadBuilder::new()
2264 .put_fixed(tilt_x)
2265 .put_fixed(tilt_y)
2266 .build();
2267 client
2268 .send_message(crate::wire::Message::new(sender_id, 13u16, payload, fds))
2269 .await
2270 .map_err(crate::server::error::Error::IoError)
2271 }
2272 }
2273 #[doc = ""]
2274 #[doc = "Sent whenever the z-rotation axis on the tool changes. The"]
2275 #[doc = "rotation value is in degrees clockwise from the tool's"]
2276 #[doc = "logical neutral position."]
2277 #[doc = ""]
2278 fn rotation(
2279 &self,
2280 client: &mut crate::server::Client,
2281 sender_id: crate::wire::ObjectId,
2282 degrees: crate::wire::Fixed,
2283 ) -> impl Future<Output = crate::server::Result<()>> + Send {
2284 async move {
2285 tracing::debug!("-> zwp_tablet_tool_v2#{}.rotation({})", sender_id, degrees);
2286 let (payload, fds) = crate::wire::PayloadBuilder::new()
2287 .put_fixed(degrees)
2288 .build();
2289 client
2290 .send_message(crate::wire::Message::new(sender_id, 14u16, payload, fds))
2291 .await
2292 .map_err(crate::server::error::Error::IoError)
2293 }
2294 }
2295 #[doc = ""]
2296 #[doc = "Sent whenever the slider position on the tool changes. The"]
2297 #[doc = "value is normalized between -65535 and 65535, with 0 as the logical"]
2298 #[doc = "neutral position of the slider."]
2299 #[doc = ""]
2300 #[doc = "The slider is available on e.g. the Wacom Airbrush tool."]
2301 #[doc = ""]
2302 fn slider(
2303 &self,
2304 client: &mut crate::server::Client,
2305 sender_id: crate::wire::ObjectId,
2306 position: i32,
2307 ) -> impl Future<Output = crate::server::Result<()>> + Send {
2308 async move {
2309 tracing::debug!("-> zwp_tablet_tool_v2#{}.slider({})", sender_id, position);
2310 let (payload, fds) =
2311 crate::wire::PayloadBuilder::new().put_int(position).build();
2312 client
2313 .send_message(crate::wire::Message::new(sender_id, 15u16, payload, fds))
2314 .await
2315 .map_err(crate::server::error::Error::IoError)
2316 }
2317 }
2318 #[doc = ""]
2319 #[doc = "Sent whenever the wheel on the tool emits an event. This event"]
2320 #[doc = "contains two values for the same axis change. The degrees value is"]
2321 #[doc = "in the same orientation as the wl_pointer.vertical_scroll axis. The"]
2322 #[doc = "clicks value is in discrete logical clicks of the mouse wheel. This"]
2323 #[doc = "value may be zero if the movement of the wheel was less"]
2324 #[doc = "than one logical click."]
2325 #[doc = ""]
2326 #[doc = "Clients should choose either value and avoid mixing degrees and"]
2327 #[doc = "clicks. The compositor may accumulate values smaller than a logical"]
2328 #[doc = "click and emulate click events when a certain threshold is met."]
2329 #[doc = "Thus, wl_tablet_tool.wheel events with non-zero clicks values may"]
2330 #[doc = "have different degrees values."]
2331 #[doc = ""]
2332 fn wheel(
2333 &self,
2334 client: &mut crate::server::Client,
2335 sender_id: crate::wire::ObjectId,
2336 degrees: crate::wire::Fixed,
2337 clicks: i32,
2338 ) -> impl Future<Output = crate::server::Result<()>> + Send {
2339 async move {
2340 tracing::debug!(
2341 "-> zwp_tablet_tool_v2#{}.wheel({}, {})",
2342 sender_id,
2343 degrees,
2344 clicks
2345 );
2346 let (payload, fds) = crate::wire::PayloadBuilder::new()
2347 .put_fixed(degrees)
2348 .put_int(clicks)
2349 .build();
2350 client
2351 .send_message(crate::wire::Message::new(sender_id, 16u16, payload, fds))
2352 .await
2353 .map_err(crate::server::error::Error::IoError)
2354 }
2355 }
2356 #[doc = ""]
2357 #[doc = "Sent whenever a button on the tool is pressed or released."]
2358 #[doc = ""]
2359 #[doc = "If a button is held down when the tool moves in or out of proximity,"]
2360 #[doc = "button events are generated by the compositor. See"]
2361 #[doc = "wp_tablet_tool.proximity_in and wp_tablet_tool.proximity_out for"]
2362 #[doc = "details."]
2363 #[doc = ""]
2364 fn button(
2365 &self,
2366 client: &mut crate::server::Client,
2367 sender_id: crate::wire::ObjectId,
2368 serial: u32,
2369 button: u32,
2370 state: ButtonState,
2371 ) -> impl Future<Output = crate::server::Result<()>> + Send {
2372 async move {
2373 tracing::debug!(
2374 "-> zwp_tablet_tool_v2#{}.button({}, {}, {})",
2375 sender_id,
2376 serial,
2377 button,
2378 state
2379 );
2380 let (payload, fds) = crate::wire::PayloadBuilder::new()
2381 .put_uint(serial)
2382 .put_uint(button)
2383 .put_uint(state as u32)
2384 .build();
2385 client
2386 .send_message(crate::wire::Message::new(sender_id, 17u16, payload, fds))
2387 .await
2388 .map_err(crate::server::error::Error::IoError)
2389 }
2390 }
2391 #[doc = ""]
2392 #[doc = "Marks the end of a series of axis and/or button updates from the"]
2393 #[doc = "tablet. The Wayland protocol requires axis updates to be sent"]
2394 #[doc = "sequentially, however all events within a frame should be considered"]
2395 #[doc = "one hardware event."]
2396 #[doc = ""]
2397 fn frame(
2398 &self,
2399 client: &mut crate::server::Client,
2400 sender_id: crate::wire::ObjectId,
2401 time: u32,
2402 ) -> impl Future<Output = crate::server::Result<()>> + Send {
2403 async move {
2404 tracing::debug!("-> zwp_tablet_tool_v2#{}.frame({})", sender_id, time);
2405 let (payload, fds) = crate::wire::PayloadBuilder::new().put_uint(time).build();
2406 client
2407 .send_message(crate::wire::Message::new(sender_id, 18u16, payload, fds))
2408 .await
2409 .map_err(crate::server::error::Error::IoError)
2410 }
2411 }
2412 }
2413 }
2414 #[doc = ""]
2415 #[doc = "The wp_tablet interface represents one graphics tablet device. The"]
2416 #[doc = "tablet interface itself does not generate events; all events are"]
2417 #[doc = "generated by wp_tablet_tool objects when in proximity above a tablet."]
2418 #[doc = ""]
2419 #[doc = "A tablet has a number of static characteristics, e.g. device name and"]
2420 #[doc = "pid/vid. These capabilities are sent in an event sequence after the"]
2421 #[doc = "wp_tablet_seat.tablet_added event. This initial event sequence is"]
2422 #[doc = "terminated by a wp_tablet.done event."]
2423 #[doc = ""]
2424 #[allow(clippy::too_many_arguments)]
2425 pub mod zwp_tablet_v2 {
2426 #[allow(unused)]
2427 use futures_util::SinkExt;
2428 #[allow(unused)]
2429 use std::os::fd::AsRawFd;
2430 #[doc = ""]
2431 #[doc = "Describes the bus types this tablet is connected to."]
2432 #[doc = ""]
2433 #[repr(u32)]
2434 #[non_exhaustive]
2435 #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy)]
2436 pub enum Bustype {
2437 #[doc = "USB"]
2438 Usb = 3u32,
2439 #[doc = "Bluetooth"]
2440 Bluetooth = 5u32,
2441 #[doc = "Virtual"]
2442 Virtual = 6u32,
2443 #[doc = "Serial"]
2444 Serial = 17u32,
2445 #[doc = "I2C"]
2446 I2c = 24u32,
2447 }
2448 impl TryFrom<u32> for Bustype {
2449 type Error = crate::wire::DecodeError;
2450 fn try_from(v: u32) -> Result<Self, Self::Error> {
2451 match v {
2452 3u32 => Ok(Self::Usb),
2453 5u32 => Ok(Self::Bluetooth),
2454 6u32 => Ok(Self::Virtual),
2455 17u32 => Ok(Self::Serial),
2456 24u32 => Ok(Self::I2c),
2457 _ => Err(crate::wire::DecodeError::MalformedPayload),
2458 }
2459 }
2460 }
2461 impl std::fmt::Display for Bustype {
2462 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2463 (*self as u32).fmt(f)
2464 }
2465 }
2466 #[doc = "Trait to implement the zwp_tablet_v2 interface. See the module level documentation for more info"]
2467 pub trait ZwpTabletV2: crate::server::Dispatcher {
2468 const INTERFACE: &'static str = "zwp_tablet_v2";
2469 const VERSION: u32 = 2u32;
2470 fn handle_request(
2471 &self,
2472 client: &mut crate::server::Client,
2473 sender_id: crate::wire::ObjectId,
2474 message: &mut crate::wire::Message,
2475 ) -> impl Future<Output = crate::server::Result<()>> + Send {
2476 async move {
2477 #[allow(clippy::match_single_binding)]
2478 match message.opcode() {
2479 0u16 => {
2480 tracing::debug!("zwp_tablet_v2#{}.destroy()", sender_id,);
2481 let result = self.destroy(client, sender_id).await;
2482 client.remove(sender_id);
2483 result
2484 }
2485 opcode => Err(crate::server::error::Error::UnknownOpcode(opcode)),
2486 }
2487 }
2488 }
2489 #[doc = ""]
2490 #[doc = "This destroys the client's resource for this tablet object."]
2491 #[doc = ""]
2492 fn destroy(
2493 &self,
2494 client: &mut crate::server::Client,
2495 sender_id: crate::wire::ObjectId,
2496 ) -> impl Future<Output = crate::server::Result<()>> + Send;
2497 #[doc = ""]
2498 #[doc = "A descriptive name for the tablet device."]
2499 #[doc = ""]
2500 #[doc = "If the device has no descriptive name, this event is not sent."]
2501 #[doc = ""]
2502 #[doc = "This event is sent in the initial burst of events before the"]
2503 #[doc = "wp_tablet.done event."]
2504 #[doc = ""]
2505 fn name(
2506 &self,
2507 client: &mut crate::server::Client,
2508 sender_id: crate::wire::ObjectId,
2509 name: String,
2510 ) -> impl Future<Output = crate::server::Result<()>> + Send {
2511 async move {
2512 tracing::debug!("-> zwp_tablet_v2#{}.name(\"{}\")", sender_id, name);
2513 let (payload, fds) = crate::wire::PayloadBuilder::new()
2514 .put_string(Some(name))
2515 .build();
2516 client
2517 .send_message(crate::wire::Message::new(sender_id, 0u16, payload, fds))
2518 .await
2519 .map_err(crate::server::error::Error::IoError)
2520 }
2521 }
2522 #[doc = ""]
2523 #[doc = "The vendor and product IDs for the tablet device."]
2524 #[doc = ""]
2525 #[doc = "The interpretation of the id depends on the wp_tablet.bustype."]
2526 #[doc = "Prior to version v2 of this protocol, the id was implied to be a USB"]
2527 #[doc = "vendor and product ID. If no wp_tablet.bustype is sent, the ID"]
2528 #[doc = "is to be interpreted as USB vendor and product ID."]
2529 #[doc = ""]
2530 #[doc = "If the device has no vendor/product ID, this event is not sent."]
2531 #[doc = "This can happen for virtual devices or non-USB devices, for instance."]
2532 #[doc = ""]
2533 #[doc = "This event is sent in the initial burst of events before the"]
2534 #[doc = "wp_tablet.done event."]
2535 #[doc = ""]
2536 fn id(
2537 &self,
2538 client: &mut crate::server::Client,
2539 sender_id: crate::wire::ObjectId,
2540 vid: u32,
2541 pid: u32,
2542 ) -> impl Future<Output = crate::server::Result<()>> + Send {
2543 async move {
2544 tracing::debug!("-> zwp_tablet_v2#{}.id({}, {})", sender_id, vid, pid);
2545 let (payload, fds) = crate::wire::PayloadBuilder::new()
2546 .put_uint(vid)
2547 .put_uint(pid)
2548 .build();
2549 client
2550 .send_message(crate::wire::Message::new(sender_id, 1u16, payload, fds))
2551 .await
2552 .map_err(crate::server::error::Error::IoError)
2553 }
2554 }
2555 #[doc = ""]
2556 #[doc = "A system-specific device path that indicates which device is behind"]
2557 #[doc = "this wp_tablet. This information may be used to gather additional"]
2558 #[doc = "information about the device, e.g. through libwacom."]
2559 #[doc = ""]
2560 #[doc = "A device may have more than one device path. If so, multiple"]
2561 #[doc = "wp_tablet.path events are sent. A device may be emulated and not"]
2562 #[doc = "have a device path, and in that case this event will not be sent."]
2563 #[doc = ""]
2564 #[doc = "The format of the path is unspecified, it may be a device node, a"]
2565 #[doc = "sysfs path, or some other identifier. It is up to the client to"]
2566 #[doc = "identify the string provided."]
2567 #[doc = ""]
2568 #[doc = "This event is sent in the initial burst of events before the"]
2569 #[doc = "wp_tablet.done event."]
2570 #[doc = ""]
2571 fn path(
2572 &self,
2573 client: &mut crate::server::Client,
2574 sender_id: crate::wire::ObjectId,
2575 path: String,
2576 ) -> impl Future<Output = crate::server::Result<()>> + Send {
2577 async move {
2578 tracing::debug!("-> zwp_tablet_v2#{}.path(\"{}\")", sender_id, path);
2579 let (payload, fds) = crate::wire::PayloadBuilder::new()
2580 .put_string(Some(path))
2581 .build();
2582 client
2583 .send_message(crate::wire::Message::new(sender_id, 2u16, payload, fds))
2584 .await
2585 .map_err(crate::server::error::Error::IoError)
2586 }
2587 }
2588 #[doc = ""]
2589 #[doc = "This event is sent immediately to signal the end of the initial"]
2590 #[doc = "burst of descriptive events. A client may consider the static"]
2591 #[doc = "description of the tablet to be complete and finalize initialization"]
2592 #[doc = "of the tablet."]
2593 #[doc = ""]
2594 fn done(
2595 &self,
2596 client: &mut crate::server::Client,
2597 sender_id: crate::wire::ObjectId,
2598 ) -> impl Future<Output = crate::server::Result<()>> + Send {
2599 async move {
2600 tracing::debug!("-> zwp_tablet_v2#{}.done()", sender_id,);
2601 let (payload, fds) = crate::wire::PayloadBuilder::new().build();
2602 client
2603 .send_message(crate::wire::Message::new(sender_id, 3u16, payload, fds))
2604 .await
2605 .map_err(crate::server::error::Error::IoError)
2606 }
2607 }
2608 #[doc = ""]
2609 #[doc = "Sent when the tablet has been removed from the system. When a tablet"]
2610 #[doc = "is removed, some tools may be removed."]
2611 #[doc = ""]
2612 #[doc = "When this event is received, the client must wp_tablet.destroy"]
2613 #[doc = "the object."]
2614 #[doc = ""]
2615 fn removed(
2616 &self,
2617 client: &mut crate::server::Client,
2618 sender_id: crate::wire::ObjectId,
2619 ) -> impl Future<Output = crate::server::Result<()>> + Send {
2620 async move {
2621 tracing::debug!("-> zwp_tablet_v2#{}.removed()", sender_id,);
2622 let (payload, fds) = crate::wire::PayloadBuilder::new().build();
2623 client
2624 .send_message(crate::wire::Message::new(sender_id, 4u16, payload, fds))
2625 .await
2626 .map_err(crate::server::error::Error::IoError)
2627 }
2628 }
2629 #[doc = ""]
2630 #[doc = "The bustype argument is one of the BUS_ defines in the Linux kernel's"]
2631 #[doc = "linux/input.h"]
2632 #[doc = ""]
2633 #[doc = "If the device has no known bustype or the bustype cannot be"]
2634 #[doc = "queried, this event is not sent."]
2635 #[doc = ""]
2636 #[doc = "This event is sent in the initial burst of events before the"]
2637 #[doc = "wp_tablet.done event."]
2638 #[doc = ""]
2639 fn bustype(
2640 &self,
2641 client: &mut crate::server::Client,
2642 sender_id: crate::wire::ObjectId,
2643 bustype: Bustype,
2644 ) -> impl Future<Output = crate::server::Result<()>> + Send {
2645 async move {
2646 tracing::debug!("-> zwp_tablet_v2#{}.bustype({})", sender_id, bustype);
2647 let (payload, fds) = crate::wire::PayloadBuilder::new()
2648 .put_uint(bustype as u32)
2649 .build();
2650 client
2651 .send_message(crate::wire::Message::new(sender_id, 5u16, payload, fds))
2652 .await
2653 .map_err(crate::server::error::Error::IoError)
2654 }
2655 }
2656 }
2657 }
2658 #[doc = ""]
2659 #[doc = "A circular interaction area, such as the touch ring on the Wacom Intuos"]
2660 #[doc = "Pro series tablets."]
2661 #[doc = ""]
2662 #[doc = "Events on a ring are logically grouped by the wl_tablet_pad_ring.frame"]
2663 #[doc = "event."]
2664 #[doc = ""]
2665 #[allow(clippy::too_many_arguments)]
2666 pub mod zwp_tablet_pad_ring_v2 {
2667 #[allow(unused)]
2668 use futures_util::SinkExt;
2669 #[allow(unused)]
2670 use std::os::fd::AsRawFd;
2671 #[doc = ""]
2672 #[doc = "Describes the source types for ring events. This indicates to the"]
2673 #[doc = "client how a ring event was physically generated; a client may"]
2674 #[doc = "adjust the user interface accordingly. For example, events"]
2675 #[doc = "from a \"finger\" source may trigger kinetic scrolling."]
2676 #[doc = ""]
2677 #[repr(u32)]
2678 #[non_exhaustive]
2679 #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy)]
2680 pub enum Source {
2681 #[doc = "finger"]
2682 Finger = 1u32,
2683 }
2684 impl TryFrom<u32> for Source {
2685 type Error = crate::wire::DecodeError;
2686 fn try_from(v: u32) -> Result<Self, Self::Error> {
2687 match v {
2688 1u32 => Ok(Self::Finger),
2689 _ => Err(crate::wire::DecodeError::MalformedPayload),
2690 }
2691 }
2692 }
2693 impl std::fmt::Display for Source {
2694 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2695 (*self as u32).fmt(f)
2696 }
2697 }
2698 #[doc = "Trait to implement the zwp_tablet_pad_ring_v2 interface. See the module level documentation for more info"]
2699 pub trait ZwpTabletPadRingV2: crate::server::Dispatcher {
2700 const INTERFACE: &'static str = "zwp_tablet_pad_ring_v2";
2701 const VERSION: u32 = 2u32;
2702 fn handle_request(
2703 &self,
2704 client: &mut crate::server::Client,
2705 sender_id: crate::wire::ObjectId,
2706 message: &mut crate::wire::Message,
2707 ) -> impl Future<Output = crate::server::Result<()>> + Send {
2708 async move {
2709 #[allow(clippy::match_single_binding)]
2710 match message.opcode() {
2711 0u16 => {
2712 let description = message
2713 .string()?
2714 .ok_or(crate::wire::DecodeError::MalformedPayload)?;
2715 let serial = message.uint()?;
2716 tracing::debug!(
2717 "zwp_tablet_pad_ring_v2#{}.set_feedback(\"{}\", {})",
2718 sender_id,
2719 description,
2720 serial
2721 );
2722 self.set_feedback(client, sender_id, description, serial)
2723 .await
2724 }
2725 1u16 => {
2726 tracing::debug!("zwp_tablet_pad_ring_v2#{}.destroy()", sender_id,);
2727 let result = self.destroy(client, sender_id).await;
2728 client.remove(sender_id);
2729 result
2730 }
2731 opcode => Err(crate::server::error::Error::UnknownOpcode(opcode)),
2732 }
2733 }
2734 }
2735 #[doc = ""]
2736 #[doc = "Request that the compositor use the provided feedback string"]
2737 #[doc = "associated with this ring. This request should be issued immediately"]
2738 #[doc = "after a wp_tablet_pad_group.mode_switch event from the corresponding"]
2739 #[doc = "group is received, or whenever the ring is mapped to a different"]
2740 #[doc = "action. See wp_tablet_pad_group.mode_switch for more details."]
2741 #[doc = ""]
2742 #[doc = "Clients are encouraged to provide context-aware descriptions for"]
2743 #[doc = "the actions associated with the ring; compositors may use this"]
2744 #[doc = "information to offer visual feedback about the button layout"]
2745 #[doc = "(eg. on-screen displays)."]
2746 #[doc = ""]
2747 #[doc = "The provided string 'description' is a UTF-8 encoded string to be"]
2748 #[doc = "associated with this ring, and is considered user-visible; general"]
2749 #[doc = "internationalization rules apply."]
2750 #[doc = ""]
2751 #[doc = "The serial argument will be that of the last"]
2752 #[doc = "wp_tablet_pad_group.mode_switch event received for the group of this"]
2753 #[doc = "ring. Requests providing other serials than the most recent one will be"]
2754 #[doc = "ignored."]
2755 #[doc = ""]
2756 fn set_feedback(
2757 &self,
2758 client: &mut crate::server::Client,
2759 sender_id: crate::wire::ObjectId,
2760 description: String,
2761 serial: u32,
2762 ) -> impl Future<Output = crate::server::Result<()>> + Send;
2763 #[doc = ""]
2764 #[doc = "This destroys the client's resource for this ring object."]
2765 #[doc = ""]
2766 fn destroy(
2767 &self,
2768 client: &mut crate::server::Client,
2769 sender_id: crate::wire::ObjectId,
2770 ) -> impl Future<Output = crate::server::Result<()>> + Send;
2771 #[doc = ""]
2772 #[doc = "Source information for ring events."]
2773 #[doc = ""]
2774 #[doc = "This event does not occur on its own. It is sent before a"]
2775 #[doc = "wp_tablet_pad_ring.frame event and carries the source information"]
2776 #[doc = "for all events within that frame."]
2777 #[doc = ""]
2778 #[doc = "The source specifies how this event was generated. If the source is"]
2779 #[doc = "wp_tablet_pad_ring.source.finger, a wp_tablet_pad_ring.stop event"]
2780 #[doc = "will be sent when the user lifts the finger off the device."]
2781 #[doc = ""]
2782 #[doc = "This event is optional. If the source is unknown for an interaction,"]
2783 #[doc = "no event is sent."]
2784 #[doc = ""]
2785 fn source(
2786 &self,
2787 client: &mut crate::server::Client,
2788 sender_id: crate::wire::ObjectId,
2789 source: Source,
2790 ) -> impl Future<Output = crate::server::Result<()>> + Send {
2791 async move {
2792 tracing::debug!("-> zwp_tablet_pad_ring_v2#{}.source({})", sender_id, source);
2793 let (payload, fds) = crate::wire::PayloadBuilder::new()
2794 .put_uint(source as u32)
2795 .build();
2796 client
2797 .send_message(crate::wire::Message::new(sender_id, 0u16, payload, fds))
2798 .await
2799 .map_err(crate::server::error::Error::IoError)
2800 }
2801 }
2802 #[doc = ""]
2803 #[doc = "Sent whenever the angle on a ring changes."]
2804 #[doc = ""]
2805 #[doc = "The angle is provided in degrees clockwise from the logical"]
2806 #[doc = "north of the ring in the pad's current rotation."]
2807 #[doc = ""]
2808 fn angle(
2809 &self,
2810 client: &mut crate::server::Client,
2811 sender_id: crate::wire::ObjectId,
2812 degrees: crate::wire::Fixed,
2813 ) -> impl Future<Output = crate::server::Result<()>> + Send {
2814 async move {
2815 tracing::debug!("-> zwp_tablet_pad_ring_v2#{}.angle({})", sender_id, degrees);
2816 let (payload, fds) = crate::wire::PayloadBuilder::new()
2817 .put_fixed(degrees)
2818 .build();
2819 client
2820 .send_message(crate::wire::Message::new(sender_id, 1u16, payload, fds))
2821 .await
2822 .map_err(crate::server::error::Error::IoError)
2823 }
2824 }
2825 #[doc = ""]
2826 #[doc = "Stop notification for ring events."]
2827 #[doc = ""]
2828 #[doc = "For some wp_tablet_pad_ring.source types, a wp_tablet_pad_ring.stop"]
2829 #[doc = "event is sent to notify a client that the interaction with the ring"]
2830 #[doc = "has terminated. This enables the client to implement kinetic scrolling."]
2831 #[doc = "See the wp_tablet_pad_ring.source documentation for information on"]
2832 #[doc = "when this event may be generated."]
2833 #[doc = ""]
2834 #[doc = "Any wp_tablet_pad_ring.angle events with the same source after this"]
2835 #[doc = "event should be considered as the start of a new interaction."]
2836 #[doc = ""]
2837 fn stop(
2838 &self,
2839 client: &mut crate::server::Client,
2840 sender_id: crate::wire::ObjectId,
2841 ) -> impl Future<Output = crate::server::Result<()>> + Send {
2842 async move {
2843 tracing::debug!("-> zwp_tablet_pad_ring_v2#{}.stop()", sender_id,);
2844 let (payload, fds) = crate::wire::PayloadBuilder::new().build();
2845 client
2846 .send_message(crate::wire::Message::new(sender_id, 2u16, payload, fds))
2847 .await
2848 .map_err(crate::server::error::Error::IoError)
2849 }
2850 }
2851 #[doc = ""]
2852 #[doc = "Indicates the end of a set of ring events that logically belong"]
2853 #[doc = "together. A client is expected to accumulate the data in all events"]
2854 #[doc = "within the frame before proceeding."]
2855 #[doc = ""]
2856 #[doc = "All wp_tablet_pad_ring events before a wp_tablet_pad_ring.frame event belong"]
2857 #[doc = "logically together. For example, on termination of a finger interaction"]
2858 #[doc = "on a ring the compositor will send a wp_tablet_pad_ring.source event,"]
2859 #[doc = "a wp_tablet_pad_ring.stop event and a wp_tablet_pad_ring.frame event."]
2860 #[doc = ""]
2861 #[doc = "A wp_tablet_pad_ring.frame event is sent for every logical event"]
2862 #[doc = "group, even if the group only contains a single wp_tablet_pad_ring"]
2863 #[doc = "event. Specifically, a client may get a sequence: angle, frame,"]
2864 #[doc = "angle, frame, etc."]
2865 #[doc = ""]
2866 fn frame(
2867 &self,
2868 client: &mut crate::server::Client,
2869 sender_id: crate::wire::ObjectId,
2870 time: u32,
2871 ) -> impl Future<Output = crate::server::Result<()>> + Send {
2872 async move {
2873 tracing::debug!("-> zwp_tablet_pad_ring_v2#{}.frame({})", sender_id, time);
2874 let (payload, fds) = crate::wire::PayloadBuilder::new().put_uint(time).build();
2875 client
2876 .send_message(crate::wire::Message::new(sender_id, 3u16, payload, fds))
2877 .await
2878 .map_err(crate::server::error::Error::IoError)
2879 }
2880 }
2881 }
2882 }
2883 #[doc = ""]
2884 #[doc = "A linear interaction area, such as the strips found in Wacom Cintiq"]
2885 #[doc = "models."]
2886 #[doc = ""]
2887 #[doc = "Events on a strip are logically grouped by the wl_tablet_pad_strip.frame"]
2888 #[doc = "event."]
2889 #[doc = ""]
2890 #[allow(clippy::too_many_arguments)]
2891 pub mod zwp_tablet_pad_strip_v2 {
2892 #[allow(unused)]
2893 use futures_util::SinkExt;
2894 #[allow(unused)]
2895 use std::os::fd::AsRawFd;
2896 #[doc = ""]
2897 #[doc = "Describes the source types for strip events. This indicates to the"]
2898 #[doc = "client how a strip event was physically generated; a client may"]
2899 #[doc = "adjust the user interface accordingly. For example, events"]
2900 #[doc = "from a \"finger\" source may trigger kinetic scrolling."]
2901 #[doc = ""]
2902 #[repr(u32)]
2903 #[non_exhaustive]
2904 #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy)]
2905 pub enum Source {
2906 #[doc = "finger"]
2907 Finger = 1u32,
2908 }
2909 impl TryFrom<u32> for Source {
2910 type Error = crate::wire::DecodeError;
2911 fn try_from(v: u32) -> Result<Self, Self::Error> {
2912 match v {
2913 1u32 => Ok(Self::Finger),
2914 _ => Err(crate::wire::DecodeError::MalformedPayload),
2915 }
2916 }
2917 }
2918 impl std::fmt::Display for Source {
2919 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2920 (*self as u32).fmt(f)
2921 }
2922 }
2923 #[doc = "Trait to implement the zwp_tablet_pad_strip_v2 interface. See the module level documentation for more info"]
2924 pub trait ZwpTabletPadStripV2: crate::server::Dispatcher {
2925 const INTERFACE: &'static str = "zwp_tablet_pad_strip_v2";
2926 const VERSION: u32 = 2u32;
2927 fn handle_request(
2928 &self,
2929 client: &mut crate::server::Client,
2930 sender_id: crate::wire::ObjectId,
2931 message: &mut crate::wire::Message,
2932 ) -> impl Future<Output = crate::server::Result<()>> + Send {
2933 async move {
2934 #[allow(clippy::match_single_binding)]
2935 match message.opcode() {
2936 0u16 => {
2937 let description = message
2938 .string()?
2939 .ok_or(crate::wire::DecodeError::MalformedPayload)?;
2940 let serial = message.uint()?;
2941 tracing::debug!(
2942 "zwp_tablet_pad_strip_v2#{}.set_feedback(\"{}\", {})",
2943 sender_id,
2944 description,
2945 serial
2946 );
2947 self.set_feedback(client, sender_id, description, serial)
2948 .await
2949 }
2950 1u16 => {
2951 tracing::debug!("zwp_tablet_pad_strip_v2#{}.destroy()", sender_id,);
2952 let result = self.destroy(client, sender_id).await;
2953 client.remove(sender_id);
2954 result
2955 }
2956 opcode => Err(crate::server::error::Error::UnknownOpcode(opcode)),
2957 }
2958 }
2959 }
2960 #[doc = ""]
2961 #[doc = "Requests the compositor to use the provided feedback string"]
2962 #[doc = "associated with this strip. This request should be issued immediately"]
2963 #[doc = "after a wp_tablet_pad_group.mode_switch event from the corresponding"]
2964 #[doc = "group is received, or whenever the strip is mapped to a different"]
2965 #[doc = "action. See wp_tablet_pad_group.mode_switch for more details."]
2966 #[doc = ""]
2967 #[doc = "Clients are encouraged to provide context-aware descriptions for"]
2968 #[doc = "the actions associated with the strip, and compositors may use this"]
2969 #[doc = "information to offer visual feedback about the button layout"]
2970 #[doc = "(eg. on-screen displays)."]
2971 #[doc = ""]
2972 #[doc = "The provided string 'description' is a UTF-8 encoded string to be"]
2973 #[doc = "associated with this ring, and is considered user-visible; general"]
2974 #[doc = "internationalization rules apply."]
2975 #[doc = ""]
2976 #[doc = "The serial argument will be that of the last"]
2977 #[doc = "wp_tablet_pad_group.mode_switch event received for the group of this"]
2978 #[doc = "strip. Requests providing other serials than the most recent one will be"]
2979 #[doc = "ignored."]
2980 #[doc = ""]
2981 fn set_feedback(
2982 &self,
2983 client: &mut crate::server::Client,
2984 sender_id: crate::wire::ObjectId,
2985 description: String,
2986 serial: u32,
2987 ) -> impl Future<Output = crate::server::Result<()>> + Send;
2988 #[doc = ""]
2989 #[doc = "This destroys the client's resource for this strip object."]
2990 #[doc = ""]
2991 fn destroy(
2992 &self,
2993 client: &mut crate::server::Client,
2994 sender_id: crate::wire::ObjectId,
2995 ) -> impl Future<Output = crate::server::Result<()>> + Send;
2996 #[doc = ""]
2997 #[doc = "Source information for strip events."]
2998 #[doc = ""]
2999 #[doc = "This event does not occur on its own. It is sent before a"]
3000 #[doc = "wp_tablet_pad_strip.frame event and carries the source information"]
3001 #[doc = "for all events within that frame."]
3002 #[doc = ""]
3003 #[doc = "The source specifies how this event was generated. If the source is"]
3004 #[doc = "wp_tablet_pad_strip.source.finger, a wp_tablet_pad_strip.stop event"]
3005 #[doc = "will be sent when the user lifts their finger off the device."]
3006 #[doc = ""]
3007 #[doc = "This event is optional. If the source is unknown for an interaction,"]
3008 #[doc = "no event is sent."]
3009 #[doc = ""]
3010 fn source(
3011 &self,
3012 client: &mut crate::server::Client,
3013 sender_id: crate::wire::ObjectId,
3014 source: Source,
3015 ) -> impl Future<Output = crate::server::Result<()>> + Send {
3016 async move {
3017 tracing::debug!(
3018 "-> zwp_tablet_pad_strip_v2#{}.source({})",
3019 sender_id,
3020 source
3021 );
3022 let (payload, fds) = crate::wire::PayloadBuilder::new()
3023 .put_uint(source as u32)
3024 .build();
3025 client
3026 .send_message(crate::wire::Message::new(sender_id, 0u16, payload, fds))
3027 .await
3028 .map_err(crate::server::error::Error::IoError)
3029 }
3030 }
3031 #[doc = ""]
3032 #[doc = "Sent whenever the position on a strip changes."]
3033 #[doc = ""]
3034 #[doc = "The position is normalized to a range of [0, 65535], the 0-value"]
3035 #[doc = "represents the top-most and/or left-most position of the strip in"]
3036 #[doc = "the pad's current rotation."]
3037 #[doc = ""]
3038 fn position(
3039 &self,
3040 client: &mut crate::server::Client,
3041 sender_id: crate::wire::ObjectId,
3042 position: u32,
3043 ) -> impl Future<Output = crate::server::Result<()>> + Send {
3044 async move {
3045 tracing::debug!(
3046 "-> zwp_tablet_pad_strip_v2#{}.position({})",
3047 sender_id,
3048 position
3049 );
3050 let (payload, fds) = crate::wire::PayloadBuilder::new()
3051 .put_uint(position)
3052 .build();
3053 client
3054 .send_message(crate::wire::Message::new(sender_id, 1u16, payload, fds))
3055 .await
3056 .map_err(crate::server::error::Error::IoError)
3057 }
3058 }
3059 #[doc = ""]
3060 #[doc = "Stop notification for strip events."]
3061 #[doc = ""]
3062 #[doc = "For some wp_tablet_pad_strip.source types, a wp_tablet_pad_strip.stop"]
3063 #[doc = "event is sent to notify a client that the interaction with the strip"]
3064 #[doc = "has terminated. This enables the client to implement kinetic"]
3065 #[doc = "scrolling. See the wp_tablet_pad_strip.source documentation for"]
3066 #[doc = "information on when this event may be generated."]
3067 #[doc = ""]
3068 #[doc = "Any wp_tablet_pad_strip.position events with the same source after this"]
3069 #[doc = "event should be considered as the start of a new interaction."]
3070 #[doc = ""]
3071 fn stop(
3072 &self,
3073 client: &mut crate::server::Client,
3074 sender_id: crate::wire::ObjectId,
3075 ) -> impl Future<Output = crate::server::Result<()>> + Send {
3076 async move {
3077 tracing::debug!("-> zwp_tablet_pad_strip_v2#{}.stop()", sender_id,);
3078 let (payload, fds) = crate::wire::PayloadBuilder::new().build();
3079 client
3080 .send_message(crate::wire::Message::new(sender_id, 2u16, payload, fds))
3081 .await
3082 .map_err(crate::server::error::Error::IoError)
3083 }
3084 }
3085 #[doc = ""]
3086 #[doc = "Indicates the end of a set of events that represent one logical"]
3087 #[doc = "hardware strip event. A client is expected to accumulate the data"]
3088 #[doc = "in all events within the frame before proceeding."]
3089 #[doc = ""]
3090 #[doc = "All wp_tablet_pad_strip events before a wp_tablet_pad_strip.frame event belong"]
3091 #[doc = "logically together. For example, on termination of a finger interaction"]
3092 #[doc = "on a strip the compositor will send a wp_tablet_pad_strip.source event,"]
3093 #[doc = "a wp_tablet_pad_strip.stop event and a wp_tablet_pad_strip.frame"]
3094 #[doc = "event."]
3095 #[doc = ""]
3096 #[doc = "A wp_tablet_pad_strip.frame event is sent for every logical event"]
3097 #[doc = "group, even if the group only contains a single wp_tablet_pad_strip"]
3098 #[doc = "event. Specifically, a client may get a sequence: position, frame,"]
3099 #[doc = "position, frame, etc."]
3100 #[doc = ""]
3101 fn frame(
3102 &self,
3103 client: &mut crate::server::Client,
3104 sender_id: crate::wire::ObjectId,
3105 time: u32,
3106 ) -> impl Future<Output = crate::server::Result<()>> + Send {
3107 async move {
3108 tracing::debug!("-> zwp_tablet_pad_strip_v2#{}.frame({})", sender_id, time);
3109 let (payload, fds) = crate::wire::PayloadBuilder::new().put_uint(time).build();
3110 client
3111 .send_message(crate::wire::Message::new(sender_id, 3u16, payload, fds))
3112 .await
3113 .map_err(crate::server::error::Error::IoError)
3114 }
3115 }
3116 }
3117 }
3118 #[doc = ""]
3119 #[doc = "A pad group describes a distinct (sub)set of buttons, rings and strips"]
3120 #[doc = "present in the tablet. The criteria of this grouping is usually positional,"]
3121 #[doc = "eg. if a tablet has buttons on the left and right side, 2 groups will be"]
3122 #[doc = "presented. The physical arrangement of groups is undisclosed and may"]
3123 #[doc = "change on the fly."]
3124 #[doc = ""]
3125 #[doc = "Pad groups will announce their features during pad initialization. Between"]
3126 #[doc = "the corresponding wp_tablet_pad.group event and wp_tablet_pad_group.done, the"]
3127 #[doc = "pad group will announce the buttons, rings and strips contained in it,"]
3128 #[doc = "plus the number of supported modes."]
3129 #[doc = ""]
3130 #[doc = "Modes are a mechanism to allow multiple groups of actions for every element"]
3131 #[doc = "in the pad group. The number of groups and available modes in each is"]
3132 #[doc = "persistent across device plugs. The current mode is user-switchable, it"]
3133 #[doc = "will be announced through the wp_tablet_pad_group.mode_switch event both"]
3134 #[doc = "whenever it is switched, and after wp_tablet_pad.enter."]
3135 #[doc = ""]
3136 #[doc = "The current mode logically applies to all elements in the pad group,"]
3137 #[doc = "although it is at clients' discretion whether to actually perform different"]
3138 #[doc = "actions, and/or issue the respective .set_feedback requests to notify the"]
3139 #[doc = "compositor. See the wp_tablet_pad_group.mode_switch event for more details."]
3140 #[doc = ""]
3141 #[allow(clippy::too_many_arguments)]
3142 pub mod zwp_tablet_pad_group_v2 {
3143 #[allow(unused)]
3144 use futures_util::SinkExt;
3145 #[allow(unused)]
3146 use std::os::fd::AsRawFd;
3147 #[doc = "Trait to implement the zwp_tablet_pad_group_v2 interface. See the module level documentation for more info"]
3148 pub trait ZwpTabletPadGroupV2: crate::server::Dispatcher {
3149 const INTERFACE: &'static str = "zwp_tablet_pad_group_v2";
3150 const VERSION: u32 = 2u32;
3151 fn handle_request(
3152 &self,
3153 client: &mut crate::server::Client,
3154 sender_id: crate::wire::ObjectId,
3155 message: &mut crate::wire::Message,
3156 ) -> impl Future<Output = crate::server::Result<()>> + Send {
3157 async move {
3158 #[allow(clippy::match_single_binding)]
3159 match message.opcode() {
3160 0u16 => {
3161 tracing::debug!("zwp_tablet_pad_group_v2#{}.destroy()", sender_id,);
3162 let result = self.destroy(client, sender_id).await;
3163 client.remove(sender_id);
3164 result
3165 }
3166 opcode => Err(crate::server::error::Error::UnknownOpcode(opcode)),
3167 }
3168 }
3169 }
3170 #[doc = ""]
3171 #[doc = "Destroy the wp_tablet_pad_group object. Objects created from this object"]
3172 #[doc = "are unaffected and should be destroyed separately."]
3173 #[doc = ""]
3174 fn destroy(
3175 &self,
3176 client: &mut crate::server::Client,
3177 sender_id: crate::wire::ObjectId,
3178 ) -> impl Future<Output = crate::server::Result<()>> + Send;
3179 #[doc = ""]
3180 #[doc = "Sent on wp_tablet_pad_group initialization to announce the available"]
3181 #[doc = "buttons in the group. Button indices start at 0, a button may only be"]
3182 #[doc = "in one group at a time."]
3183 #[doc = ""]
3184 #[doc = "This event is first sent in the initial burst of events before the"]
3185 #[doc = "wp_tablet_pad_group.done event."]
3186 #[doc = ""]
3187 #[doc = "Some buttons are reserved by the compositor. These buttons may not be"]
3188 #[doc = "assigned to any wp_tablet_pad_group. Compositors may broadcast this"]
3189 #[doc = "event in the case of changes to the mapping of these reserved buttons."]
3190 #[doc = "If the compositor happens to reserve all buttons in a group, this event"]
3191 #[doc = "will be sent with an empty array."]
3192 #[doc = ""]
3193 fn buttons(
3194 &self,
3195 client: &mut crate::server::Client,
3196 sender_id: crate::wire::ObjectId,
3197 buttons: Vec<u8>,
3198 ) -> impl Future<Output = crate::server::Result<()>> + Send {
3199 async move {
3200 tracing::debug!(
3201 "-> zwp_tablet_pad_group_v2#{}.buttons(array[{}])",
3202 sender_id,
3203 buttons.len()
3204 );
3205 let (payload, fds) = crate::wire::PayloadBuilder::new()
3206 .put_array(buttons)
3207 .build();
3208 client
3209 .send_message(crate::wire::Message::new(sender_id, 0u16, payload, fds))
3210 .await
3211 .map_err(crate::server::error::Error::IoError)
3212 }
3213 }
3214 #[doc = ""]
3215 #[doc = "Sent on wp_tablet_pad_group initialization to announce available rings."]
3216 #[doc = "One event is sent for each ring available on this pad group."]
3217 #[doc = ""]
3218 #[doc = "This event is sent in the initial burst of events before the"]
3219 #[doc = "wp_tablet_pad_group.done event."]
3220 #[doc = ""]
3221 fn ring(
3222 &self,
3223 client: &mut crate::server::Client,
3224 sender_id: crate::wire::ObjectId,
3225 ring: crate::wire::ObjectId,
3226 ) -> impl Future<Output = crate::server::Result<()>> + Send {
3227 async move {
3228 tracing::debug!("-> zwp_tablet_pad_group_v2#{}.ring({})", sender_id, ring);
3229 let (payload, fds) = crate::wire::PayloadBuilder::new()
3230 .put_object(Some(ring))
3231 .build();
3232 client
3233 .send_message(crate::wire::Message::new(sender_id, 1u16, payload, fds))
3234 .await
3235 .map_err(crate::server::error::Error::IoError)
3236 }
3237 }
3238 #[doc = ""]
3239 #[doc = "Sent on wp_tablet_pad initialization to announce available strips."]
3240 #[doc = "One event is sent for each strip available on this pad group."]
3241 #[doc = ""]
3242 #[doc = "This event is sent in the initial burst of events before the"]
3243 #[doc = "wp_tablet_pad_group.done event."]
3244 #[doc = ""]
3245 fn strip(
3246 &self,
3247 client: &mut crate::server::Client,
3248 sender_id: crate::wire::ObjectId,
3249 strip: crate::wire::ObjectId,
3250 ) -> impl Future<Output = crate::server::Result<()>> + Send {
3251 async move {
3252 tracing::debug!("-> zwp_tablet_pad_group_v2#{}.strip({})", sender_id, strip);
3253 let (payload, fds) = crate::wire::PayloadBuilder::new()
3254 .put_object(Some(strip))
3255 .build();
3256 client
3257 .send_message(crate::wire::Message::new(sender_id, 2u16, payload, fds))
3258 .await
3259 .map_err(crate::server::error::Error::IoError)
3260 }
3261 }
3262 #[doc = ""]
3263 #[doc = "Sent on wp_tablet_pad_group initialization to announce that the pad"]
3264 #[doc = "group may switch between modes. A client may use a mode to store a"]
3265 #[doc = "specific configuration for buttons, rings and strips and use the"]
3266 #[doc = "wl_tablet_pad_group.mode_switch event to toggle between these"]
3267 #[doc = "configurations. Mode indices start at 0."]
3268 #[doc = ""]
3269 #[doc = "Switching modes is compositor-dependent. See the"]
3270 #[doc = "wp_tablet_pad_group.mode_switch event for more details."]
3271 #[doc = ""]
3272 #[doc = "This event is sent in the initial burst of events before the"]
3273 #[doc = "wp_tablet_pad_group.done event. This event is only sent when more than"]
3274 #[doc = "more than one mode is available."]
3275 #[doc = ""]
3276 fn modes(
3277 &self,
3278 client: &mut crate::server::Client,
3279 sender_id: crate::wire::ObjectId,
3280 modes: u32,
3281 ) -> impl Future<Output = crate::server::Result<()>> + Send {
3282 async move {
3283 tracing::debug!("-> zwp_tablet_pad_group_v2#{}.modes({})", sender_id, modes);
3284 let (payload, fds) = crate::wire::PayloadBuilder::new().put_uint(modes).build();
3285 client
3286 .send_message(crate::wire::Message::new(sender_id, 3u16, payload, fds))
3287 .await
3288 .map_err(crate::server::error::Error::IoError)
3289 }
3290 }
3291 #[doc = ""]
3292 #[doc = "This event is sent immediately to signal the end of the initial"]
3293 #[doc = "burst of descriptive events. A client may consider the static"]
3294 #[doc = "description of the tablet to be complete and finalize initialization"]
3295 #[doc = "of the tablet group."]
3296 #[doc = ""]
3297 fn done(
3298 &self,
3299 client: &mut crate::server::Client,
3300 sender_id: crate::wire::ObjectId,
3301 ) -> impl Future<Output = crate::server::Result<()>> + Send {
3302 async move {
3303 tracing::debug!("-> zwp_tablet_pad_group_v2#{}.done()", sender_id,);
3304 let (payload, fds) = crate::wire::PayloadBuilder::new().build();
3305 client
3306 .send_message(crate::wire::Message::new(sender_id, 4u16, payload, fds))
3307 .await
3308 .map_err(crate::server::error::Error::IoError)
3309 }
3310 }
3311 #[doc = ""]
3312 #[doc = "Notification that the mode was switched."]
3313 #[doc = ""]
3314 #[doc = "A mode applies to all buttons, rings, strips and dials in a group"]
3315 #[doc = "simultaneously, but a client is not required to assign different actions"]
3316 #[doc = "for each mode. For example, a client may have mode-specific button"]
3317 #[doc = "mappings but map the ring to vertical scrolling in all modes. Mode"]
3318 #[doc = "indices start at 0."]
3319 #[doc = ""]
3320 #[doc = "Switching modes is compositor-dependent. The compositor may provide"]
3321 #[doc = "visual cues to the user about the mode, e.g. by toggling LEDs on"]
3322 #[doc = "the tablet device. Mode-switching may be software-controlled or"]
3323 #[doc = "controlled by one or more physical buttons. For example, on a Wacom"]
3324 #[doc = "Intuos Pro, the button inside the ring may be assigned to switch"]
3325 #[doc = "between modes."]
3326 #[doc = ""]
3327 #[doc = "The compositor will also send this event after wp_tablet_pad.enter on"]
3328 #[doc = "each group in order to notify of the current mode. Groups that only"]
3329 #[doc = "feature one mode will use mode=0 when emitting this event."]
3330 #[doc = ""]
3331 #[doc = "If a button action in the new mode differs from the action in the"]
3332 #[doc = "previous mode, the client should immediately issue a"]
3333 #[doc = "wp_tablet_pad.set_feedback request for each changed button."]
3334 #[doc = ""]
3335 #[doc = "If a ring, strip or dial action in the new mode differs from the action"]
3336 #[doc = "in the previous mode, the client should immediately issue a"]
3337 #[doc = "wp_tablet_ring.set_feedback, wp_tablet_strip.set_feedback or"]
3338 #[doc = "wp_tablet_dial.set_feedback request for each changed ring, strip or dial."]
3339 #[doc = ""]
3340 fn mode_switch(
3341 &self,
3342 client: &mut crate::server::Client,
3343 sender_id: crate::wire::ObjectId,
3344 time: u32,
3345 serial: u32,
3346 mode: u32,
3347 ) -> impl Future<Output = crate::server::Result<()>> + Send {
3348 async move {
3349 tracing::debug!(
3350 "-> zwp_tablet_pad_group_v2#{}.mode_switch({}, {}, {})",
3351 sender_id,
3352 time,
3353 serial,
3354 mode
3355 );
3356 let (payload, fds) = crate::wire::PayloadBuilder::new()
3357 .put_uint(time)
3358 .put_uint(serial)
3359 .put_uint(mode)
3360 .build();
3361 client
3362 .send_message(crate::wire::Message::new(sender_id, 5u16, payload, fds))
3363 .await
3364 .map_err(crate::server::error::Error::IoError)
3365 }
3366 }
3367 #[doc = ""]
3368 #[doc = "Sent on wp_tablet_pad initialization to announce available dials."]
3369 #[doc = "One event is sent for each dial available on this pad group."]
3370 #[doc = ""]
3371 #[doc = "This event is sent in the initial burst of events before the"]
3372 #[doc = "wp_tablet_pad_group.done event."]
3373 #[doc = ""]
3374 fn dial(
3375 &self,
3376 client: &mut crate::server::Client,
3377 sender_id: crate::wire::ObjectId,
3378 dial: crate::wire::ObjectId,
3379 ) -> impl Future<Output = crate::server::Result<()>> + Send {
3380 async move {
3381 tracing::debug!("-> zwp_tablet_pad_group_v2#{}.dial({})", sender_id, dial);
3382 let (payload, fds) = crate::wire::PayloadBuilder::new()
3383 .put_object(Some(dial))
3384 .build();
3385 client
3386 .send_message(crate::wire::Message::new(sender_id, 6u16, payload, fds))
3387 .await
3388 .map_err(crate::server::error::Error::IoError)
3389 }
3390 }
3391 }
3392 }
3393 #[doc = ""]
3394 #[doc = "A pad device is a set of buttons, rings, strips and dials"]
3395 #[doc = "usually physically present on the tablet device itself. Some"]
3396 #[doc = "exceptions exist where the pad device is physically detached, e.g. the"]
3397 #[doc = "Wacom ExpressKey Remote."]
3398 #[doc = ""]
3399 #[doc = "Pad devices have no axes that control the cursor and are generally"]
3400 #[doc = "auxiliary devices to the tool devices used on the tablet surface."]
3401 #[doc = ""]
3402 #[doc = "A pad device has a number of static characteristics, e.g. the number"]
3403 #[doc = "of rings. These capabilities are sent in an event sequence after the"]
3404 #[doc = "wp_tablet_seat.pad_added event before any actual events from this pad."]
3405 #[doc = "This initial event sequence is terminated by a wp_tablet_pad.done"]
3406 #[doc = "event."]
3407 #[doc = ""]
3408 #[doc = "All pad features (buttons, rings, strips and dials) are logically divided into"]
3409 #[doc = "groups and all pads have at least one group. The available groups are"]
3410 #[doc = "notified through the wp_tablet_pad.group event; the compositor will"]
3411 #[doc = "emit one event per group before emitting wp_tablet_pad.done."]
3412 #[doc = ""]
3413 #[doc = "Groups may have multiple modes. Modes allow clients to map multiple"]
3414 #[doc = "actions to a single pad feature. Only one mode can be active per group,"]
3415 #[doc = "although different groups may have different active modes."]
3416 #[doc = ""]
3417 #[allow(clippy::too_many_arguments)]
3418 pub mod zwp_tablet_pad_v2 {
3419 #[allow(unused)]
3420 use futures_util::SinkExt;
3421 #[allow(unused)]
3422 use std::os::fd::AsRawFd;
3423 #[doc = ""]
3424 #[doc = "Describes the physical state of a button that caused the button"]
3425 #[doc = "event."]
3426 #[doc = ""]
3427 #[repr(u32)]
3428 #[non_exhaustive]
3429 #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy)]
3430 pub enum ButtonState {
3431 #[doc = "the button is not pressed"]
3432 Released = 0u32,
3433 #[doc = "the button is pressed"]
3434 Pressed = 1u32,
3435 }
3436 impl TryFrom<u32> for ButtonState {
3437 type Error = crate::wire::DecodeError;
3438 fn try_from(v: u32) -> Result<Self, Self::Error> {
3439 match v {
3440 0u32 => Ok(Self::Released),
3441 1u32 => Ok(Self::Pressed),
3442 _ => Err(crate::wire::DecodeError::MalformedPayload),
3443 }
3444 }
3445 }
3446 impl std::fmt::Display for ButtonState {
3447 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3448 (*self as u32).fmt(f)
3449 }
3450 }
3451 #[doc = "Trait to implement the zwp_tablet_pad_v2 interface. See the module level documentation for more info"]
3452 pub trait ZwpTabletPadV2: crate::server::Dispatcher {
3453 const INTERFACE: &'static str = "zwp_tablet_pad_v2";
3454 const VERSION: u32 = 2u32;
3455 fn handle_request(
3456 &self,
3457 client: &mut crate::server::Client,
3458 sender_id: crate::wire::ObjectId,
3459 message: &mut crate::wire::Message,
3460 ) -> impl Future<Output = crate::server::Result<()>> + Send {
3461 async move {
3462 #[allow(clippy::match_single_binding)]
3463 match message.opcode() {
3464 0u16 => {
3465 let button = message.uint()?;
3466 let description = message
3467 .string()?
3468 .ok_or(crate::wire::DecodeError::MalformedPayload)?;
3469 let serial = message.uint()?;
3470 tracing::debug!(
3471 "zwp_tablet_pad_v2#{}.set_feedback({}, \"{}\", {})",
3472 sender_id,
3473 button,
3474 description,
3475 serial
3476 );
3477 self.set_feedback(client, sender_id, button, description, serial)
3478 .await
3479 }
3480 1u16 => {
3481 tracing::debug!("zwp_tablet_pad_v2#{}.destroy()", sender_id,);
3482 let result = self.destroy(client, sender_id).await;
3483 client.remove(sender_id);
3484 result
3485 }
3486 opcode => Err(crate::server::error::Error::UnknownOpcode(opcode)),
3487 }
3488 }
3489 }
3490 #[doc = ""]
3491 #[doc = "Requests the compositor to use the provided feedback string"]
3492 #[doc = "associated with this button. This request should be issued immediately"]
3493 #[doc = "after a wp_tablet_pad_group.mode_switch event from the corresponding"]
3494 #[doc = "group is received, or whenever a button is mapped to a different"]
3495 #[doc = "action. See wp_tablet_pad_group.mode_switch for more details."]
3496 #[doc = ""]
3497 #[doc = "Clients are encouraged to provide context-aware descriptions for"]
3498 #[doc = "the actions associated with each button, and compositors may use"]
3499 #[doc = "this information to offer visual feedback on the button layout"]
3500 #[doc = "(e.g. on-screen displays)."]
3501 #[doc = ""]
3502 #[doc = "Button indices start at 0. Setting the feedback string on a button"]
3503 #[doc = "that is reserved by the compositor (i.e. not belonging to any"]
3504 #[doc = "wp_tablet_pad_group) does not generate an error but the compositor"]
3505 #[doc = "is free to ignore the request."]
3506 #[doc = ""]
3507 #[doc = "The provided string 'description' is a UTF-8 encoded string to be"]
3508 #[doc = "associated with this ring, and is considered user-visible; general"]
3509 #[doc = "internationalization rules apply."]
3510 #[doc = ""]
3511 #[doc = "The serial argument will be that of the last"]
3512 #[doc = "wp_tablet_pad_group.mode_switch event received for the group of this"]
3513 #[doc = "button. Requests providing other serials than the most recent one will"]
3514 #[doc = "be ignored."]
3515 #[doc = ""]
3516 fn set_feedback(
3517 &self,
3518 client: &mut crate::server::Client,
3519 sender_id: crate::wire::ObjectId,
3520 button: u32,
3521 description: String,
3522 serial: u32,
3523 ) -> impl Future<Output = crate::server::Result<()>> + Send;
3524 #[doc = ""]
3525 #[doc = "Destroy the wp_tablet_pad object. Objects created from this object"]
3526 #[doc = "are unaffected and should be destroyed separately."]
3527 #[doc = ""]
3528 fn destroy(
3529 &self,
3530 client: &mut crate::server::Client,
3531 sender_id: crate::wire::ObjectId,
3532 ) -> impl Future<Output = crate::server::Result<()>> + Send;
3533 #[doc = ""]
3534 #[doc = "Sent on wp_tablet_pad initialization to announce available groups."]
3535 #[doc = "One event is sent for each pad group available."]
3536 #[doc = ""]
3537 #[doc = "This event is sent in the initial burst of events before the"]
3538 #[doc = "wp_tablet_pad.done event. At least one group will be announced."]
3539 #[doc = ""]
3540 fn group(
3541 &self,
3542 client: &mut crate::server::Client,
3543 sender_id: crate::wire::ObjectId,
3544 pad_group: crate::wire::ObjectId,
3545 ) -> impl Future<Output = crate::server::Result<()>> + Send {
3546 async move {
3547 tracing::debug!("-> zwp_tablet_pad_v2#{}.group({})", sender_id, pad_group);
3548 let (payload, fds) = crate::wire::PayloadBuilder::new()
3549 .put_object(Some(pad_group))
3550 .build();
3551 client
3552 .send_message(crate::wire::Message::new(sender_id, 0u16, payload, fds))
3553 .await
3554 .map_err(crate::server::error::Error::IoError)
3555 }
3556 }
3557 #[doc = ""]
3558 #[doc = "A system-specific device path that indicates which device is behind"]
3559 #[doc = "this wp_tablet_pad. This information may be used to gather additional"]
3560 #[doc = "information about the device, e.g. through libwacom."]
3561 #[doc = ""]
3562 #[doc = "The format of the path is unspecified, it may be a device node, a"]
3563 #[doc = "sysfs path, or some other identifier. It is up to the client to"]
3564 #[doc = "identify the string provided."]
3565 #[doc = ""]
3566 #[doc = "This event is sent in the initial burst of events before the"]
3567 #[doc = "wp_tablet_pad.done event."]
3568 #[doc = ""]
3569 fn path(
3570 &self,
3571 client: &mut crate::server::Client,
3572 sender_id: crate::wire::ObjectId,
3573 path: String,
3574 ) -> impl Future<Output = crate::server::Result<()>> + Send {
3575 async move {
3576 tracing::debug!("-> zwp_tablet_pad_v2#{}.path(\"{}\")", sender_id, path);
3577 let (payload, fds) = crate::wire::PayloadBuilder::new()
3578 .put_string(Some(path))
3579 .build();
3580 client
3581 .send_message(crate::wire::Message::new(sender_id, 1u16, payload, fds))
3582 .await
3583 .map_err(crate::server::error::Error::IoError)
3584 }
3585 }
3586 #[doc = ""]
3587 #[doc = "Sent on wp_tablet_pad initialization to announce the available"]
3588 #[doc = "buttons."]
3589 #[doc = ""]
3590 #[doc = "This event is sent in the initial burst of events before the"]
3591 #[doc = "wp_tablet_pad.done event. This event is only sent when at least one"]
3592 #[doc = "button is available."]
3593 #[doc = ""]
3594 fn buttons(
3595 &self,
3596 client: &mut crate::server::Client,
3597 sender_id: crate::wire::ObjectId,
3598 buttons: u32,
3599 ) -> impl Future<Output = crate::server::Result<()>> + Send {
3600 async move {
3601 tracing::debug!("-> zwp_tablet_pad_v2#{}.buttons({})", sender_id, buttons);
3602 let (payload, fds) =
3603 crate::wire::PayloadBuilder::new().put_uint(buttons).build();
3604 client
3605 .send_message(crate::wire::Message::new(sender_id, 2u16, payload, fds))
3606 .await
3607 .map_err(crate::server::error::Error::IoError)
3608 }
3609 }
3610 #[doc = ""]
3611 #[doc = "This event signals the end of the initial burst of descriptive"]
3612 #[doc = "events. A client may consider the static description of the pad to"]
3613 #[doc = "be complete and finalize initialization of the pad."]
3614 #[doc = ""]
3615 fn done(
3616 &self,
3617 client: &mut crate::server::Client,
3618 sender_id: crate::wire::ObjectId,
3619 ) -> impl Future<Output = crate::server::Result<()>> + Send {
3620 async move {
3621 tracing::debug!("-> zwp_tablet_pad_v2#{}.done()", sender_id,);
3622 let (payload, fds) = crate::wire::PayloadBuilder::new().build();
3623 client
3624 .send_message(crate::wire::Message::new(sender_id, 3u16, payload, fds))
3625 .await
3626 .map_err(crate::server::error::Error::IoError)
3627 }
3628 }
3629 #[doc = ""]
3630 #[doc = "Sent whenever the physical state of a button changes."]
3631 #[doc = ""]
3632 fn button(
3633 &self,
3634 client: &mut crate::server::Client,
3635 sender_id: crate::wire::ObjectId,
3636 time: u32,
3637 button: u32,
3638 state: ButtonState,
3639 ) -> impl Future<Output = crate::server::Result<()>> + Send {
3640 async move {
3641 tracing::debug!(
3642 "-> zwp_tablet_pad_v2#{}.button({}, {}, {})",
3643 sender_id,
3644 time,
3645 button,
3646 state
3647 );
3648 let (payload, fds) = crate::wire::PayloadBuilder::new()
3649 .put_uint(time)
3650 .put_uint(button)
3651 .put_uint(state as u32)
3652 .build();
3653 client
3654 .send_message(crate::wire::Message::new(sender_id, 4u16, payload, fds))
3655 .await
3656 .map_err(crate::server::error::Error::IoError)
3657 }
3658 }
3659 #[doc = ""]
3660 #[doc = "Notification that this pad is focused on the specified surface."]
3661 #[doc = ""]
3662 fn enter(
3663 &self,
3664 client: &mut crate::server::Client,
3665 sender_id: crate::wire::ObjectId,
3666 serial: u32,
3667 tablet: crate::wire::ObjectId,
3668 surface: crate::wire::ObjectId,
3669 ) -> impl Future<Output = crate::server::Result<()>> + Send {
3670 async move {
3671 tracing::debug!(
3672 "-> zwp_tablet_pad_v2#{}.enter({}, {}, {})",
3673 sender_id,
3674 serial,
3675 tablet,
3676 surface
3677 );
3678 let (payload, fds) = crate::wire::PayloadBuilder::new()
3679 .put_uint(serial)
3680 .put_object(Some(tablet))
3681 .put_object(Some(surface))
3682 .build();
3683 client
3684 .send_message(crate::wire::Message::new(sender_id, 5u16, payload, fds))
3685 .await
3686 .map_err(crate::server::error::Error::IoError)
3687 }
3688 }
3689 #[doc = ""]
3690 #[doc = "Notification that this pad is no longer focused on the specified"]
3691 #[doc = "surface."]
3692 #[doc = ""]
3693 fn leave(
3694 &self,
3695 client: &mut crate::server::Client,
3696 sender_id: crate::wire::ObjectId,
3697 serial: u32,
3698 surface: crate::wire::ObjectId,
3699 ) -> impl Future<Output = crate::server::Result<()>> + Send {
3700 async move {
3701 tracing::debug!(
3702 "-> zwp_tablet_pad_v2#{}.leave({}, {})",
3703 sender_id,
3704 serial,
3705 surface
3706 );
3707 let (payload, fds) = crate::wire::PayloadBuilder::new()
3708 .put_uint(serial)
3709 .put_object(Some(surface))
3710 .build();
3711 client
3712 .send_message(crate::wire::Message::new(sender_id, 6u16, payload, fds))
3713 .await
3714 .map_err(crate::server::error::Error::IoError)
3715 }
3716 }
3717 #[doc = ""]
3718 #[doc = "Sent when the pad has been removed from the system. When a tablet"]
3719 #[doc = "is removed its pad(s) will be removed too."]
3720 #[doc = ""]
3721 #[doc = "When this event is received, the client must destroy all rings, strips"]
3722 #[doc = "and groups that were offered by this pad, and issue wp_tablet_pad.destroy"]
3723 #[doc = "the pad itself."]
3724 #[doc = ""]
3725 fn removed(
3726 &self,
3727 client: &mut crate::server::Client,
3728 sender_id: crate::wire::ObjectId,
3729 ) -> impl Future<Output = crate::server::Result<()>> + Send {
3730 async move {
3731 tracing::debug!("-> zwp_tablet_pad_v2#{}.removed()", sender_id,);
3732 let (payload, fds) = crate::wire::PayloadBuilder::new().build();
3733 client
3734 .send_message(crate::wire::Message::new(sender_id, 7u16, payload, fds))
3735 .await
3736 .map_err(crate::server::error::Error::IoError)
3737 }
3738 }
3739 }
3740 }
3741 #[doc = ""]
3742 #[doc = "A rotary control, e.g. a dial or a wheel."]
3743 #[doc = ""]
3744 #[doc = "Events on a dial are logically grouped by the wl_tablet_pad_dial.frame"]
3745 #[doc = "event."]
3746 #[doc = ""]
3747 #[allow(clippy::too_many_arguments)]
3748 pub mod zwp_tablet_pad_dial_v2 {
3749 #[allow(unused)]
3750 use futures_util::SinkExt;
3751 #[allow(unused)]
3752 use std::os::fd::AsRawFd;
3753 #[doc = "Trait to implement the zwp_tablet_pad_dial_v2 interface. See the module level documentation for more info"]
3754 pub trait ZwpTabletPadDialV2: crate::server::Dispatcher {
3755 const INTERFACE: &'static str = "zwp_tablet_pad_dial_v2";
3756 const VERSION: u32 = 2u32;
3757 fn handle_request(
3758 &self,
3759 client: &mut crate::server::Client,
3760 sender_id: crate::wire::ObjectId,
3761 message: &mut crate::wire::Message,
3762 ) -> impl Future<Output = crate::server::Result<()>> + Send {
3763 async move {
3764 #[allow(clippy::match_single_binding)]
3765 match message.opcode() {
3766 0u16 => {
3767 let description = message
3768 .string()?
3769 .ok_or(crate::wire::DecodeError::MalformedPayload)?;
3770 let serial = message.uint()?;
3771 tracing::debug!(
3772 "zwp_tablet_pad_dial_v2#{}.set_feedback(\"{}\", {})",
3773 sender_id,
3774 description,
3775 serial
3776 );
3777 self.set_feedback(client, sender_id, description, serial)
3778 .await
3779 }
3780 1u16 => {
3781 tracing::debug!("zwp_tablet_pad_dial_v2#{}.destroy()", sender_id,);
3782 let result = self.destroy(client, sender_id).await;
3783 client.remove(sender_id);
3784 result
3785 }
3786 opcode => Err(crate::server::error::Error::UnknownOpcode(opcode)),
3787 }
3788 }
3789 }
3790 #[doc = ""]
3791 #[doc = "Requests the compositor to use the provided feedback string"]
3792 #[doc = "associated with this dial. This request should be issued immediately"]
3793 #[doc = "after a wp_tablet_pad_group.mode_switch event from the corresponding"]
3794 #[doc = "group is received, or whenever the dial is mapped to a different"]
3795 #[doc = "action. See wp_tablet_pad_group.mode_switch for more details."]
3796 #[doc = ""]
3797 #[doc = "Clients are encouraged to provide context-aware descriptions for"]
3798 #[doc = "the actions associated with the dial, and compositors may use this"]
3799 #[doc = "information to offer visual feedback about the button layout"]
3800 #[doc = "(eg. on-screen displays)."]
3801 #[doc = ""]
3802 #[doc = "The provided string 'description' is a UTF-8 encoded string to be"]
3803 #[doc = "associated with this ring, and is considered user-visible; general"]
3804 #[doc = "internationalization rules apply."]
3805 #[doc = ""]
3806 #[doc = "The serial argument will be that of the last"]
3807 #[doc = "wp_tablet_pad_group.mode_switch event received for the group of this"]
3808 #[doc = "dial. Requests providing other serials than the most recent one will be"]
3809 #[doc = "ignored."]
3810 #[doc = ""]
3811 fn set_feedback(
3812 &self,
3813 client: &mut crate::server::Client,
3814 sender_id: crate::wire::ObjectId,
3815 description: String,
3816 serial: u32,
3817 ) -> impl Future<Output = crate::server::Result<()>> + Send;
3818 #[doc = ""]
3819 #[doc = "This destroys the client's resource for this dial object."]
3820 #[doc = ""]
3821 fn destroy(
3822 &self,
3823 client: &mut crate::server::Client,
3824 sender_id: crate::wire::ObjectId,
3825 ) -> impl Future<Output = crate::server::Result<()>> + Send;
3826 #[doc = ""]
3827 #[doc = "Sent whenever the position on a dial changes."]
3828 #[doc = ""]
3829 #[doc = "This event carries the wheel delta as multiples or fractions"]
3830 #[doc = "of 120 with each multiple of 120 representing one logical wheel detent."]
3831 #[doc = "For example, an axis_value120 of 30 is one quarter of"]
3832 #[doc = "a logical wheel step in the positive direction, a value120 of"]
3833 #[doc = "-240 are two logical wheel steps in the negative direction within the"]
3834 #[doc = "same hardware event. See the wl_pointer.axis_value120 for more details."]
3835 #[doc = ""]
3836 #[doc = "The value120 must not be zero."]
3837 #[doc = ""]
3838 fn delta(
3839 &self,
3840 client: &mut crate::server::Client,
3841 sender_id: crate::wire::ObjectId,
3842 value120: i32,
3843 ) -> impl Future<Output = crate::server::Result<()>> + Send {
3844 async move {
3845 tracing::debug!(
3846 "-> zwp_tablet_pad_dial_v2#{}.delta({})",
3847 sender_id,
3848 value120
3849 );
3850 let (payload, fds) =
3851 crate::wire::PayloadBuilder::new().put_int(value120).build();
3852 client
3853 .send_message(crate::wire::Message::new(sender_id, 0u16, payload, fds))
3854 .await
3855 .map_err(crate::server::error::Error::IoError)
3856 }
3857 }
3858 #[doc = ""]
3859 #[doc = "Indicates the end of a set of events that represent one logical"]
3860 #[doc = "hardware dial event. A client is expected to accumulate the data"]
3861 #[doc = "in all events within the frame before proceeding."]
3862 #[doc = ""]
3863 #[doc = "All wp_tablet_pad_dial events before a wp_tablet_pad_dial.frame event belong"]
3864 #[doc = "logically together."]
3865 #[doc = ""]
3866 #[doc = "A wp_tablet_pad_dial.frame event is sent for every logical event"]
3867 #[doc = "group, even if the group only contains a single wp_tablet_pad_dial"]
3868 #[doc = "event. Specifically, a client may get a sequence: delta, frame,"]
3869 #[doc = "delta, frame, etc."]
3870 #[doc = ""]
3871 fn frame(
3872 &self,
3873 client: &mut crate::server::Client,
3874 sender_id: crate::wire::ObjectId,
3875 time: u32,
3876 ) -> impl Future<Output = crate::server::Result<()>> + Send {
3877 async move {
3878 tracing::debug!("-> zwp_tablet_pad_dial_v2#{}.frame({})", sender_id, time);
3879 let (payload, fds) = crate::wire::PayloadBuilder::new().put_uint(time).build();
3880 client
3881 .send_message(crate::wire::Message::new(sender_id, 1u16, payload, fds))
3882 .await
3883 .map_err(crate::server::error::Error::IoError)
3884 }
3885 }
3886 }
3887 }
3888}
3889#[allow(clippy::module_inception)]
3890pub mod viewporter {
3891 #[doc = ""]
3892 #[doc = "The global interface exposing surface cropping and scaling"]
3893 #[doc = "capabilities is used to instantiate an interface extension for a"]
3894 #[doc = "wl_surface object. This extended interface will then allow"]
3895 #[doc = "cropping and scaling the surface contents, effectively"]
3896 #[doc = "disconnecting the direct relationship between the buffer and the"]
3897 #[doc = "surface size."]
3898 #[doc = ""]
3899 #[allow(clippy::too_many_arguments)]
3900 pub mod wp_viewporter {
3901 #[allow(unused)]
3902 use futures_util::SinkExt;
3903 #[allow(unused)]
3904 use std::os::fd::AsRawFd;
3905 #[repr(u32)]
3906 #[non_exhaustive]
3907 #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy)]
3908 pub enum Error {
3909 #[doc = "the surface already has a viewport object associated"]
3910 ViewportExists = 0u32,
3911 }
3912 impl TryFrom<u32> for Error {
3913 type Error = crate::wire::DecodeError;
3914 fn try_from(v: u32) -> Result<Self, Self::Error> {
3915 match v {
3916 0u32 => Ok(Self::ViewportExists),
3917 _ => Err(crate::wire::DecodeError::MalformedPayload),
3918 }
3919 }
3920 }
3921 impl std::fmt::Display for Error {
3922 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3923 (*self as u32).fmt(f)
3924 }
3925 }
3926 #[doc = "Trait to implement the wp_viewporter interface. See the module level documentation for more info"]
3927 pub trait WpViewporter: crate::server::Dispatcher {
3928 const INTERFACE: &'static str = "wp_viewporter";
3929 const VERSION: u32 = 1u32;
3930 fn handle_request(
3931 &self,
3932 client: &mut crate::server::Client,
3933 sender_id: crate::wire::ObjectId,
3934 message: &mut crate::wire::Message,
3935 ) -> impl Future<Output = crate::server::Result<()>> + Send {
3936 async move {
3937 #[allow(clippy::match_single_binding)]
3938 match message.opcode() {
3939 0u16 => {
3940 tracing::debug!("wp_viewporter#{}.destroy()", sender_id,);
3941 let result = self.destroy(client, sender_id).await;
3942 client.remove(sender_id);
3943 result
3944 }
3945 1u16 => {
3946 let id = message
3947 .object()?
3948 .ok_or(crate::wire::DecodeError::MalformedPayload)?;
3949 let surface = message
3950 .object()?
3951 .ok_or(crate::wire::DecodeError::MalformedPayload)?;
3952 tracing::debug!(
3953 "wp_viewporter#{}.get_viewport({}, {})",
3954 sender_id,
3955 id,
3956 surface
3957 );
3958 self.get_viewport(client, sender_id, id, surface).await
3959 }
3960 opcode => Err(crate::server::error::Error::UnknownOpcode(opcode)),
3961 }
3962 }
3963 }
3964 #[doc = ""]
3965 #[doc = "Informs the server that the client will not be using this"]
3966 #[doc = "protocol object anymore. This does not affect any other objects,"]
3967 #[doc = "wp_viewport objects included."]
3968 #[doc = ""]
3969 fn destroy(
3970 &self,
3971 client: &mut crate::server::Client,
3972 sender_id: crate::wire::ObjectId,
3973 ) -> impl Future<Output = crate::server::Result<()>> + Send;
3974 #[doc = ""]
3975 #[doc = "Instantiate an interface extension for the given wl_surface to"]
3976 #[doc = "crop and scale its content. If the given wl_surface already has"]
3977 #[doc = "a wp_viewport object associated, the viewport_exists"]
3978 #[doc = "protocol error is raised."]
3979 #[doc = ""]
3980 fn get_viewport(
3981 &self,
3982 client: &mut crate::server::Client,
3983 sender_id: crate::wire::ObjectId,
3984 id: crate::wire::ObjectId,
3985 surface: crate::wire::ObjectId,
3986 ) -> impl Future<Output = crate::server::Result<()>> + Send;
3987 }
3988 }
3989 #[doc = ""]
3990 #[doc = "An additional interface to a wl_surface object, which allows the"]
3991 #[doc = "client to specify the cropping and scaling of the surface"]
3992 #[doc = "contents."]
3993 #[doc = ""]
3994 #[doc = "This interface works with two concepts: the source rectangle (src_x,"]
3995 #[doc = "src_y, src_width, src_height), and the destination size (dst_width,"]
3996 #[doc = "dst_height). The contents of the source rectangle are scaled to the"]
3997 #[doc = "destination size, and content outside the source rectangle is ignored."]
3998 #[doc = "This state is double-buffered, see wl_surface.commit."]
3999 #[doc = ""]
4000 #[doc = "The two parts of crop and scale state are independent: the source"]
4001 #[doc = "rectangle, and the destination size. Initially both are unset, that"]
4002 #[doc = "is, no scaling is applied. The whole of the current wl_buffer is"]
4003 #[doc = "used as the source, and the surface size is as defined in"]
4004 #[doc = "wl_surface.attach."]
4005 #[doc = ""]
4006 #[doc = "If the destination size is set, it causes the surface size to become"]
4007 #[doc = "dst_width, dst_height. The source (rectangle) is scaled to exactly"]
4008 #[doc = "this size. This overrides whatever the attached wl_buffer size is,"]
4009 #[doc = "unless the wl_buffer is NULL. If the wl_buffer is NULL, the surface"]
4010 #[doc = "has no content and therefore no size. Otherwise, the size is always"]
4011 #[doc = "at least 1x1 in surface local coordinates."]
4012 #[doc = ""]
4013 #[doc = "If the source rectangle is set, it defines what area of the wl_buffer is"]
4014 #[doc = "taken as the source. If the source rectangle is set and the destination"]
4015 #[doc = "size is not set, then src_width and src_height must be integers, and the"]
4016 #[doc = "surface size becomes the source rectangle size. This results in cropping"]
4017 #[doc = "without scaling. If src_width or src_height are not integers and"]
4018 #[doc = "destination size is not set, the bad_size protocol error is raised when"]
4019 #[doc = "the surface state is applied."]
4020 #[doc = ""]
4021 #[doc = "The coordinate transformations from buffer pixel coordinates up to"]
4022 #[doc = "the surface-local coordinates happen in the following order:"]
4023 #[doc = "1. buffer_transform (wl_surface.set_buffer_transform)"]
4024 #[doc = "2. buffer_scale (wl_surface.set_buffer_scale)"]
4025 #[doc = "3. crop and scale (wp_viewport.set*)"]
4026 #[doc = "This means, that the source rectangle coordinates of crop and scale"]
4027 #[doc = "are given in the coordinates after the buffer transform and scale,"]
4028 #[doc = "i.e. in the coordinates that would be the surface-local coordinates"]
4029 #[doc = "if the crop and scale was not applied."]
4030 #[doc = ""]
4031 #[doc = "If src_x or src_y are negative, the bad_value protocol error is raised."]
4032 #[doc = "Otherwise, if the source rectangle is partially or completely outside of"]
4033 #[doc = "the non-NULL wl_buffer, then the out_of_buffer protocol error is raised"]
4034 #[doc = "when the surface state is applied. A NULL wl_buffer does not raise the"]
4035 #[doc = "out_of_buffer error."]
4036 #[doc = ""]
4037 #[doc = "If the wl_surface associated with the wp_viewport is destroyed,"]
4038 #[doc = "all wp_viewport requests except 'destroy' raise the protocol error"]
4039 #[doc = "no_surface."]
4040 #[doc = ""]
4041 #[doc = "If the wp_viewport object is destroyed, the crop and scale"]
4042 #[doc = "state is removed from the wl_surface. The change will be applied"]
4043 #[doc = "on the next wl_surface.commit."]
4044 #[doc = ""]
4045 #[allow(clippy::too_many_arguments)]
4046 pub mod wp_viewport {
4047 #[allow(unused)]
4048 use futures_util::SinkExt;
4049 #[allow(unused)]
4050 use std::os::fd::AsRawFd;
4051 #[repr(u32)]
4052 #[non_exhaustive]
4053 #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy)]
4054 pub enum Error {
4055 #[doc = "negative or zero values in width or height"]
4056 BadValue = 0u32,
4057 #[doc = "destination size is not integer"]
4058 BadSize = 1u32,
4059 #[doc = "source rectangle extends outside of the content area"]
4060 OutOfBuffer = 2u32,
4061 #[doc = "the wl_surface was destroyed"]
4062 NoSurface = 3u32,
4063 }
4064 impl TryFrom<u32> for Error {
4065 type Error = crate::wire::DecodeError;
4066 fn try_from(v: u32) -> Result<Self, Self::Error> {
4067 match v {
4068 0u32 => Ok(Self::BadValue),
4069 1u32 => Ok(Self::BadSize),
4070 2u32 => Ok(Self::OutOfBuffer),
4071 3u32 => Ok(Self::NoSurface),
4072 _ => Err(crate::wire::DecodeError::MalformedPayload),
4073 }
4074 }
4075 }
4076 impl std::fmt::Display for Error {
4077 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
4078 (*self as u32).fmt(f)
4079 }
4080 }
4081 #[doc = "Trait to implement the wp_viewport interface. See the module level documentation for more info"]
4082 pub trait WpViewport: crate::server::Dispatcher {
4083 const INTERFACE: &'static str = "wp_viewport";
4084 const VERSION: u32 = 1u32;
4085 fn handle_request(
4086 &self,
4087 client: &mut crate::server::Client,
4088 sender_id: crate::wire::ObjectId,
4089 message: &mut crate::wire::Message,
4090 ) -> impl Future<Output = crate::server::Result<()>> + Send {
4091 async move {
4092 #[allow(clippy::match_single_binding)]
4093 match message.opcode() {
4094 0u16 => {
4095 tracing::debug!("wp_viewport#{}.destroy()", sender_id,);
4096 let result = self.destroy(client, sender_id).await;
4097 client.remove(sender_id);
4098 result
4099 }
4100 1u16 => {
4101 let x = message.fixed()?;
4102 let y = message.fixed()?;
4103 let width = message.fixed()?;
4104 let height = message.fixed()?;
4105 tracing::debug!(
4106 "wp_viewport#{}.set_source({}, {}, {}, {})",
4107 sender_id,
4108 x,
4109 y,
4110 width,
4111 height
4112 );
4113 self.set_source(client, sender_id, x, y, width, height)
4114 .await
4115 }
4116 2u16 => {
4117 let width = message.int()?;
4118 let height = message.int()?;
4119 tracing::debug!(
4120 "wp_viewport#{}.set_destination({}, {})",
4121 sender_id,
4122 width,
4123 height
4124 );
4125 self.set_destination(client, sender_id, width, height).await
4126 }
4127 opcode => Err(crate::server::error::Error::UnknownOpcode(opcode)),
4128 }
4129 }
4130 }
4131 #[doc = ""]
4132 #[doc = "The associated wl_surface's crop and scale state is removed."]
4133 #[doc = "The change is applied on the next wl_surface.commit."]
4134 #[doc = ""]
4135 fn destroy(
4136 &self,
4137 client: &mut crate::server::Client,
4138 sender_id: crate::wire::ObjectId,
4139 ) -> impl Future<Output = crate::server::Result<()>> + Send;
4140 #[doc = ""]
4141 #[doc = "Set the source rectangle of the associated wl_surface. See"]
4142 #[doc = "wp_viewport for the description, and relation to the wl_buffer"]
4143 #[doc = "size."]
4144 #[doc = ""]
4145 #[doc = "If all of x, y, width and height are -1.0, the source rectangle is"]
4146 #[doc = "unset instead. Any other set of values where width or height are zero"]
4147 #[doc = "or negative, or x or y are negative, raise the bad_value protocol"]
4148 #[doc = "error."]
4149 #[doc = ""]
4150 #[doc = "The crop and scale state is double-buffered, see wl_surface.commit."]
4151 #[doc = ""]
4152 fn set_source(
4153 &self,
4154 client: &mut crate::server::Client,
4155 sender_id: crate::wire::ObjectId,
4156 x: crate::wire::Fixed,
4157 y: crate::wire::Fixed,
4158 width: crate::wire::Fixed,
4159 height: crate::wire::Fixed,
4160 ) -> impl Future<Output = crate::server::Result<()>> + Send;
4161 #[doc = ""]
4162 #[doc = "Set the destination size of the associated wl_surface. See"]
4163 #[doc = "wp_viewport for the description, and relation to the wl_buffer"]
4164 #[doc = "size."]
4165 #[doc = ""]
4166 #[doc = "If width is -1 and height is -1, the destination size is unset"]
4167 #[doc = "instead. Any other pair of values for width and height that"]
4168 #[doc = "contains zero or negative values raises the bad_value protocol"]
4169 #[doc = "error."]
4170 #[doc = ""]
4171 #[doc = "The crop and scale state is double-buffered, see wl_surface.commit."]
4172 #[doc = ""]
4173 fn set_destination(
4174 &self,
4175 client: &mut crate::server::Client,
4176 sender_id: crate::wire::ObjectId,
4177 width: i32,
4178 height: i32,
4179 ) -> impl Future<Output = crate::server::Result<()>> + Send;
4180 }
4181 }
4182}
4183#[allow(clippy::module_inception)]
4184pub mod xdg_shell {
4185 #[doc = ""]
4186 #[doc = "The xdg_wm_base interface is exposed as a global object enabling clients"]
4187 #[doc = "to turn their wl_surfaces into windows in a desktop environment. It"]
4188 #[doc = "defines the basic functionality needed for clients and the compositor to"]
4189 #[doc = "create windows that can be dragged, resized, maximized, etc, as well as"]
4190 #[doc = "creating transient windows such as popup menus."]
4191 #[doc = ""]
4192 #[allow(clippy::too_many_arguments)]
4193 pub mod xdg_wm_base {
4194 #[allow(unused)]
4195 use futures_util::SinkExt;
4196 #[allow(unused)]
4197 use std::os::fd::AsRawFd;
4198 #[repr(u32)]
4199 #[non_exhaustive]
4200 #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy)]
4201 pub enum Error {
4202 #[doc = "given wl_surface has another role"]
4203 Role = 0u32,
4204 #[doc = "xdg_wm_base was destroyed before children"]
4205 DefunctSurfaces = 1u32,
4206 #[doc = "the client tried to map or destroy a non-topmost popup"]
4207 NotTheTopmostPopup = 2u32,
4208 #[doc = "the client specified an invalid popup parent surface"]
4209 InvalidPopupParent = 3u32,
4210 #[doc = "the client provided an invalid surface state"]
4211 InvalidSurfaceState = 4u32,
4212 #[doc = "the client provided an invalid positioner"]
4213 InvalidPositioner = 5u32,
4214 #[doc = "the client didn’t respond to a ping event in time"]
4215 Unresponsive = 6u32,
4216 }
4217 impl TryFrom<u32> for Error {
4218 type Error = crate::wire::DecodeError;
4219 fn try_from(v: u32) -> Result<Self, Self::Error> {
4220 match v {
4221 0u32 => Ok(Self::Role),
4222 1u32 => Ok(Self::DefunctSurfaces),
4223 2u32 => Ok(Self::NotTheTopmostPopup),
4224 3u32 => Ok(Self::InvalidPopupParent),
4225 4u32 => Ok(Self::InvalidSurfaceState),
4226 5u32 => Ok(Self::InvalidPositioner),
4227 6u32 => Ok(Self::Unresponsive),
4228 _ => Err(crate::wire::DecodeError::MalformedPayload),
4229 }
4230 }
4231 }
4232 impl std::fmt::Display for Error {
4233 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
4234 (*self as u32).fmt(f)
4235 }
4236 }
4237 #[doc = "Trait to implement the xdg_wm_base interface. See the module level documentation for more info"]
4238 pub trait XdgWmBase: crate::server::Dispatcher {
4239 const INTERFACE: &'static str = "xdg_wm_base";
4240 const VERSION: u32 = 7u32;
4241 fn handle_request(
4242 &self,
4243 client: &mut crate::server::Client,
4244 sender_id: crate::wire::ObjectId,
4245 message: &mut crate::wire::Message,
4246 ) -> impl Future<Output = crate::server::Result<()>> + Send {
4247 async move {
4248 #[allow(clippy::match_single_binding)]
4249 match message.opcode() {
4250 0u16 => {
4251 tracing::debug!("xdg_wm_base#{}.destroy()", sender_id,);
4252 let result = self.destroy(client, sender_id).await;
4253 client.remove(sender_id);
4254 result
4255 }
4256 1u16 => {
4257 let id = message
4258 .object()?
4259 .ok_or(crate::wire::DecodeError::MalformedPayload)?;
4260 tracing::debug!("xdg_wm_base#{}.create_positioner({})", sender_id, id);
4261 self.create_positioner(client, sender_id, id).await
4262 }
4263 2u16 => {
4264 let id = message
4265 .object()?
4266 .ok_or(crate::wire::DecodeError::MalformedPayload)?;
4267 let surface = message
4268 .object()?
4269 .ok_or(crate::wire::DecodeError::MalformedPayload)?;
4270 tracing::debug!(
4271 "xdg_wm_base#{}.get_xdg_surface({}, {})",
4272 sender_id,
4273 id,
4274 surface
4275 );
4276 self.get_xdg_surface(client, sender_id, id, surface).await
4277 }
4278 3u16 => {
4279 let serial = message.uint()?;
4280 tracing::debug!("xdg_wm_base#{}.pong({})", sender_id, serial);
4281 self.pong(client, sender_id, serial).await
4282 }
4283 opcode => Err(crate::server::error::Error::UnknownOpcode(opcode)),
4284 }
4285 }
4286 }
4287 #[doc = ""]
4288 #[doc = "Destroy this xdg_wm_base object."]
4289 #[doc = ""]
4290 #[doc = "Destroying a bound xdg_wm_base object while there are surfaces"]
4291 #[doc = "still alive created by this xdg_wm_base object instance is illegal"]
4292 #[doc = "and will result in a defunct_surfaces error."]
4293 #[doc = ""]
4294 fn destroy(
4295 &self,
4296 client: &mut crate::server::Client,
4297 sender_id: crate::wire::ObjectId,
4298 ) -> impl Future<Output = crate::server::Result<()>> + Send;
4299 #[doc = ""]
4300 #[doc = "Create a positioner object. A positioner object is used to position"]
4301 #[doc = "surfaces relative to some parent surface. See the interface description"]
4302 #[doc = "and xdg_surface.get_popup for details."]
4303 #[doc = ""]
4304 fn create_positioner(
4305 &self,
4306 client: &mut crate::server::Client,
4307 sender_id: crate::wire::ObjectId,
4308 id: crate::wire::ObjectId,
4309 ) -> impl Future<Output = crate::server::Result<()>> + Send;
4310 #[doc = ""]
4311 #[doc = "This creates an xdg_surface for the given surface. While xdg_surface"]
4312 #[doc = "itself is not a role, the corresponding surface may only be assigned"]
4313 #[doc = "a role extending xdg_surface, such as xdg_toplevel or xdg_popup. It is"]
4314 #[doc = "illegal to create an xdg_surface for a wl_surface which already has an"]
4315 #[doc = "assigned role and this will result in a role error."]
4316 #[doc = ""]
4317 #[doc = "This creates an xdg_surface for the given surface. An xdg_surface is"]
4318 #[doc = "used as basis to define a role to a given surface, such as xdg_toplevel"]
4319 #[doc = "or xdg_popup. It also manages functionality shared between xdg_surface"]
4320 #[doc = "based surface roles."]
4321 #[doc = ""]
4322 #[doc = "See the documentation of xdg_surface for more details about what an"]
4323 #[doc = "xdg_surface is and how it is used."]
4324 #[doc = ""]
4325 fn get_xdg_surface(
4326 &self,
4327 client: &mut crate::server::Client,
4328 sender_id: crate::wire::ObjectId,
4329 id: crate::wire::ObjectId,
4330 surface: crate::wire::ObjectId,
4331 ) -> impl Future<Output = crate::server::Result<()>> + Send;
4332 #[doc = ""]
4333 #[doc = "A client must respond to a ping event with a pong request or"]
4334 #[doc = "the client may be deemed unresponsive. See xdg_wm_base.ping"]
4335 #[doc = "and xdg_wm_base.error.unresponsive."]
4336 #[doc = ""]
4337 fn pong(
4338 &self,
4339 client: &mut crate::server::Client,
4340 sender_id: crate::wire::ObjectId,
4341 serial: u32,
4342 ) -> impl Future<Output = crate::server::Result<()>> + Send;
4343 #[doc = ""]
4344 #[doc = "The ping event asks the client if it's still alive. Pass the"]
4345 #[doc = "serial specified in the event back to the compositor by sending"]
4346 #[doc = "a \"pong\" request back with the specified serial. See xdg_wm_base.pong."]
4347 #[doc = ""]
4348 #[doc = "Compositors can use this to determine if the client is still"]
4349 #[doc = "alive. It's unspecified what will happen if the client doesn't"]
4350 #[doc = "respond to the ping request, or in what timeframe. Clients should"]
4351 #[doc = "try to respond in a reasonable amount of time. The “unresponsive”"]
4352 #[doc = "error is provided for compositors that wish to disconnect unresponsive"]
4353 #[doc = "clients."]
4354 #[doc = ""]
4355 #[doc = "A compositor is free to ping in any way it wants, but a client must"]
4356 #[doc = "always respond to any xdg_wm_base object it created."]
4357 #[doc = ""]
4358 fn ping(
4359 &self,
4360 client: &mut crate::server::Client,
4361 sender_id: crate::wire::ObjectId,
4362 serial: u32,
4363 ) -> impl Future<Output = crate::server::Result<()>> + Send {
4364 async move {
4365 tracing::debug!("-> xdg_wm_base#{}.ping({})", sender_id, serial);
4366 let (payload, fds) =
4367 crate::wire::PayloadBuilder::new().put_uint(serial).build();
4368 client
4369 .send_message(crate::wire::Message::new(sender_id, 0u16, payload, fds))
4370 .await
4371 .map_err(crate::server::error::Error::IoError)
4372 }
4373 }
4374 }
4375 }
4376 #[doc = ""]
4377 #[doc = "The xdg_positioner provides a collection of rules for the placement of a"]
4378 #[doc = "child surface relative to a parent surface. Rules can be defined to ensure"]
4379 #[doc = "the child surface remains within the visible area's borders, and to"]
4380 #[doc = "specify how the child surface changes its position, such as sliding along"]
4381 #[doc = "an axis, or flipping around a rectangle. These positioner-created rules are"]
4382 #[doc = "constrained by the requirement that a child surface must intersect with or"]
4383 #[doc = "be at least partially adjacent to its parent surface."]
4384 #[doc = ""]
4385 #[doc = "See the various requests for details about possible rules."]
4386 #[doc = ""]
4387 #[doc = "At the time of the request, the compositor makes a copy of the rules"]
4388 #[doc = "specified by the xdg_positioner. Thus, after the request is complete the"]
4389 #[doc = "xdg_positioner object can be destroyed or reused; further changes to the"]
4390 #[doc = "object will have no effect on previous usages."]
4391 #[doc = ""]
4392 #[doc = "For an xdg_positioner object to be considered complete, it must have a"]
4393 #[doc = "non-zero size set by set_size, and a non-zero anchor rectangle set by"]
4394 #[doc = "set_anchor_rect. Passing an incomplete xdg_positioner object when"]
4395 #[doc = "positioning a surface raises an invalid_positioner error."]
4396 #[doc = ""]
4397 #[allow(clippy::too_many_arguments)]
4398 pub mod xdg_positioner {
4399 #[allow(unused)]
4400 use futures_util::SinkExt;
4401 #[allow(unused)]
4402 use std::os::fd::AsRawFd;
4403 #[repr(u32)]
4404 #[non_exhaustive]
4405 #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy)]
4406 pub enum Error {
4407 #[doc = "invalid input provided"]
4408 InvalidInput = 0u32,
4409 }
4410 impl TryFrom<u32> for Error {
4411 type Error = crate::wire::DecodeError;
4412 fn try_from(v: u32) -> Result<Self, Self::Error> {
4413 match v {
4414 0u32 => Ok(Self::InvalidInput),
4415 _ => Err(crate::wire::DecodeError::MalformedPayload),
4416 }
4417 }
4418 }
4419 impl std::fmt::Display for Error {
4420 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
4421 (*self as u32).fmt(f)
4422 }
4423 }
4424 #[repr(u32)]
4425 #[non_exhaustive]
4426 #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy)]
4427 pub enum Anchor {
4428 None = 0u32,
4429 Top = 1u32,
4430 Bottom = 2u32,
4431 Left = 3u32,
4432 Right = 4u32,
4433 TopLeft = 5u32,
4434 BottomLeft = 6u32,
4435 TopRight = 7u32,
4436 BottomRight = 8u32,
4437 }
4438 impl TryFrom<u32> for Anchor {
4439 type Error = crate::wire::DecodeError;
4440 fn try_from(v: u32) -> Result<Self, Self::Error> {
4441 match v {
4442 0u32 => Ok(Self::None),
4443 1u32 => Ok(Self::Top),
4444 2u32 => Ok(Self::Bottom),
4445 3u32 => Ok(Self::Left),
4446 4u32 => Ok(Self::Right),
4447 5u32 => Ok(Self::TopLeft),
4448 6u32 => Ok(Self::BottomLeft),
4449 7u32 => Ok(Self::TopRight),
4450 8u32 => Ok(Self::BottomRight),
4451 _ => Err(crate::wire::DecodeError::MalformedPayload),
4452 }
4453 }
4454 }
4455 impl std::fmt::Display for Anchor {
4456 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
4457 (*self as u32).fmt(f)
4458 }
4459 }
4460 #[repr(u32)]
4461 #[non_exhaustive]
4462 #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy)]
4463 pub enum Gravity {
4464 None = 0u32,
4465 Top = 1u32,
4466 Bottom = 2u32,
4467 Left = 3u32,
4468 Right = 4u32,
4469 TopLeft = 5u32,
4470 BottomLeft = 6u32,
4471 TopRight = 7u32,
4472 BottomRight = 8u32,
4473 }
4474 impl TryFrom<u32> for Gravity {
4475 type Error = crate::wire::DecodeError;
4476 fn try_from(v: u32) -> Result<Self, Self::Error> {
4477 match v {
4478 0u32 => Ok(Self::None),
4479 1u32 => Ok(Self::Top),
4480 2u32 => Ok(Self::Bottom),
4481 3u32 => Ok(Self::Left),
4482 4u32 => Ok(Self::Right),
4483 5u32 => Ok(Self::TopLeft),
4484 6u32 => Ok(Self::BottomLeft),
4485 7u32 => Ok(Self::TopRight),
4486 8u32 => Ok(Self::BottomRight),
4487 _ => Err(crate::wire::DecodeError::MalformedPayload),
4488 }
4489 }
4490 }
4491 impl std::fmt::Display for Gravity {
4492 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
4493 (*self as u32).fmt(f)
4494 }
4495 }
4496 bitflags::bitflags! { # [doc = ""] # [doc = "The constraint adjustment value define ways the compositor will adjust"] # [doc = "the position of the surface, if the unadjusted position would result"] # [doc = "in the surface being partly constrained."] # [doc = ""] # [doc = "Whether a surface is considered 'constrained' is left to the compositor"] # [doc = "to determine. For example, the surface may be partly outside the"] # [doc = "compositor's defined 'work area', thus necessitating the child surface's"] # [doc = "position be adjusted until it is entirely inside the work area."] # [doc = ""] # [doc = "The adjustments can be combined, according to a defined precedence: 1)"] # [doc = "Flip, 2) Slide, 3) Resize."] # [doc = ""] # [derive (Debug , PartialEq , Eq , PartialOrd , Ord , Hash , Clone , Copy)] pub struct ConstraintAdjustment : u32 { const None = 0u32 ; const SlideX = 1u32 ; const SlideY = 2u32 ; const FlipX = 4u32 ; const FlipY = 8u32 ; const ResizeX = 16u32 ; const ResizeY = 32u32 ; } }
4497 impl TryFrom<u32> for ConstraintAdjustment {
4498 type Error = crate::wire::DecodeError;
4499 fn try_from(v: u32) -> Result<Self, Self::Error> {
4500 Self::from_bits(v).ok_or(crate::wire::DecodeError::MalformedPayload)
4501 }
4502 }
4503 impl std::fmt::Display for ConstraintAdjustment {
4504 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
4505 self.bits().fmt(f)
4506 }
4507 }
4508 #[doc = "Trait to implement the xdg_positioner interface. See the module level documentation for more info"]
4509 pub trait XdgPositioner: crate::server::Dispatcher {
4510 const INTERFACE: &'static str = "xdg_positioner";
4511 const VERSION: u32 = 7u32;
4512 fn handle_request(
4513 &self,
4514 client: &mut crate::server::Client,
4515 sender_id: crate::wire::ObjectId,
4516 message: &mut crate::wire::Message,
4517 ) -> impl Future<Output = crate::server::Result<()>> + Send {
4518 async move {
4519 #[allow(clippy::match_single_binding)]
4520 match message.opcode() {
4521 0u16 => {
4522 tracing::debug!("xdg_positioner#{}.destroy()", sender_id,);
4523 let result = self.destroy(client, sender_id).await;
4524 client.remove(sender_id);
4525 result
4526 }
4527 1u16 => {
4528 let width = message.int()?;
4529 let height = message.int()?;
4530 tracing::debug!(
4531 "xdg_positioner#{}.set_size({}, {})",
4532 sender_id,
4533 width,
4534 height
4535 );
4536 self.set_size(client, sender_id, width, height).await
4537 }
4538 2u16 => {
4539 let x = message.int()?;
4540 let y = message.int()?;
4541 let width = message.int()?;
4542 let height = message.int()?;
4543 tracing::debug!(
4544 "xdg_positioner#{}.set_anchor_rect({}, {}, {}, {})",
4545 sender_id,
4546 x,
4547 y,
4548 width,
4549 height
4550 );
4551 self.set_anchor_rect(client, sender_id, x, y, width, height)
4552 .await
4553 }
4554 3u16 => {
4555 let anchor = message.uint()?;
4556 tracing::debug!("xdg_positioner#{}.set_anchor({})", sender_id, anchor);
4557 self.set_anchor(client, sender_id, anchor.try_into()?).await
4558 }
4559 4u16 => {
4560 let gravity = message.uint()?;
4561 tracing::debug!(
4562 "xdg_positioner#{}.set_gravity({})",
4563 sender_id,
4564 gravity
4565 );
4566 self.set_gravity(client, sender_id, gravity.try_into()?)
4567 .await
4568 }
4569 5u16 => {
4570 let constraint_adjustment = message.uint()?;
4571 tracing::debug!(
4572 "xdg_positioner#{}.set_constraint_adjustment({})",
4573 sender_id,
4574 constraint_adjustment
4575 );
4576 self.set_constraint_adjustment(
4577 client,
4578 sender_id,
4579 constraint_adjustment.try_into()?,
4580 )
4581 .await
4582 }
4583 6u16 => {
4584 let x = message.int()?;
4585 let y = message.int()?;
4586 tracing::debug!(
4587 "xdg_positioner#{}.set_offset({}, {})",
4588 sender_id,
4589 x,
4590 y
4591 );
4592 self.set_offset(client, sender_id, x, y).await
4593 }
4594 7u16 => {
4595 tracing::debug!("xdg_positioner#{}.set_reactive()", sender_id,);
4596 self.set_reactive(client, sender_id).await
4597 }
4598 8u16 => {
4599 let parent_width = message.int()?;
4600 let parent_height = message.int()?;
4601 tracing::debug!(
4602 "xdg_positioner#{}.set_parent_size({}, {})",
4603 sender_id,
4604 parent_width,
4605 parent_height
4606 );
4607 self.set_parent_size(client, sender_id, parent_width, parent_height)
4608 .await
4609 }
4610 9u16 => {
4611 let serial = message.uint()?;
4612 tracing::debug!(
4613 "xdg_positioner#{}.set_parent_configure({})",
4614 sender_id,
4615 serial
4616 );
4617 self.set_parent_configure(client, sender_id, serial).await
4618 }
4619 opcode => Err(crate::server::error::Error::UnknownOpcode(opcode)),
4620 }
4621 }
4622 }
4623 #[doc = ""]
4624 #[doc = "Notify the compositor that the xdg_positioner will no longer be used."]
4625 #[doc = ""]
4626 fn destroy(
4627 &self,
4628 client: &mut crate::server::Client,
4629 sender_id: crate::wire::ObjectId,
4630 ) -> impl Future<Output = crate::server::Result<()>> + Send;
4631 #[doc = ""]
4632 #[doc = "Set the size of the surface that is to be positioned with the positioner"]
4633 #[doc = "object. The size is in surface-local coordinates and corresponds to the"]
4634 #[doc = "window geometry. See xdg_surface.set_window_geometry."]
4635 #[doc = ""]
4636 #[doc = "If a zero or negative size is set the invalid_input error is raised."]
4637 #[doc = ""]
4638 fn set_size(
4639 &self,
4640 client: &mut crate::server::Client,
4641 sender_id: crate::wire::ObjectId,
4642 width: i32,
4643 height: i32,
4644 ) -> impl Future<Output = crate::server::Result<()>> + Send;
4645 #[doc = ""]
4646 #[doc = "Specify the anchor rectangle within the parent surface that the child"]
4647 #[doc = "surface will be placed relative to. The rectangle is relative to the"]
4648 #[doc = "window geometry as defined by xdg_surface.set_window_geometry of the"]
4649 #[doc = "parent surface."]
4650 #[doc = ""]
4651 #[doc = "When the xdg_positioner object is used to position a child surface, the"]
4652 #[doc = "anchor rectangle may not extend outside the window geometry of the"]
4653 #[doc = "positioned child's parent surface."]
4654 #[doc = ""]
4655 #[doc = "If a negative size is set the invalid_input error is raised."]
4656 #[doc = ""]
4657 fn set_anchor_rect(
4658 &self,
4659 client: &mut crate::server::Client,
4660 sender_id: crate::wire::ObjectId,
4661 x: i32,
4662 y: i32,
4663 width: i32,
4664 height: i32,
4665 ) -> impl Future<Output = crate::server::Result<()>> + Send;
4666 #[doc = ""]
4667 #[doc = "Defines the anchor point for the anchor rectangle. The specified anchor"]
4668 #[doc = "is used derive an anchor point that the child surface will be"]
4669 #[doc = "positioned relative to. If a corner anchor is set (e.g. 'top_left' or"]
4670 #[doc = "'bottom_right'), the anchor point will be at the specified corner;"]
4671 #[doc = "otherwise, the derived anchor point will be centered on the specified"]
4672 #[doc = "edge, or in the center of the anchor rectangle if no edge is specified."]
4673 #[doc = ""]
4674 fn set_anchor(
4675 &self,
4676 client: &mut crate::server::Client,
4677 sender_id: crate::wire::ObjectId,
4678 anchor: Anchor,
4679 ) -> impl Future<Output = crate::server::Result<()>> + Send;
4680 #[doc = ""]
4681 #[doc = "Defines in what direction a surface should be positioned, relative to"]
4682 #[doc = "the anchor point of the parent surface. If a corner gravity is"]
4683 #[doc = "specified (e.g. 'bottom_right' or 'top_left'), then the child surface"]
4684 #[doc = "will be placed towards the specified gravity; otherwise, the child"]
4685 #[doc = "surface will be centered over the anchor point on any axis that had no"]
4686 #[doc = "gravity specified. If the gravity is not in the ‘gravity’ enum, an"]
4687 #[doc = "invalid_input error is raised."]
4688 #[doc = ""]
4689 fn set_gravity(
4690 &self,
4691 client: &mut crate::server::Client,
4692 sender_id: crate::wire::ObjectId,
4693 gravity: Gravity,
4694 ) -> impl Future<Output = crate::server::Result<()>> + Send;
4695 #[doc = ""]
4696 #[doc = "Specify how the window should be positioned if the originally intended"]
4697 #[doc = "position caused the surface to be constrained, meaning at least"]
4698 #[doc = "partially outside positioning boundaries set by the compositor. The"]
4699 #[doc = "adjustment is set by constructing a bitmask describing the adjustment to"]
4700 #[doc = "be made when the surface is constrained on that axis."]
4701 #[doc = ""]
4702 #[doc = "If no bit for one axis is set, the compositor will assume that the child"]
4703 #[doc = "surface should not change its position on that axis when constrained."]
4704 #[doc = ""]
4705 #[doc = "If more than one bit for one axis is set, the order of how adjustments"]
4706 #[doc = "are applied is specified in the corresponding adjustment descriptions."]
4707 #[doc = ""]
4708 #[doc = "The default adjustment is none."]
4709 #[doc = ""]
4710 fn set_constraint_adjustment(
4711 &self,
4712 client: &mut crate::server::Client,
4713 sender_id: crate::wire::ObjectId,
4714 constraint_adjustment: ConstraintAdjustment,
4715 ) -> impl Future<Output = crate::server::Result<()>> + Send;
4716 #[doc = ""]
4717 #[doc = "Specify the surface position offset relative to the position of the"]
4718 #[doc = "anchor on the anchor rectangle and the anchor on the surface. For"]
4719 #[doc = "example if the anchor of the anchor rectangle is at (x, y), the surface"]
4720 #[doc = "has the gravity bottom|right, and the offset is (ox, oy), the calculated"]
4721 #[doc = "surface position will be (x + ox, y + oy). The offset position of the"]
4722 #[doc = "surface is the one used for constraint testing. See"]
4723 #[doc = "set_constraint_adjustment."]
4724 #[doc = ""]
4725 #[doc = "An example use case is placing a popup menu on top of a user interface"]
4726 #[doc = "element, while aligning the user interface element of the parent surface"]
4727 #[doc = "with some user interface element placed somewhere in the popup surface."]
4728 #[doc = ""]
4729 fn set_offset(
4730 &self,
4731 client: &mut crate::server::Client,
4732 sender_id: crate::wire::ObjectId,
4733 x: i32,
4734 y: i32,
4735 ) -> impl Future<Output = crate::server::Result<()>> + Send;
4736 #[doc = ""]
4737 #[doc = "When set reactive, the surface is reconstrained if the conditions used"]
4738 #[doc = "for constraining changed, e.g. the parent window moved."]
4739 #[doc = ""]
4740 #[doc = "If the conditions changed and the popup was reconstrained, an"]
4741 #[doc = "xdg_popup.configure event is sent with updated geometry, followed by an"]
4742 #[doc = "xdg_surface.configure event."]
4743 #[doc = ""]
4744 fn set_reactive(
4745 &self,
4746 client: &mut crate::server::Client,
4747 sender_id: crate::wire::ObjectId,
4748 ) -> impl Future<Output = crate::server::Result<()>> + Send;
4749 #[doc = ""]
4750 #[doc = "Set the parent window geometry the compositor should use when"]
4751 #[doc = "positioning the popup. The compositor may use this information to"]
4752 #[doc = "determine the future state the popup should be constrained using. If"]
4753 #[doc = "this doesn't match the dimension of the parent the popup is eventually"]
4754 #[doc = "positioned against, the behavior is undefined."]
4755 #[doc = ""]
4756 #[doc = "The arguments are given in the surface-local coordinate space."]
4757 #[doc = ""]
4758 fn set_parent_size(
4759 &self,
4760 client: &mut crate::server::Client,
4761 sender_id: crate::wire::ObjectId,
4762 parent_width: i32,
4763 parent_height: i32,
4764 ) -> impl Future<Output = crate::server::Result<()>> + Send;
4765 #[doc = ""]
4766 #[doc = "Set the serial of an xdg_surface.configure event this positioner will be"]
4767 #[doc = "used in response to. The compositor may use this information together"]
4768 #[doc = "with set_parent_size to determine what future state the popup should be"]
4769 #[doc = "constrained using."]
4770 #[doc = ""]
4771 fn set_parent_configure(
4772 &self,
4773 client: &mut crate::server::Client,
4774 sender_id: crate::wire::ObjectId,
4775 serial: u32,
4776 ) -> impl Future<Output = crate::server::Result<()>> + Send;
4777 }
4778 }
4779 #[doc = ""]
4780 #[doc = "An interface that may be implemented by a wl_surface, for"]
4781 #[doc = "implementations that provide a desktop-style user interface."]
4782 #[doc = ""]
4783 #[doc = "It provides a base set of functionality required to construct user"]
4784 #[doc = "interface elements requiring management by the compositor, such as"]
4785 #[doc = "toplevel windows, menus, etc. The types of functionality are split into"]
4786 #[doc = "xdg_surface roles."]
4787 #[doc = ""]
4788 #[doc = "Creating an xdg_surface does not set the role for a wl_surface. In order"]
4789 #[doc = "to map an xdg_surface, the client must create a role-specific object"]
4790 #[doc = "using, e.g., get_toplevel, get_popup. The wl_surface for any given"]
4791 #[doc = "xdg_surface can have at most one role, and may not be assigned any role"]
4792 #[doc = "not based on xdg_surface."]
4793 #[doc = ""]
4794 #[doc = "A role must be assigned before any other requests are made to the"]
4795 #[doc = "xdg_surface object."]
4796 #[doc = ""]
4797 #[doc = "The client must call wl_surface.commit on the corresponding wl_surface"]
4798 #[doc = "for the xdg_surface state to take effect."]
4799 #[doc = ""]
4800 #[doc = "Creating an xdg_surface from a wl_surface which has a buffer attached or"]
4801 #[doc = "committed is a client error, and any attempts by a client to attach or"]
4802 #[doc = "manipulate a buffer prior to the first xdg_surface.configure call must"]
4803 #[doc = "also be treated as errors."]
4804 #[doc = ""]
4805 #[doc = "After creating a role-specific object and setting it up (e.g. by sending"]
4806 #[doc = "the title, app ID, size constraints, parent, etc), the client must"]
4807 #[doc = "perform an initial commit without any buffer attached. The compositor"]
4808 #[doc = "will reply with initial wl_surface state such as"]
4809 #[doc = "wl_surface.preferred_buffer_scale followed by an xdg_surface.configure"]
4810 #[doc = "event. The client must acknowledge it and is then allowed to attach a"]
4811 #[doc = "buffer to map the surface."]
4812 #[doc = ""]
4813 #[doc = "Mapping an xdg_surface-based role surface is defined as making it"]
4814 #[doc = "possible for the surface to be shown by the compositor. Note that"]
4815 #[doc = "a mapped surface is not guaranteed to be visible once it is mapped."]
4816 #[doc = ""]
4817 #[doc = "For an xdg_surface to be mapped by the compositor, the following"]
4818 #[doc = "conditions must be met:"]
4819 #[doc = "(1) the client has assigned an xdg_surface-based role to the surface"]
4820 #[doc = "(2) the client has set and committed the xdg_surface state and the"]
4821 #[doc = "role-dependent state to the surface"]
4822 #[doc = "(3) the client has committed a buffer to the surface"]
4823 #[doc = ""]
4824 #[doc = "A newly-unmapped surface is considered to have met condition (1) out"]
4825 #[doc = "of the 3 required conditions for mapping a surface if its role surface"]
4826 #[doc = "has not been destroyed, i.e. the client must perform the initial commit"]
4827 #[doc = "again before attaching a buffer."]
4828 #[doc = ""]
4829 #[allow(clippy::too_many_arguments)]
4830 pub mod xdg_surface {
4831 #[allow(unused)]
4832 use futures_util::SinkExt;
4833 #[allow(unused)]
4834 use std::os::fd::AsRawFd;
4835 #[repr(u32)]
4836 #[non_exhaustive]
4837 #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy)]
4838 pub enum Error {
4839 #[doc = "Surface was not fully constructed"]
4840 NotConstructed = 1u32,
4841 #[doc = "Surface was already constructed"]
4842 AlreadyConstructed = 2u32,
4843 #[doc = "Attaching a buffer to an unconfigured surface"]
4844 UnconfiguredBuffer = 3u32,
4845 #[doc = "Invalid serial number when acking a configure event"]
4846 InvalidSerial = 4u32,
4847 #[doc = "Width or height was zero or negative"]
4848 InvalidSize = 5u32,
4849 #[doc = "Surface was destroyed before its role object"]
4850 DefunctRoleObject = 6u32,
4851 }
4852 impl TryFrom<u32> for Error {
4853 type Error = crate::wire::DecodeError;
4854 fn try_from(v: u32) -> Result<Self, Self::Error> {
4855 match v {
4856 1u32 => Ok(Self::NotConstructed),
4857 2u32 => Ok(Self::AlreadyConstructed),
4858 3u32 => Ok(Self::UnconfiguredBuffer),
4859 4u32 => Ok(Self::InvalidSerial),
4860 5u32 => Ok(Self::InvalidSize),
4861 6u32 => Ok(Self::DefunctRoleObject),
4862 _ => Err(crate::wire::DecodeError::MalformedPayload),
4863 }
4864 }
4865 }
4866 impl std::fmt::Display for Error {
4867 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
4868 (*self as u32).fmt(f)
4869 }
4870 }
4871 #[doc = "Trait to implement the xdg_surface interface. See the module level documentation for more info"]
4872 pub trait XdgSurface: crate::server::Dispatcher {
4873 const INTERFACE: &'static str = "xdg_surface";
4874 const VERSION: u32 = 7u32;
4875 fn handle_request(
4876 &self,
4877 client: &mut crate::server::Client,
4878 sender_id: crate::wire::ObjectId,
4879 message: &mut crate::wire::Message,
4880 ) -> impl Future<Output = crate::server::Result<()>> + Send {
4881 async move {
4882 #[allow(clippy::match_single_binding)]
4883 match message.opcode() {
4884 0u16 => {
4885 tracing::debug!("xdg_surface#{}.destroy()", sender_id,);
4886 let result = self.destroy(client, sender_id).await;
4887 client.remove(sender_id);
4888 result
4889 }
4890 1u16 => {
4891 let id = message
4892 .object()?
4893 .ok_or(crate::wire::DecodeError::MalformedPayload)?;
4894 tracing::debug!("xdg_surface#{}.get_toplevel({})", sender_id, id);
4895 self.get_toplevel(client, sender_id, id).await
4896 }
4897 2u16 => {
4898 let id = message
4899 .object()?
4900 .ok_or(crate::wire::DecodeError::MalformedPayload)?;
4901 let parent = message.object()?;
4902 let positioner = message
4903 .object()?
4904 .ok_or(crate::wire::DecodeError::MalformedPayload)?;
4905 tracing::debug!(
4906 "xdg_surface#{}.get_popup({}, {}, {})",
4907 sender_id,
4908 id,
4909 parent
4910 .as_ref()
4911 .map_or("null".to_string(), |v| v.to_string()),
4912 positioner
4913 );
4914 self.get_popup(client, sender_id, id, parent, positioner)
4915 .await
4916 }
4917 3u16 => {
4918 let x = message.int()?;
4919 let y = message.int()?;
4920 let width = message.int()?;
4921 let height = message.int()?;
4922 tracing::debug!(
4923 "xdg_surface#{}.set_window_geometry({}, {}, {}, {})",
4924 sender_id,
4925 x,
4926 y,
4927 width,
4928 height
4929 );
4930 self.set_window_geometry(client, sender_id, x, y, width, height)
4931 .await
4932 }
4933 4u16 => {
4934 let serial = message.uint()?;
4935 tracing::debug!("xdg_surface#{}.ack_configure({})", sender_id, serial);
4936 self.ack_configure(client, sender_id, serial).await
4937 }
4938 opcode => Err(crate::server::error::Error::UnknownOpcode(opcode)),
4939 }
4940 }
4941 }
4942 #[doc = ""]
4943 #[doc = "Destroy the xdg_surface object. An xdg_surface must only be destroyed"]
4944 #[doc = "after its role object has been destroyed, otherwise"]
4945 #[doc = "a defunct_role_object error is raised."]
4946 #[doc = ""]
4947 fn destroy(
4948 &self,
4949 client: &mut crate::server::Client,
4950 sender_id: crate::wire::ObjectId,
4951 ) -> impl Future<Output = crate::server::Result<()>> + Send;
4952 #[doc = ""]
4953 #[doc = "This creates an xdg_toplevel object for the given xdg_surface and gives"]
4954 #[doc = "the associated wl_surface the xdg_toplevel role."]
4955 #[doc = ""]
4956 #[doc = "See the documentation of xdg_toplevel for more details about what an"]
4957 #[doc = "xdg_toplevel is and how it is used."]
4958 #[doc = ""]
4959 fn get_toplevel(
4960 &self,
4961 client: &mut crate::server::Client,
4962 sender_id: crate::wire::ObjectId,
4963 id: crate::wire::ObjectId,
4964 ) -> impl Future<Output = crate::server::Result<()>> + Send;
4965 #[doc = ""]
4966 #[doc = "This creates an xdg_popup object for the given xdg_surface and gives"]
4967 #[doc = "the associated wl_surface the xdg_popup role."]
4968 #[doc = ""]
4969 #[doc = "If null is passed as a parent, a parent surface must be specified using"]
4970 #[doc = "some other protocol, before committing the initial state."]
4971 #[doc = ""]
4972 #[doc = "See the documentation of xdg_popup for more details about what an"]
4973 #[doc = "xdg_popup is and how it is used."]
4974 #[doc = ""]
4975 fn get_popup(
4976 &self,
4977 client: &mut crate::server::Client,
4978 sender_id: crate::wire::ObjectId,
4979 id: crate::wire::ObjectId,
4980 parent: Option<crate::wire::ObjectId>,
4981 positioner: crate::wire::ObjectId,
4982 ) -> impl Future<Output = crate::server::Result<()>> + Send;
4983 #[doc = ""]
4984 #[doc = "The window geometry of a surface is its \"visible bounds\" from the"]
4985 #[doc = "user's perspective. Client-side decorations often have invisible"]
4986 #[doc = "portions like drop-shadows which should be ignored for the"]
4987 #[doc = "purposes of aligning, placing and constraining windows."]
4988 #[doc = ""]
4989 #[doc = "The window geometry is double-buffered state, see wl_surface.commit."]
4990 #[doc = ""]
4991 #[doc = "When maintaining a position, the compositor should treat the (x, y)"]
4992 #[doc = "coordinate of the window geometry as the top left corner of the window."]
4993 #[doc = "A client changing the (x, y) window geometry coordinate should in"]
4994 #[doc = "general not alter the position of the window."]
4995 #[doc = ""]
4996 #[doc = "Once the window geometry of the surface is set, it is not possible to"]
4997 #[doc = "unset it, and it will remain the same until set_window_geometry is"]
4998 #[doc = "called again, even if a new subsurface or buffer is attached."]
4999 #[doc = ""]
5000 #[doc = "If never set, the value is the full bounds of the surface,"]
5001 #[doc = "including any subsurfaces. This updates dynamically on every"]
5002 #[doc = "commit. This unset is meant for extremely simple clients."]
5003 #[doc = ""]
5004 #[doc = "The arguments are given in the surface-local coordinate space of"]
5005 #[doc = "the wl_surface associated with this xdg_surface, and may extend outside"]
5006 #[doc = "of the wl_surface itself to mark parts of the subsurface tree as part of"]
5007 #[doc = "the window geometry."]
5008 #[doc = ""]
5009 #[doc = "When applied, the effective window geometry will be the set window"]
5010 #[doc = "geometry clamped to the bounding rectangle of the combined"]
5011 #[doc = "geometry of the surface of the xdg_surface and the associated"]
5012 #[doc = "subsurfaces."]
5013 #[doc = ""]
5014 #[doc = "The effective geometry will not be recalculated unless a new call to"]
5015 #[doc = "set_window_geometry is done and the new pending surface state is"]
5016 #[doc = "subsequently applied."]
5017 #[doc = ""]
5018 #[doc = "The width and height of the effective window geometry must be"]
5019 #[doc = "greater than zero. Setting an invalid size will raise an"]
5020 #[doc = "invalid_size error."]
5021 #[doc = ""]
5022 fn set_window_geometry(
5023 &self,
5024 client: &mut crate::server::Client,
5025 sender_id: crate::wire::ObjectId,
5026 x: i32,
5027 y: i32,
5028 width: i32,
5029 height: i32,
5030 ) -> impl Future<Output = crate::server::Result<()>> + Send;
5031 #[doc = ""]
5032 #[doc = "When a configure event is received, if a client commits the"]
5033 #[doc = "surface in response to the configure event, then the client"]
5034 #[doc = "must make an ack_configure request sometime before the commit"]
5035 #[doc = "request, passing along the serial of the configure event."]
5036 #[doc = ""]
5037 #[doc = "For instance, for toplevel surfaces the compositor might use this"]
5038 #[doc = "information to move a surface to the top left only when the client has"]
5039 #[doc = "drawn itself for the maximized or fullscreen state."]
5040 #[doc = ""]
5041 #[doc = "If the client receives multiple configure events before it"]
5042 #[doc = "can respond to one, it only has to ack the last configure event."]
5043 #[doc = "Acking a configure event that was never sent raises an invalid_serial"]
5044 #[doc = "error."]
5045 #[doc = ""]
5046 #[doc = "A client is not required to commit immediately after sending"]
5047 #[doc = "an ack_configure request - it may even ack_configure several times"]
5048 #[doc = "before its next surface commit."]
5049 #[doc = ""]
5050 #[doc = "A client may send multiple ack_configure requests before committing, but"]
5051 #[doc = "only the last request sent before a commit indicates which configure"]
5052 #[doc = "event the client really is responding to."]
5053 #[doc = ""]
5054 #[doc = "Sending an ack_configure request consumes the serial number sent with"]
5055 #[doc = "the request, as well as serial numbers sent by all configure events"]
5056 #[doc = "sent on this xdg_surface prior to the configure event referenced by"]
5057 #[doc = "the committed serial."]
5058 #[doc = ""]
5059 #[doc = "It is an error to issue multiple ack_configure requests referencing a"]
5060 #[doc = "serial from the same configure event, or to issue an ack_configure"]
5061 #[doc = "request referencing a serial from a configure event issued before the"]
5062 #[doc = "event identified by the last ack_configure request for the same"]
5063 #[doc = "xdg_surface. Doing so will raise an invalid_serial error."]
5064 #[doc = ""]
5065 fn ack_configure(
5066 &self,
5067 client: &mut crate::server::Client,
5068 sender_id: crate::wire::ObjectId,
5069 serial: u32,
5070 ) -> impl Future<Output = crate::server::Result<()>> + Send;
5071 #[doc = ""]
5072 #[doc = "The configure event marks the end of a configure sequence. A configure"]
5073 #[doc = "sequence is a set of one or more events configuring the state of the"]
5074 #[doc = "xdg_surface, including the final xdg_surface.configure event."]
5075 #[doc = ""]
5076 #[doc = "Where applicable, xdg_surface surface roles will during a configure"]
5077 #[doc = "sequence extend this event as a latched state sent as events before the"]
5078 #[doc = "xdg_surface.configure event. Such events should be considered to make up"]
5079 #[doc = "a set of atomically applied configuration states, where the"]
5080 #[doc = "xdg_surface.configure commits the accumulated state."]
5081 #[doc = ""]
5082 #[doc = "Clients should arrange their surface for the new states, and then send"]
5083 #[doc = "an ack_configure request with the serial sent in this configure event at"]
5084 #[doc = "some point before committing the new surface."]
5085 #[doc = ""]
5086 #[doc = "If the client receives multiple configure events before it can respond"]
5087 #[doc = "to one, it is free to discard all but the last event it received."]
5088 #[doc = ""]
5089 fn configure(
5090 &self,
5091 client: &mut crate::server::Client,
5092 sender_id: crate::wire::ObjectId,
5093 serial: u32,
5094 ) -> impl Future<Output = crate::server::Result<()>> + Send {
5095 async move {
5096 tracing::debug!("-> xdg_surface#{}.configure({})", sender_id, serial);
5097 let (payload, fds) =
5098 crate::wire::PayloadBuilder::new().put_uint(serial).build();
5099 client
5100 .send_message(crate::wire::Message::new(sender_id, 0u16, payload, fds))
5101 .await
5102 .map_err(crate::server::error::Error::IoError)
5103 }
5104 }
5105 }
5106 }
5107 #[doc = ""]
5108 #[doc = "This interface defines an xdg_surface role which allows a surface to,"]
5109 #[doc = "among other things, set window-like properties such as maximize,"]
5110 #[doc = "fullscreen, and minimize, set application-specific metadata like title and"]
5111 #[doc = "id, and well as trigger user interactive operations such as interactive"]
5112 #[doc = "resize and move."]
5113 #[doc = ""]
5114 #[doc = "A xdg_toplevel by default is responsible for providing the full intended"]
5115 #[doc = "visual representation of the toplevel, which depending on the window"]
5116 #[doc = "state, may mean things like a title bar, window controls and drop shadow."]
5117 #[doc = ""]
5118 #[doc = "Unmapping an xdg_toplevel means that the surface cannot be shown"]
5119 #[doc = "by the compositor until it is explicitly mapped again."]
5120 #[doc = "All active operations (e.g., move, resize) are canceled and all"]
5121 #[doc = "attributes (e.g. title, state, stacking, ...) are discarded for"]
5122 #[doc = "an xdg_toplevel surface when it is unmapped. The xdg_toplevel returns to"]
5123 #[doc = "the state it had right after xdg_surface.get_toplevel. The client"]
5124 #[doc = "can re-map the toplevel by performing a commit without any buffer"]
5125 #[doc = "attached, waiting for a configure event and handling it as usual (see"]
5126 #[doc = "xdg_surface description)."]
5127 #[doc = ""]
5128 #[doc = "Attaching a null buffer to a toplevel unmaps the surface."]
5129 #[doc = ""]
5130 #[allow(clippy::too_many_arguments)]
5131 pub mod xdg_toplevel {
5132 #[allow(unused)]
5133 use futures_util::SinkExt;
5134 #[allow(unused)]
5135 use std::os::fd::AsRawFd;
5136 #[repr(u32)]
5137 #[non_exhaustive]
5138 #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy)]
5139 pub enum Error {
5140 #[doc = "provided value is"]
5141 #[doc = "not a valid variant of the resize_edge enum"]
5142 InvalidResizeEdge = 0u32,
5143 #[doc = "invalid parent toplevel"]
5144 InvalidParent = 1u32,
5145 #[doc = "client provided an invalid min or max size"]
5146 InvalidSize = 2u32,
5147 }
5148 impl TryFrom<u32> for Error {
5149 type Error = crate::wire::DecodeError;
5150 fn try_from(v: u32) -> Result<Self, Self::Error> {
5151 match v {
5152 0u32 => Ok(Self::InvalidResizeEdge),
5153 1u32 => Ok(Self::InvalidParent),
5154 2u32 => Ok(Self::InvalidSize),
5155 _ => Err(crate::wire::DecodeError::MalformedPayload),
5156 }
5157 }
5158 }
5159 impl std::fmt::Display for Error {
5160 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
5161 (*self as u32).fmt(f)
5162 }
5163 }
5164 #[doc = ""]
5165 #[doc = "These values are used to indicate which edge of a surface"]
5166 #[doc = "is being dragged in a resize operation."]
5167 #[doc = ""]
5168 #[repr(u32)]
5169 #[non_exhaustive]
5170 #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy)]
5171 pub enum ResizeEdge {
5172 None = 0u32,
5173 Top = 1u32,
5174 Bottom = 2u32,
5175 Left = 4u32,
5176 TopLeft = 5u32,
5177 BottomLeft = 6u32,
5178 Right = 8u32,
5179 TopRight = 9u32,
5180 BottomRight = 10u32,
5181 }
5182 impl TryFrom<u32> for ResizeEdge {
5183 type Error = crate::wire::DecodeError;
5184 fn try_from(v: u32) -> Result<Self, Self::Error> {
5185 match v {
5186 0u32 => Ok(Self::None),
5187 1u32 => Ok(Self::Top),
5188 2u32 => Ok(Self::Bottom),
5189 4u32 => Ok(Self::Left),
5190 5u32 => Ok(Self::TopLeft),
5191 6u32 => Ok(Self::BottomLeft),
5192 8u32 => Ok(Self::Right),
5193 9u32 => Ok(Self::TopRight),
5194 10u32 => Ok(Self::BottomRight),
5195 _ => Err(crate::wire::DecodeError::MalformedPayload),
5196 }
5197 }
5198 }
5199 impl std::fmt::Display for ResizeEdge {
5200 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
5201 (*self as u32).fmt(f)
5202 }
5203 }
5204 #[doc = ""]
5205 #[doc = "The different state values used on the surface. This is designed for"]
5206 #[doc = "state values like maximized, fullscreen. It is paired with the"]
5207 #[doc = "configure event to ensure that both the client and the compositor"]
5208 #[doc = "setting the state can be synchronized."]
5209 #[doc = ""]
5210 #[doc = "States set in this way are double-buffered, see wl_surface.commit."]
5211 #[doc = ""]
5212 #[repr(u32)]
5213 #[non_exhaustive]
5214 #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy)]
5215 pub enum State {
5216 #[doc = "the surface is maximized"]
5217 Maximized = 1u32,
5218 #[doc = "the surface is fullscreen"]
5219 Fullscreen = 2u32,
5220 #[doc = "the surface is being resized"]
5221 Resizing = 3u32,
5222 #[doc = "the surface is now activated"]
5223 Activated = 4u32,
5224 TiledLeft = 5u32,
5225 TiledRight = 6u32,
5226 TiledTop = 7u32,
5227 TiledBottom = 8u32,
5228 Suspended = 9u32,
5229 ConstrainedLeft = 10u32,
5230 ConstrainedRight = 11u32,
5231 ConstrainedTop = 12u32,
5232 ConstrainedBottom = 13u32,
5233 }
5234 impl TryFrom<u32> for State {
5235 type Error = crate::wire::DecodeError;
5236 fn try_from(v: u32) -> Result<Self, Self::Error> {
5237 match v {
5238 1u32 => Ok(Self::Maximized),
5239 2u32 => Ok(Self::Fullscreen),
5240 3u32 => Ok(Self::Resizing),
5241 4u32 => Ok(Self::Activated),
5242 5u32 => Ok(Self::TiledLeft),
5243 6u32 => Ok(Self::TiledRight),
5244 7u32 => Ok(Self::TiledTop),
5245 8u32 => Ok(Self::TiledBottom),
5246 9u32 => Ok(Self::Suspended),
5247 10u32 => Ok(Self::ConstrainedLeft),
5248 11u32 => Ok(Self::ConstrainedRight),
5249 12u32 => Ok(Self::ConstrainedTop),
5250 13u32 => Ok(Self::ConstrainedBottom),
5251 _ => Err(crate::wire::DecodeError::MalformedPayload),
5252 }
5253 }
5254 }
5255 impl std::fmt::Display for State {
5256 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
5257 (*self as u32).fmt(f)
5258 }
5259 }
5260 #[repr(u32)]
5261 #[non_exhaustive]
5262 #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy)]
5263 pub enum WmCapabilities {
5264 #[doc = "show_window_menu is available"]
5265 WindowMenu = 1u32,
5266 #[doc = "set_maximized and unset_maximized are available"]
5267 Maximize = 2u32,
5268 #[doc = "set_fullscreen and unset_fullscreen are available"]
5269 Fullscreen = 3u32,
5270 #[doc = "set_minimized is available"]
5271 Minimize = 4u32,
5272 }
5273 impl TryFrom<u32> for WmCapabilities {
5274 type Error = crate::wire::DecodeError;
5275 fn try_from(v: u32) -> Result<Self, Self::Error> {
5276 match v {
5277 1u32 => Ok(Self::WindowMenu),
5278 2u32 => Ok(Self::Maximize),
5279 3u32 => Ok(Self::Fullscreen),
5280 4u32 => Ok(Self::Minimize),
5281 _ => Err(crate::wire::DecodeError::MalformedPayload),
5282 }
5283 }
5284 }
5285 impl std::fmt::Display for WmCapabilities {
5286 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
5287 (*self as u32).fmt(f)
5288 }
5289 }
5290 #[doc = "Trait to implement the xdg_toplevel interface. See the module level documentation for more info"]
5291 pub trait XdgToplevel: crate::server::Dispatcher {
5292 const INTERFACE: &'static str = "xdg_toplevel";
5293 const VERSION: u32 = 7u32;
5294 fn handle_request(
5295 &self,
5296 client: &mut crate::server::Client,
5297 sender_id: crate::wire::ObjectId,
5298 message: &mut crate::wire::Message,
5299 ) -> impl Future<Output = crate::server::Result<()>> + Send {
5300 async move {
5301 #[allow(clippy::match_single_binding)]
5302 match message.opcode() {
5303 0u16 => {
5304 tracing::debug!("xdg_toplevel#{}.destroy()", sender_id,);
5305 let result = self.destroy(client, sender_id).await;
5306 client.remove(sender_id);
5307 result
5308 }
5309 1u16 => {
5310 let parent = message.object()?;
5311 tracing::debug!(
5312 "xdg_toplevel#{}.set_parent({})",
5313 sender_id,
5314 parent
5315 .as_ref()
5316 .map_or("null".to_string(), |v| v.to_string())
5317 );
5318 self.set_parent(client, sender_id, parent).await
5319 }
5320 2u16 => {
5321 let title = message
5322 .string()?
5323 .ok_or(crate::wire::DecodeError::MalformedPayload)?;
5324 tracing::debug!("xdg_toplevel#{}.set_title(\"{}\")", sender_id, title);
5325 self.set_title(client, sender_id, title).await
5326 }
5327 3u16 => {
5328 let app_id = message
5329 .string()?
5330 .ok_or(crate::wire::DecodeError::MalformedPayload)?;
5331 tracing::debug!(
5332 "xdg_toplevel#{}.set_app_id(\"{}\")",
5333 sender_id,
5334 app_id
5335 );
5336 self.set_app_id(client, sender_id, app_id).await
5337 }
5338 4u16 => {
5339 let seat = message
5340 .object()?
5341 .ok_or(crate::wire::DecodeError::MalformedPayload)?;
5342 let serial = message.uint()?;
5343 let x = message.int()?;
5344 let y = message.int()?;
5345 tracing::debug!(
5346 "xdg_toplevel#{}.show_window_menu({}, {}, {}, {})",
5347 sender_id,
5348 seat,
5349 serial,
5350 x,
5351 y
5352 );
5353 self.show_window_menu(client, sender_id, seat, serial, x, y)
5354 .await
5355 }
5356 5u16 => {
5357 let seat = message
5358 .object()?
5359 .ok_or(crate::wire::DecodeError::MalformedPayload)?;
5360 let serial = message.uint()?;
5361 tracing::debug!(
5362 "xdg_toplevel#{}.move({}, {})",
5363 sender_id,
5364 seat,
5365 serial
5366 );
5367 self.r#move(client, sender_id, seat, serial).await
5368 }
5369 6u16 => {
5370 let seat = message
5371 .object()?
5372 .ok_or(crate::wire::DecodeError::MalformedPayload)?;
5373 let serial = message.uint()?;
5374 let edges = message.uint()?;
5375 tracing::debug!(
5376 "xdg_toplevel#{}.resize({}, {}, {})",
5377 sender_id,
5378 seat,
5379 serial,
5380 edges
5381 );
5382 self.resize(client, sender_id, seat, serial, edges.try_into()?)
5383 .await
5384 }
5385 7u16 => {
5386 let width = message.int()?;
5387 let height = message.int()?;
5388 tracing::debug!(
5389 "xdg_toplevel#{}.set_max_size({}, {})",
5390 sender_id,
5391 width,
5392 height
5393 );
5394 self.set_max_size(client, sender_id, width, height).await
5395 }
5396 8u16 => {
5397 let width = message.int()?;
5398 let height = message.int()?;
5399 tracing::debug!(
5400 "xdg_toplevel#{}.set_min_size({}, {})",
5401 sender_id,
5402 width,
5403 height
5404 );
5405 self.set_min_size(client, sender_id, width, height).await
5406 }
5407 9u16 => {
5408 tracing::debug!("xdg_toplevel#{}.set_maximized()", sender_id,);
5409 self.set_maximized(client, sender_id).await
5410 }
5411 10u16 => {
5412 tracing::debug!("xdg_toplevel#{}.unset_maximized()", sender_id,);
5413 self.unset_maximized(client, sender_id).await
5414 }
5415 11u16 => {
5416 let output = message.object()?;
5417 tracing::debug!(
5418 "xdg_toplevel#{}.set_fullscreen({})",
5419 sender_id,
5420 output
5421 .as_ref()
5422 .map_or("null".to_string(), |v| v.to_string())
5423 );
5424 self.set_fullscreen(client, sender_id, output).await
5425 }
5426 12u16 => {
5427 tracing::debug!("xdg_toplevel#{}.unset_fullscreen()", sender_id,);
5428 self.unset_fullscreen(client, sender_id).await
5429 }
5430 13u16 => {
5431 tracing::debug!("xdg_toplevel#{}.set_minimized()", sender_id,);
5432 self.set_minimized(client, sender_id).await
5433 }
5434 opcode => Err(crate::server::error::Error::UnknownOpcode(opcode)),
5435 }
5436 }
5437 }
5438 #[doc = ""]
5439 #[doc = "This request destroys the role surface and unmaps the surface;"]
5440 #[doc = "see \"Unmapping\" behavior in interface section for details."]
5441 #[doc = ""]
5442 fn destroy(
5443 &self,
5444 client: &mut crate::server::Client,
5445 sender_id: crate::wire::ObjectId,
5446 ) -> impl Future<Output = crate::server::Result<()>> + Send;
5447 #[doc = ""]
5448 #[doc = "Set the \"parent\" of this surface. This surface should be stacked"]
5449 #[doc = "above the parent surface and all other ancestor surfaces."]
5450 #[doc = ""]
5451 #[doc = "Parent surfaces should be set on dialogs, toolboxes, or other"]
5452 #[doc = "\"auxiliary\" surfaces, so that the parent is raised when the dialog"]
5453 #[doc = "is raised."]
5454 #[doc = ""]
5455 #[doc = "Setting a null parent for a child surface unsets its parent. Setting"]
5456 #[doc = "a null parent for a surface which currently has no parent is a no-op."]
5457 #[doc = ""]
5458 #[doc = "Only mapped surfaces can have child surfaces. Setting a parent which"]
5459 #[doc = "is not mapped is equivalent to setting a null parent. If a surface"]
5460 #[doc = "becomes unmapped, its children's parent is set to the parent of"]
5461 #[doc = "the now-unmapped surface. If the now-unmapped surface has no parent,"]
5462 #[doc = "its children's parent is unset. If the now-unmapped surface becomes"]
5463 #[doc = "mapped again, its parent-child relationship is not restored."]
5464 #[doc = ""]
5465 #[doc = "The parent toplevel must not be one of the child toplevel's"]
5466 #[doc = "descendants, and the parent must be different from the child toplevel,"]
5467 #[doc = "otherwise the invalid_parent protocol error is raised."]
5468 #[doc = ""]
5469 fn set_parent(
5470 &self,
5471 client: &mut crate::server::Client,
5472 sender_id: crate::wire::ObjectId,
5473 parent: Option<crate::wire::ObjectId>,
5474 ) -> impl Future<Output = crate::server::Result<()>> + Send;
5475 #[doc = ""]
5476 #[doc = "Set a short title for the surface."]
5477 #[doc = ""]
5478 #[doc = "This string may be used to identify the surface in a task bar,"]
5479 #[doc = "window list, or other user interface elements provided by the"]
5480 #[doc = "compositor."]
5481 #[doc = ""]
5482 #[doc = "The string must be encoded in UTF-8."]
5483 #[doc = ""]
5484 fn set_title(
5485 &self,
5486 client: &mut crate::server::Client,
5487 sender_id: crate::wire::ObjectId,
5488 title: String,
5489 ) -> impl Future<Output = crate::server::Result<()>> + Send;
5490 #[doc = ""]
5491 #[doc = "Set an application identifier for the surface."]
5492 #[doc = ""]
5493 #[doc = "The app ID identifies the general class of applications to which"]
5494 #[doc = "the surface belongs. The compositor can use this to group multiple"]
5495 #[doc = "surfaces together, or to determine how to launch a new application."]
5496 #[doc = ""]
5497 #[doc = "For D-Bus activatable applications, the app ID is used as the D-Bus"]
5498 #[doc = "service name."]
5499 #[doc = ""]
5500 #[doc = "The compositor shell will try to group application surfaces together"]
5501 #[doc = "by their app ID. As a best practice, it is suggested to select app"]
5502 #[doc = "ID's that match the basename of the application's .desktop file."]
5503 #[doc = "For example, \"org.freedesktop.FooViewer\" where the .desktop file is"]
5504 #[doc = "\"org.freedesktop.FooViewer.desktop\"."]
5505 #[doc = ""]
5506 #[doc = "Like other properties, a set_app_id request can be sent after the"]
5507 #[doc = "xdg_toplevel has been mapped to update the property."]
5508 #[doc = ""]
5509 #[doc = "See the desktop-entry specification [0] for more details on"]
5510 #[doc = "application identifiers and how they relate to well-known D-Bus"]
5511 #[doc = "names and .desktop files."]
5512 #[doc = ""]
5513 #[doc = "[0] https://standards.freedesktop.org/desktop-entry-spec/"]
5514 #[doc = ""]
5515 fn set_app_id(
5516 &self,
5517 client: &mut crate::server::Client,
5518 sender_id: crate::wire::ObjectId,
5519 app_id: String,
5520 ) -> impl Future<Output = crate::server::Result<()>> + Send;
5521 #[doc = ""]
5522 #[doc = "Clients implementing client-side decorations might want to show"]
5523 #[doc = "a context menu when right-clicking on the decorations, giving the"]
5524 #[doc = "user a menu that they can use to maximize or minimize the window."]
5525 #[doc = ""]
5526 #[doc = "This request asks the compositor to pop up such a window menu at"]
5527 #[doc = "the given position, relative to the local surface coordinates of"]
5528 #[doc = "the parent surface. There are no guarantees as to what menu items"]
5529 #[doc = "the window menu contains, or even if a window menu will be drawn"]
5530 #[doc = "at all."]
5531 #[doc = ""]
5532 #[doc = "This request must be used in response to some sort of user action"]
5533 #[doc = "like a button press, key press, or touch down event."]
5534 #[doc = ""]
5535 fn show_window_menu(
5536 &self,
5537 client: &mut crate::server::Client,
5538 sender_id: crate::wire::ObjectId,
5539 seat: crate::wire::ObjectId,
5540 serial: u32,
5541 x: i32,
5542 y: i32,
5543 ) -> impl Future<Output = crate::server::Result<()>> + Send;
5544 #[doc = ""]
5545 #[doc = "Start an interactive, user-driven move of the surface."]
5546 #[doc = ""]
5547 #[doc = "This request must be used in response to some sort of user action"]
5548 #[doc = "like a button press, key press, or touch down event. The passed"]
5549 #[doc = "serial is used to determine the type of interactive move (touch,"]
5550 #[doc = "pointer, etc)."]
5551 #[doc = ""]
5552 #[doc = "The server may ignore move requests depending on the state of"]
5553 #[doc = "the surface (e.g. fullscreen or maximized), or if the passed serial"]
5554 #[doc = "is no longer valid."]
5555 #[doc = ""]
5556 #[doc = "If triggered, the surface will lose the focus of the device"]
5557 #[doc = "(wl_pointer, wl_touch, etc) used for the move. It is up to the"]
5558 #[doc = "compositor to visually indicate that the move is taking place, such as"]
5559 #[doc = "updating a pointer cursor, during the move. There is no guarantee"]
5560 #[doc = "that the device focus will return when the move is completed."]
5561 #[doc = ""]
5562 fn r#move(
5563 &self,
5564 client: &mut crate::server::Client,
5565 sender_id: crate::wire::ObjectId,
5566 seat: crate::wire::ObjectId,
5567 serial: u32,
5568 ) -> impl Future<Output = crate::server::Result<()>> + Send;
5569 #[doc = ""]
5570 #[doc = "Start a user-driven, interactive resize of the surface."]
5571 #[doc = ""]
5572 #[doc = "This request must be used in response to some sort of user action"]
5573 #[doc = "like a button press, key press, or touch down event. The passed"]
5574 #[doc = "serial is used to determine the type of interactive resize (touch,"]
5575 #[doc = "pointer, etc)."]
5576 #[doc = ""]
5577 #[doc = "The server may ignore resize requests depending on the state of"]
5578 #[doc = "the surface (e.g. fullscreen or maximized)."]
5579 #[doc = ""]
5580 #[doc = "If triggered, the client will receive configure events with the"]
5581 #[doc = "\"resize\" state enum value and the expected sizes. See the \"resize\""]
5582 #[doc = "enum value for more details about what is required. The client"]
5583 #[doc = "must also acknowledge configure events using \"ack_configure\". After"]
5584 #[doc = "the resize is completed, the client will receive another \"configure\""]
5585 #[doc = "event without the resize state."]
5586 #[doc = ""]
5587 #[doc = "If triggered, the surface also will lose the focus of the device"]
5588 #[doc = "(wl_pointer, wl_touch, etc) used for the resize. It is up to the"]
5589 #[doc = "compositor to visually indicate that the resize is taking place,"]
5590 #[doc = "such as updating a pointer cursor, during the resize. There is no"]
5591 #[doc = "guarantee that the device focus will return when the resize is"]
5592 #[doc = "completed."]
5593 #[doc = ""]
5594 #[doc = "The edges parameter specifies how the surface should be resized, and"]
5595 #[doc = "is one of the values of the resize_edge enum. Values not matching"]
5596 #[doc = "a variant of the enum will cause the invalid_resize_edge protocol error."]
5597 #[doc = "The compositor may use this information to update the surface position"]
5598 #[doc = "for example when dragging the top left corner. The compositor may also"]
5599 #[doc = "use this information to adapt its behavior, e.g. choose an appropriate"]
5600 #[doc = "cursor image."]
5601 #[doc = ""]
5602 fn resize(
5603 &self,
5604 client: &mut crate::server::Client,
5605 sender_id: crate::wire::ObjectId,
5606 seat: crate::wire::ObjectId,
5607 serial: u32,
5608 edges: ResizeEdge,
5609 ) -> impl Future<Output = crate::server::Result<()>> + Send;
5610 #[doc = ""]
5611 #[doc = "Set a maximum size for the window."]
5612 #[doc = ""]
5613 #[doc = "The client can specify a maximum size so that the compositor does"]
5614 #[doc = "not try to configure the window beyond this size."]
5615 #[doc = ""]
5616 #[doc = "The width and height arguments are in window geometry coordinates."]
5617 #[doc = "See xdg_surface.set_window_geometry."]
5618 #[doc = ""]
5619 #[doc = "Values set in this way are double-buffered, see wl_surface.commit."]
5620 #[doc = ""]
5621 #[doc = "The compositor can use this information to allow or disallow"]
5622 #[doc = "different states like maximize or fullscreen and draw accurate"]
5623 #[doc = "animations."]
5624 #[doc = ""]
5625 #[doc = "Similarly, a tiling window manager may use this information to"]
5626 #[doc = "place and resize client windows in a more effective way."]
5627 #[doc = ""]
5628 #[doc = "The client should not rely on the compositor to obey the maximum"]
5629 #[doc = "size. The compositor may decide to ignore the values set by the"]
5630 #[doc = "client and request a larger size."]
5631 #[doc = ""]
5632 #[doc = "If never set, or a value of zero in the request, means that the"]
5633 #[doc = "client has no expected maximum size in the given dimension."]
5634 #[doc = "As a result, a client wishing to reset the maximum size"]
5635 #[doc = "to an unspecified state can use zero for width and height in the"]
5636 #[doc = "request."]
5637 #[doc = ""]
5638 #[doc = "Requesting a maximum size to be smaller than the minimum size of"]
5639 #[doc = "a surface is illegal and will result in an invalid_size error."]
5640 #[doc = ""]
5641 #[doc = "The width and height must be greater than or equal to zero. Using"]
5642 #[doc = "strictly negative values for width or height will result in a"]
5643 #[doc = "invalid_size error."]
5644 #[doc = ""]
5645 fn set_max_size(
5646 &self,
5647 client: &mut crate::server::Client,
5648 sender_id: crate::wire::ObjectId,
5649 width: i32,
5650 height: i32,
5651 ) -> impl Future<Output = crate::server::Result<()>> + Send;
5652 #[doc = ""]
5653 #[doc = "Set a minimum size for the window."]
5654 #[doc = ""]
5655 #[doc = "The client can specify a minimum size so that the compositor does"]
5656 #[doc = "not try to configure the window below this size."]
5657 #[doc = ""]
5658 #[doc = "The width and height arguments are in window geometry coordinates."]
5659 #[doc = "See xdg_surface.set_window_geometry."]
5660 #[doc = ""]
5661 #[doc = "Values set in this way are double-buffered, see wl_surface.commit."]
5662 #[doc = ""]
5663 #[doc = "The compositor can use this information to allow or disallow"]
5664 #[doc = "different states like maximize or fullscreen and draw accurate"]
5665 #[doc = "animations."]
5666 #[doc = ""]
5667 #[doc = "Similarly, a tiling window manager may use this information to"]
5668 #[doc = "place and resize client windows in a more effective way."]
5669 #[doc = ""]
5670 #[doc = "The client should not rely on the compositor to obey the minimum"]
5671 #[doc = "size. The compositor may decide to ignore the values set by the"]
5672 #[doc = "client and request a smaller size."]
5673 #[doc = ""]
5674 #[doc = "If never set, or a value of zero in the request, means that the"]
5675 #[doc = "client has no expected minimum size in the given dimension."]
5676 #[doc = "As a result, a client wishing to reset the minimum size"]
5677 #[doc = "to an unspecified state can use zero for width and height in the"]
5678 #[doc = "request."]
5679 #[doc = ""]
5680 #[doc = "Requesting a minimum size to be larger than the maximum size of"]
5681 #[doc = "a surface is illegal and will result in an invalid_size error."]
5682 #[doc = ""]
5683 #[doc = "The width and height must be greater than or equal to zero. Using"]
5684 #[doc = "strictly negative values for width and height will result in a"]
5685 #[doc = "invalid_size error."]
5686 #[doc = ""]
5687 fn set_min_size(
5688 &self,
5689 client: &mut crate::server::Client,
5690 sender_id: crate::wire::ObjectId,
5691 width: i32,
5692 height: i32,
5693 ) -> impl Future<Output = crate::server::Result<()>> + Send;
5694 #[doc = ""]
5695 #[doc = "Maximize the surface."]
5696 #[doc = ""]
5697 #[doc = "After requesting that the surface should be maximized, the compositor"]
5698 #[doc = "will respond by emitting a configure event. Whether this configure"]
5699 #[doc = "actually sets the window maximized is subject to compositor policies."]
5700 #[doc = "The client must then update its content, drawing in the configured"]
5701 #[doc = "state. The client must also acknowledge the configure when committing"]
5702 #[doc = "the new content (see ack_configure)."]
5703 #[doc = ""]
5704 #[doc = "It is up to the compositor to decide how and where to maximize the"]
5705 #[doc = "surface, for example which output and what region of the screen should"]
5706 #[doc = "be used."]
5707 #[doc = ""]
5708 #[doc = "If the surface was already maximized, the compositor will still emit"]
5709 #[doc = "a configure event with the \"maximized\" state."]
5710 #[doc = ""]
5711 #[doc = "If the surface is in a fullscreen state, this request has no direct"]
5712 #[doc = "effect. It may alter the state the surface is returned to when"]
5713 #[doc = "unmaximized unless overridden by the compositor."]
5714 #[doc = ""]
5715 fn set_maximized(
5716 &self,
5717 client: &mut crate::server::Client,
5718 sender_id: crate::wire::ObjectId,
5719 ) -> impl Future<Output = crate::server::Result<()>> + Send;
5720 #[doc = ""]
5721 #[doc = "Unmaximize the surface."]
5722 #[doc = ""]
5723 #[doc = "After requesting that the surface should be unmaximized, the compositor"]
5724 #[doc = "will respond by emitting a configure event. Whether this actually"]
5725 #[doc = "un-maximizes the window is subject to compositor policies."]
5726 #[doc = "If available and applicable, the compositor will include the window"]
5727 #[doc = "geometry dimensions the window had prior to being maximized in the"]
5728 #[doc = "configure event. The client must then update its content, drawing it in"]
5729 #[doc = "the configured state. The client must also acknowledge the configure"]
5730 #[doc = "when committing the new content (see ack_configure)."]
5731 #[doc = ""]
5732 #[doc = "It is up to the compositor to position the surface after it was"]
5733 #[doc = "unmaximized; usually the position the surface had before maximizing, if"]
5734 #[doc = "applicable."]
5735 #[doc = ""]
5736 #[doc = "If the surface was already not maximized, the compositor will still"]
5737 #[doc = "emit a configure event without the \"maximized\" state."]
5738 #[doc = ""]
5739 #[doc = "If the surface is in a fullscreen state, this request has no direct"]
5740 #[doc = "effect. It may alter the state the surface is returned to when"]
5741 #[doc = "unmaximized unless overridden by the compositor."]
5742 #[doc = ""]
5743 fn unset_maximized(
5744 &self,
5745 client: &mut crate::server::Client,
5746 sender_id: crate::wire::ObjectId,
5747 ) -> impl Future<Output = crate::server::Result<()>> + Send;
5748 #[doc = ""]
5749 #[doc = "Make the surface fullscreen."]
5750 #[doc = ""]
5751 #[doc = "After requesting that the surface should be fullscreened, the"]
5752 #[doc = "compositor will respond by emitting a configure event. Whether the"]
5753 #[doc = "client is actually put into a fullscreen state is subject to compositor"]
5754 #[doc = "policies. The client must also acknowledge the configure when"]
5755 #[doc = "committing the new content (see ack_configure)."]
5756 #[doc = ""]
5757 #[doc = "The output passed by the request indicates the client's preference as"]
5758 #[doc = "to which display it should be set fullscreen on. If this value is NULL,"]
5759 #[doc = "it's up to the compositor to choose which display will be used to map"]
5760 #[doc = "this surface."]
5761 #[doc = ""]
5762 #[doc = "If the surface doesn't cover the whole output, the compositor will"]
5763 #[doc = "position the surface in the center of the output and compensate with"]
5764 #[doc = "with border fill covering the rest of the output. The content of the"]
5765 #[doc = "border fill is undefined, but should be assumed to be in some way that"]
5766 #[doc = "attempts to blend into the surrounding area (e.g. solid black)."]
5767 #[doc = ""]
5768 #[doc = "If the fullscreened surface is not opaque, the compositor must make"]
5769 #[doc = "sure that other screen content not part of the same surface tree (made"]
5770 #[doc = "up of subsurfaces, popups or similarly coupled surfaces) are not"]
5771 #[doc = "visible below the fullscreened surface."]
5772 #[doc = ""]
5773 fn set_fullscreen(
5774 &self,
5775 client: &mut crate::server::Client,
5776 sender_id: crate::wire::ObjectId,
5777 output: Option<crate::wire::ObjectId>,
5778 ) -> impl Future<Output = crate::server::Result<()>> + Send;
5779 #[doc = ""]
5780 #[doc = "Make the surface no longer fullscreen."]
5781 #[doc = ""]
5782 #[doc = "After requesting that the surface should be unfullscreened, the"]
5783 #[doc = "compositor will respond by emitting a configure event."]
5784 #[doc = "Whether this actually removes the fullscreen state of the client is"]
5785 #[doc = "subject to compositor policies."]
5786 #[doc = ""]
5787 #[doc = "Making a surface unfullscreen sets states for the surface based on the following:"]
5788 #[doc = "* the state(s) it may have had before becoming fullscreen"]
5789 #[doc = "* any state(s) decided by the compositor"]
5790 #[doc = "* any state(s) requested by the client while the surface was fullscreen"]
5791 #[doc = ""]
5792 #[doc = "The compositor may include the previous window geometry dimensions in"]
5793 #[doc = "the configure event, if applicable."]
5794 #[doc = ""]
5795 #[doc = "The client must also acknowledge the configure when committing the new"]
5796 #[doc = "content (see ack_configure)."]
5797 #[doc = ""]
5798 fn unset_fullscreen(
5799 &self,
5800 client: &mut crate::server::Client,
5801 sender_id: crate::wire::ObjectId,
5802 ) -> impl Future<Output = crate::server::Result<()>> + Send;
5803 #[doc = ""]
5804 #[doc = "Request that the compositor minimize your surface. There is no"]
5805 #[doc = "way to know if the surface is currently minimized, nor is there"]
5806 #[doc = "any way to unset minimization on this surface."]
5807 #[doc = ""]
5808 #[doc = "If you are looking to throttle redrawing when minimized, please"]
5809 #[doc = "instead use the wl_surface.frame event for this, as this will"]
5810 #[doc = "also work with live previews on windows in Alt-Tab, Expose or"]
5811 #[doc = "similar compositor features."]
5812 #[doc = ""]
5813 fn set_minimized(
5814 &self,
5815 client: &mut crate::server::Client,
5816 sender_id: crate::wire::ObjectId,
5817 ) -> impl Future<Output = crate::server::Result<()>> + Send;
5818 #[doc = ""]
5819 #[doc = "This configure event asks the client to resize its toplevel surface or"]
5820 #[doc = "to change its state. The configured state should not be applied"]
5821 #[doc = "immediately. See xdg_surface.configure for details."]
5822 #[doc = ""]
5823 #[doc = "The width and height arguments specify a hint to the window"]
5824 #[doc = "about how its surface should be resized in window geometry"]
5825 #[doc = "coordinates. See set_window_geometry."]
5826 #[doc = ""]
5827 #[doc = "If the width or height arguments are zero, it means the client"]
5828 #[doc = "should decide its own window dimension. This may happen when the"]
5829 #[doc = "compositor needs to configure the state of the surface but doesn't"]
5830 #[doc = "have any information about any previous or expected dimension."]
5831 #[doc = ""]
5832 #[doc = "The states listed in the event specify how the width/height"]
5833 #[doc = "arguments should be interpreted, and possibly how it should be"]
5834 #[doc = "drawn."]
5835 #[doc = ""]
5836 #[doc = "Clients must send an ack_configure in response to this event. See"]
5837 #[doc = "xdg_surface.configure and xdg_surface.ack_configure for details."]
5838 #[doc = ""]
5839 fn configure(
5840 &self,
5841 client: &mut crate::server::Client,
5842 sender_id: crate::wire::ObjectId,
5843 width: i32,
5844 height: i32,
5845 states: Vec<u8>,
5846 ) -> impl Future<Output = crate::server::Result<()>> + Send {
5847 async move {
5848 tracing::debug!(
5849 "-> xdg_toplevel#{}.configure({}, {}, array[{}])",
5850 sender_id,
5851 width,
5852 height,
5853 states.len()
5854 );
5855 let (payload, fds) = crate::wire::PayloadBuilder::new()
5856 .put_int(width)
5857 .put_int(height)
5858 .put_array(states)
5859 .build();
5860 client
5861 .send_message(crate::wire::Message::new(sender_id, 0u16, payload, fds))
5862 .await
5863 .map_err(crate::server::error::Error::IoError)
5864 }
5865 }
5866 #[doc = ""]
5867 #[doc = "The close event is sent by the compositor when the user"]
5868 #[doc = "wants the surface to be closed. This should be equivalent to"]
5869 #[doc = "the user clicking the close button in client-side decorations,"]
5870 #[doc = "if your application has any."]
5871 #[doc = ""]
5872 #[doc = "This is only a request that the user intends to close the"]
5873 #[doc = "window. The client may choose to ignore this request, or show"]
5874 #[doc = "a dialog to ask the user to save their data, etc."]
5875 #[doc = ""]
5876 fn close(
5877 &self,
5878 client: &mut crate::server::Client,
5879 sender_id: crate::wire::ObjectId,
5880 ) -> impl Future<Output = crate::server::Result<()>> + Send {
5881 async move {
5882 tracing::debug!("-> xdg_toplevel#{}.close()", sender_id,);
5883 let (payload, fds) = crate::wire::PayloadBuilder::new().build();
5884 client
5885 .send_message(crate::wire::Message::new(sender_id, 1u16, payload, fds))
5886 .await
5887 .map_err(crate::server::error::Error::IoError)
5888 }
5889 }
5890 #[doc = ""]
5891 #[doc = "The configure_bounds event may be sent prior to a xdg_toplevel.configure"]
5892 #[doc = "event to communicate the bounds a window geometry size is recommended"]
5893 #[doc = "to constrain to."]
5894 #[doc = ""]
5895 #[doc = "The passed width and height are in surface coordinate space. If width"]
5896 #[doc = "and height are 0, it means bounds is unknown and equivalent to as if no"]
5897 #[doc = "configure_bounds event was ever sent for this surface."]
5898 #[doc = ""]
5899 #[doc = "The bounds can for example correspond to the size of a monitor excluding"]
5900 #[doc = "any panels or other shell components, so that a surface isn't created in"]
5901 #[doc = "a way that it cannot fit."]
5902 #[doc = ""]
5903 #[doc = "The bounds may change at any point, and in such a case, a new"]
5904 #[doc = "xdg_toplevel.configure_bounds will be sent, followed by"]
5905 #[doc = "xdg_toplevel.configure and xdg_surface.configure."]
5906 #[doc = ""]
5907 fn configure_bounds(
5908 &self,
5909 client: &mut crate::server::Client,
5910 sender_id: crate::wire::ObjectId,
5911 width: i32,
5912 height: i32,
5913 ) -> impl Future<Output = crate::server::Result<()>> + Send {
5914 async move {
5915 tracing::debug!(
5916 "-> xdg_toplevel#{}.configure_bounds({}, {})",
5917 sender_id,
5918 width,
5919 height
5920 );
5921 let (payload, fds) = crate::wire::PayloadBuilder::new()
5922 .put_int(width)
5923 .put_int(height)
5924 .build();
5925 client
5926 .send_message(crate::wire::Message::new(sender_id, 2u16, payload, fds))
5927 .await
5928 .map_err(crate::server::error::Error::IoError)
5929 }
5930 }
5931 #[doc = ""]
5932 #[doc = "This event advertises the capabilities supported by the compositor. If"]
5933 #[doc = "a capability isn't supported, clients should hide or disable the UI"]
5934 #[doc = "elements that expose this functionality. For instance, if the"]
5935 #[doc = "compositor doesn't advertise support for minimized toplevels, a button"]
5936 #[doc = "triggering the set_minimized request should not be displayed."]
5937 #[doc = ""]
5938 #[doc = "The compositor will ignore requests it doesn't support. For instance,"]
5939 #[doc = "a compositor which doesn't advertise support for minimized will ignore"]
5940 #[doc = "set_minimized requests."]
5941 #[doc = ""]
5942 #[doc = "Compositors must send this event once before the first"]
5943 #[doc = "xdg_surface.configure event. When the capabilities change, compositors"]
5944 #[doc = "must send this event again and then send an xdg_surface.configure"]
5945 #[doc = "event."]
5946 #[doc = ""]
5947 #[doc = "The configured state should not be applied immediately. See"]
5948 #[doc = "xdg_surface.configure for details."]
5949 #[doc = ""]
5950 #[doc = "The capabilities are sent as an array of 32-bit unsigned integers in"]
5951 #[doc = "native endianness."]
5952 #[doc = ""]
5953 fn wm_capabilities(
5954 &self,
5955 client: &mut crate::server::Client,
5956 sender_id: crate::wire::ObjectId,
5957 capabilities: Vec<u8>,
5958 ) -> impl Future<Output = crate::server::Result<()>> + Send {
5959 async move {
5960 tracing::debug!(
5961 "-> xdg_toplevel#{}.wm_capabilities(array[{}])",
5962 sender_id,
5963 capabilities.len()
5964 );
5965 let (payload, fds) = crate::wire::PayloadBuilder::new()
5966 .put_array(capabilities)
5967 .build();
5968 client
5969 .send_message(crate::wire::Message::new(sender_id, 3u16, payload, fds))
5970 .await
5971 .map_err(crate::server::error::Error::IoError)
5972 }
5973 }
5974 }
5975 }
5976 #[doc = ""]
5977 #[doc = "A popup surface is a short-lived, temporary surface. It can be used to"]
5978 #[doc = "implement for example menus, popovers, tooltips and other similar user"]
5979 #[doc = "interface concepts."]
5980 #[doc = ""]
5981 #[doc = "A popup can be made to take an explicit grab. See xdg_popup.grab for"]
5982 #[doc = "details."]
5983 #[doc = ""]
5984 #[doc = "When the popup is dismissed, a popup_done event will be sent out, and at"]
5985 #[doc = "the same time the surface will be unmapped. See the xdg_popup.popup_done"]
5986 #[doc = "event for details."]
5987 #[doc = ""]
5988 #[doc = "Explicitly destroying the xdg_popup object will also dismiss the popup and"]
5989 #[doc = "unmap the surface. Clients that want to dismiss the popup when another"]
5990 #[doc = "surface of their own is clicked should dismiss the popup using the destroy"]
5991 #[doc = "request."]
5992 #[doc = ""]
5993 #[doc = "A newly created xdg_popup will be stacked on top of all previously created"]
5994 #[doc = "xdg_popup surfaces associated with the same xdg_toplevel."]
5995 #[doc = ""]
5996 #[doc = "The parent of an xdg_popup must be mapped (see the xdg_surface"]
5997 #[doc = "description) before the xdg_popup itself."]
5998 #[doc = ""]
5999 #[doc = "The client must call wl_surface.commit on the corresponding wl_surface"]
6000 #[doc = "for the xdg_popup state to take effect."]
6001 #[doc = ""]
6002 #[allow(clippy::too_many_arguments)]
6003 pub mod xdg_popup {
6004 #[allow(unused)]
6005 use futures_util::SinkExt;
6006 #[allow(unused)]
6007 use std::os::fd::AsRawFd;
6008 #[repr(u32)]
6009 #[non_exhaustive]
6010 #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy)]
6011 pub enum Error {
6012 #[doc = "tried to grab after being mapped"]
6013 InvalidGrab = 0u32,
6014 }
6015 impl TryFrom<u32> for Error {
6016 type Error = crate::wire::DecodeError;
6017 fn try_from(v: u32) -> Result<Self, Self::Error> {
6018 match v {
6019 0u32 => Ok(Self::InvalidGrab),
6020 _ => Err(crate::wire::DecodeError::MalformedPayload),
6021 }
6022 }
6023 }
6024 impl std::fmt::Display for Error {
6025 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
6026 (*self as u32).fmt(f)
6027 }
6028 }
6029 #[doc = "Trait to implement the xdg_popup interface. See the module level documentation for more info"]
6030 pub trait XdgPopup: crate::server::Dispatcher {
6031 const INTERFACE: &'static str = "xdg_popup";
6032 const VERSION: u32 = 7u32;
6033 fn handle_request(
6034 &self,
6035 client: &mut crate::server::Client,
6036 sender_id: crate::wire::ObjectId,
6037 message: &mut crate::wire::Message,
6038 ) -> impl Future<Output = crate::server::Result<()>> + Send {
6039 async move {
6040 #[allow(clippy::match_single_binding)]
6041 match message.opcode() {
6042 0u16 => {
6043 tracing::debug!("xdg_popup#{}.destroy()", sender_id,);
6044 let result = self.destroy(client, sender_id).await;
6045 client.remove(sender_id);
6046 result
6047 }
6048 1u16 => {
6049 let seat = message
6050 .object()?
6051 .ok_or(crate::wire::DecodeError::MalformedPayload)?;
6052 let serial = message.uint()?;
6053 tracing::debug!("xdg_popup#{}.grab({}, {})", sender_id, seat, serial);
6054 self.grab(client, sender_id, seat, serial).await
6055 }
6056 2u16 => {
6057 let positioner = message
6058 .object()?
6059 .ok_or(crate::wire::DecodeError::MalformedPayload)?;
6060 let token = message.uint()?;
6061 tracing::debug!(
6062 "xdg_popup#{}.reposition({}, {})",
6063 sender_id,
6064 positioner,
6065 token
6066 );
6067 self.reposition(client, sender_id, positioner, token).await
6068 }
6069 opcode => Err(crate::server::error::Error::UnknownOpcode(opcode)),
6070 }
6071 }
6072 }
6073 #[doc = ""]
6074 #[doc = "This destroys the popup. Explicitly destroying the xdg_popup"]
6075 #[doc = "object will also dismiss the popup, and unmap the surface."]
6076 #[doc = ""]
6077 #[doc = "If this xdg_popup is not the \"topmost\" popup, the"]
6078 #[doc = "xdg_wm_base.not_the_topmost_popup protocol error will be sent."]
6079 #[doc = ""]
6080 fn destroy(
6081 &self,
6082 client: &mut crate::server::Client,
6083 sender_id: crate::wire::ObjectId,
6084 ) -> impl Future<Output = crate::server::Result<()>> + Send;
6085 #[doc = ""]
6086 #[doc = "This request makes the created popup take an explicit grab. An explicit"]
6087 #[doc = "grab will be dismissed when the user dismisses the popup, or when the"]
6088 #[doc = "client destroys the xdg_popup. This can be done by the user clicking"]
6089 #[doc = "outside the surface, using the keyboard, or even locking the screen"]
6090 #[doc = "through closing the lid or a timeout."]
6091 #[doc = ""]
6092 #[doc = "If the compositor denies the grab, the popup will be immediately"]
6093 #[doc = "dismissed."]
6094 #[doc = ""]
6095 #[doc = "This request must be used in response to some sort of user action like a"]
6096 #[doc = "button press, key press, or touch down event. The serial number of the"]
6097 #[doc = "event should be passed as 'serial'."]
6098 #[doc = ""]
6099 #[doc = "The parent of a grabbing popup must either be an xdg_toplevel surface or"]
6100 #[doc = "another xdg_popup with an explicit grab. If the parent is another"]
6101 #[doc = "xdg_popup it means that the popups are nested, with this popup now being"]
6102 #[doc = "the topmost popup."]
6103 #[doc = ""]
6104 #[doc = "Nested popups must be destroyed in the reverse order they were created"]
6105 #[doc = "in, e.g. the only popup you are allowed to destroy at all times is the"]
6106 #[doc = "topmost one."]
6107 #[doc = ""]
6108 #[doc = "When compositors choose to dismiss a popup, they may dismiss every"]
6109 #[doc = "nested grabbing popup as well. When a compositor dismisses popups, it"]
6110 #[doc = "will follow the same dismissing order as required from the client."]
6111 #[doc = ""]
6112 #[doc = "If the topmost grabbing popup is destroyed, the grab will be returned to"]
6113 #[doc = "the parent of the popup, if that parent previously had an explicit grab."]
6114 #[doc = ""]
6115 #[doc = "If the parent is a grabbing popup which has already been dismissed, this"]
6116 #[doc = "popup will be immediately dismissed. If the parent is a popup that did"]
6117 #[doc = "not take an explicit grab, an error will be raised."]
6118 #[doc = ""]
6119 #[doc = "During a popup grab, the client owning the grab will receive pointer"]
6120 #[doc = "and touch events for all their surfaces as normal (similar to an"]
6121 #[doc = "\"owner-events\" grab in X11 parlance), while the top most grabbing popup"]
6122 #[doc = "will always have keyboard focus."]
6123 #[doc = ""]
6124 fn grab(
6125 &self,
6126 client: &mut crate::server::Client,
6127 sender_id: crate::wire::ObjectId,
6128 seat: crate::wire::ObjectId,
6129 serial: u32,
6130 ) -> impl Future<Output = crate::server::Result<()>> + Send;
6131 #[doc = ""]
6132 #[doc = "Reposition an already-mapped popup. The popup will be placed given the"]
6133 #[doc = "details in the passed xdg_positioner object, and a"]
6134 #[doc = "xdg_popup.repositioned followed by xdg_popup.configure and"]
6135 #[doc = "xdg_surface.configure will be emitted in response. Any parameters set"]
6136 #[doc = "by the previous positioner will be discarded."]
6137 #[doc = ""]
6138 #[doc = "The passed token will be sent in the corresponding"]
6139 #[doc = "xdg_popup.repositioned event. The new popup position will not take"]
6140 #[doc = "effect until the corresponding configure event is acknowledged by the"]
6141 #[doc = "client. See xdg_popup.repositioned for details. The token itself is"]
6142 #[doc = "opaque, and has no other special meaning."]
6143 #[doc = ""]
6144 #[doc = "If multiple reposition requests are sent, the compositor may skip all"]
6145 #[doc = "but the last one."]
6146 #[doc = ""]
6147 #[doc = "If the popup is repositioned in response to a configure event for its"]
6148 #[doc = "parent, the client should send an xdg_positioner.set_parent_configure"]
6149 #[doc = "and possibly an xdg_positioner.set_parent_size request to allow the"]
6150 #[doc = "compositor to properly constrain the popup."]
6151 #[doc = ""]
6152 #[doc = "If the popup is repositioned together with a parent that is being"]
6153 #[doc = "resized, but not in response to a configure event, the client should"]
6154 #[doc = "send an xdg_positioner.set_parent_size request."]
6155 #[doc = ""]
6156 fn reposition(
6157 &self,
6158 client: &mut crate::server::Client,
6159 sender_id: crate::wire::ObjectId,
6160 positioner: crate::wire::ObjectId,
6161 token: u32,
6162 ) -> impl Future<Output = crate::server::Result<()>> + Send;
6163 #[doc = ""]
6164 #[doc = "This event asks the popup surface to configure itself given the"]
6165 #[doc = "configuration. The configured state should not be applied immediately."]
6166 #[doc = "See xdg_surface.configure for details."]
6167 #[doc = ""]
6168 #[doc = "The x and y arguments represent the position the popup was placed at"]
6169 #[doc = "given the xdg_positioner rule, relative to the upper left corner of the"]
6170 #[doc = "window geometry of the parent surface."]
6171 #[doc = ""]
6172 #[doc = "For version 2 or older, the configure event for an xdg_popup is only"]
6173 #[doc = "ever sent once for the initial configuration. Starting with version 3,"]
6174 #[doc = "it may be sent again if the popup is setup with an xdg_positioner with"]
6175 #[doc = "set_reactive requested, or in response to xdg_popup.reposition requests."]
6176 #[doc = ""]
6177 fn configure(
6178 &self,
6179 client: &mut crate::server::Client,
6180 sender_id: crate::wire::ObjectId,
6181 x: i32,
6182 y: i32,
6183 width: i32,
6184 height: i32,
6185 ) -> impl Future<Output = crate::server::Result<()>> + Send {
6186 async move {
6187 tracing::debug!(
6188 "-> xdg_popup#{}.configure({}, {}, {}, {})",
6189 sender_id,
6190 x,
6191 y,
6192 width,
6193 height
6194 );
6195 let (payload, fds) = crate::wire::PayloadBuilder::new()
6196 .put_int(x)
6197 .put_int(y)
6198 .put_int(width)
6199 .put_int(height)
6200 .build();
6201 client
6202 .send_message(crate::wire::Message::new(sender_id, 0u16, payload, fds))
6203 .await
6204 .map_err(crate::server::error::Error::IoError)
6205 }
6206 }
6207 #[doc = ""]
6208 #[doc = "The popup_done event is sent out when a popup is dismissed by the"]
6209 #[doc = "compositor. The client should destroy the xdg_popup object at this"]
6210 #[doc = "point."]
6211 #[doc = ""]
6212 fn popup_done(
6213 &self,
6214 client: &mut crate::server::Client,
6215 sender_id: crate::wire::ObjectId,
6216 ) -> impl Future<Output = crate::server::Result<()>> + Send {
6217 async move {
6218 tracing::debug!("-> xdg_popup#{}.popup_done()", sender_id,);
6219 let (payload, fds) = crate::wire::PayloadBuilder::new().build();
6220 client
6221 .send_message(crate::wire::Message::new(sender_id, 1u16, payload, fds))
6222 .await
6223 .map_err(crate::server::error::Error::IoError)
6224 }
6225 }
6226 #[doc = ""]
6227 #[doc = "The repositioned event is sent as part of a popup configuration"]
6228 #[doc = "sequence, together with xdg_popup.configure and lastly"]
6229 #[doc = "xdg_surface.configure to notify the completion of a reposition request."]
6230 #[doc = ""]
6231 #[doc = "The repositioned event is to notify about the completion of a"]
6232 #[doc = "xdg_popup.reposition request. The token argument is the token passed"]
6233 #[doc = "in the xdg_popup.reposition request."]
6234 #[doc = ""]
6235 #[doc = "Immediately after this event is emitted, xdg_popup.configure and"]
6236 #[doc = "xdg_surface.configure will be sent with the updated size and position,"]
6237 #[doc = "as well as a new configure serial."]
6238 #[doc = ""]
6239 #[doc = "The client should optionally update the content of the popup, but must"]
6240 #[doc = "acknowledge the new popup configuration for the new position to take"]
6241 #[doc = "effect. See xdg_surface.ack_configure for details."]
6242 #[doc = ""]
6243 fn repositioned(
6244 &self,
6245 client: &mut crate::server::Client,
6246 sender_id: crate::wire::ObjectId,
6247 token: u32,
6248 ) -> impl Future<Output = crate::server::Result<()>> + Send {
6249 async move {
6250 tracing::debug!("-> xdg_popup#{}.repositioned({})", sender_id, token);
6251 let (payload, fds) = crate::wire::PayloadBuilder::new().put_uint(token).build();
6252 client
6253 .send_message(crate::wire::Message::new(sender_id, 2u16, payload, fds))
6254 .await
6255 .map_err(crate::server::error::Error::IoError)
6256 }
6257 }
6258 }
6259 }
6260}