poll_integration/common/protocols/tablet_v2/zwp_tablet_pad_group_v2.rs
1//! a set of buttons, rings and strips
2//!
3//! A pad group describes a distinct (sub)set of buttons, rings and strips
4//! present in the tablet. The criteria of this grouping is usually positional,
5//! eg. if a tablet has buttons on the left and right side, 2 groups will be
6//! presented. The physical arrangement of groups is undisclosed and may
7//! change on the fly.
8//!
9//! Pad groups will announce their features during pad initialization. Between
10//! the corresponding wp_tablet_pad.group event and wp_tablet_pad_group.done, the
11//! pad group will announce the buttons, rings and strips contained in it,
12//! plus the number of supported modes.
13//!
14//! Modes are a mechanism to allow multiple groups of actions for every element
15//! in the pad group. The number of groups and available modes in each is
16//! persistent across device plugs. The current mode is user-switchable, it
17//! will be announced through the wp_tablet_pad_group.mode_switch event both
18//! whenever it is switched, and after wp_tablet_pad.enter.
19//!
20//! The current mode logically applies to all elements in the pad group,
21//! although it is at clients' discretion whether to actually perform different
22//! actions, and/or issue the respective .set_feedback requests to notify the
23//! compositor. See the wp_tablet_pad_group.mode_switch event for more details.
24
25use {super::super::all_types::*, ::wl_client::builder::prelude::*};
26
27static INTERFACE: wl_interface = wl_interface {
28 name: c"zwp_tablet_pad_group_v2".as_ptr(),
29 version: 1,
30 method_count: 1,
31 methods: {
32 static MESSAGES: [wl_message; 1] = [wl_message {
33 name: c"destroy".as_ptr(),
34 signature: c"".as_ptr(),
35 types: {
36 static TYPES: [Option<&'static wl_interface>; 0] = [];
37 TYPES.as_ptr().cast()
38 },
39 }];
40 MESSAGES.as_ptr()
41 },
42 event_count: 6,
43 events: {
44 static MESSAGES: [wl_message; 6] = [
45 wl_message {
46 name: c"buttons".as_ptr(),
47 signature: c"a".as_ptr(),
48 types: {
49 static TYPES: [Option<&'static wl_interface>; 1] = [None];
50 TYPES.as_ptr().cast()
51 },
52 },
53 wl_message {
54 name: c"ring".as_ptr(),
55 signature: c"n".as_ptr(),
56 types: {
57 static TYPES: [Option<&'static wl_interface>; 1] =
58 [Some(ZwpTabletPadRingV2::WL_INTERFACE)];
59 TYPES.as_ptr().cast()
60 },
61 },
62 wl_message {
63 name: c"strip".as_ptr(),
64 signature: c"n".as_ptr(),
65 types: {
66 static TYPES: [Option<&'static wl_interface>; 1] =
67 [Some(ZwpTabletPadStripV2::WL_INTERFACE)];
68 TYPES.as_ptr().cast()
69 },
70 },
71 wl_message {
72 name: c"modes".as_ptr(),
73 signature: c"u".as_ptr(),
74 types: {
75 static TYPES: [Option<&'static wl_interface>; 1] = [None];
76 TYPES.as_ptr().cast()
77 },
78 },
79 wl_message {
80 name: c"done".as_ptr(),
81 signature: c"".as_ptr(),
82 types: {
83 static TYPES: [Option<&'static wl_interface>; 0] = [];
84 TYPES.as_ptr().cast()
85 },
86 },
87 wl_message {
88 name: c"mode_switch".as_ptr(),
89 signature: c"uuu".as_ptr(),
90 types: {
91 static TYPES: [Option<&'static wl_interface>; 3] = [None, None, None];
92 TYPES.as_ptr().cast()
93 },
94 },
95 ];
96 MESSAGES.as_ptr()
97 },
98};
99
100/// An owned zwp_tablet_pad_group_v2 proxy.
101///
102/// See the documentation of [the module][self] for the interface description.
103#[derive(Clone, Eq, PartialEq)]
104#[repr(transparent)]
105pub struct ZwpTabletPadGroupV2 {
106 /// This proxy has the interface INTERFACE.
107 proxy: UntypedOwnedProxy,
108}
109
110/// A borrowed zwp_tablet_pad_group_v2 proxy.
111///
112/// See the documentation of [the module][self] for the interface description.
113#[derive(Eq, PartialEq)]
114#[repr(transparent)]
115pub struct ZwpTabletPadGroupV2Ref {
116 /// This proxy has the interface INTERFACE.
117 proxy: UntypedBorrowedProxy,
118}
119
120// SAFETY: ZwpTabletPadGroupV2 is a transparent wrapper around UntypedOwnedProxy
121unsafe impl UntypedOwnedProxyWrapper for ZwpTabletPadGroupV2 {}
122
123// SAFETY: - INTERFACE is a valid wl_interface
124// - The only invariant is that self.proxy has a compatible interface
125unsafe impl OwnedProxy for ZwpTabletPadGroupV2 {
126 const INTERFACE: &'static str = "zwp_tablet_pad_group_v2";
127 const WL_INTERFACE: &'static wl_interface = &INTERFACE;
128 const NO_OP_EVENT_HANDLER: Self::NoOpEventHandler =
129 private::EventHandler(private::NoOpEventHandler);
130 const MAX_VERSION: u32 = 1;
131
132 type Borrowed = ZwpTabletPadGroupV2Ref;
133 type Api = private::ProxyApi;
134 type NoOpEventHandler = private::EventHandler<private::NoOpEventHandler>;
135}
136
137// SAFETY: ZwpTabletPadGroupV2Ref is a transparent wrapper around UntypedBorrowedProxy
138unsafe impl UntypedBorrowedProxyWrapper for ZwpTabletPadGroupV2Ref {}
139
140// SAFETY: - The only invariant is that self.proxy has a compatible interface
141unsafe impl BorrowedProxy for ZwpTabletPadGroupV2Ref {
142 type Owned = ZwpTabletPadGroupV2;
143}
144
145impl Deref for ZwpTabletPadGroupV2 {
146 type Target = ZwpTabletPadGroupV2Ref;
147
148 fn deref(&self) -> &Self::Target {
149 proxy::low_level::deref(self)
150 }
151}
152
153mod private {
154 pub struct ProxyApi;
155
156 #[allow(dead_code)]
157 pub struct EventHandler<H>(pub(super) H);
158
159 #[allow(dead_code)]
160 pub struct NoOpEventHandler;
161}
162
163impl Debug for ZwpTabletPadGroupV2 {
164 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
165 write!(f, "zwp_tablet_pad_group_v2#{}", self.proxy.id())
166 }
167}
168
169impl Debug for ZwpTabletPadGroupV2Ref {
170 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
171 write!(f, "zwp_tablet_pad_group_v2#{}", self.proxy.id())
172 }
173}
174
175impl PartialEq<ZwpTabletPadGroupV2Ref> for ZwpTabletPadGroupV2 {
176 fn eq(&self, other: &ZwpTabletPadGroupV2Ref) -> bool {
177 self.proxy == other.proxy
178 }
179}
180
181impl PartialEq<ZwpTabletPadGroupV2> for ZwpTabletPadGroupV2Ref {
182 fn eq(&self, other: &ZwpTabletPadGroupV2) -> bool {
183 self.proxy == other.proxy
184 }
185}
186
187#[allow(dead_code)]
188impl ZwpTabletPadGroupV2 {
189 /// Since when the destroy request is available.
190 #[allow(dead_code)]
191 pub const REQ__DESTROY__SINCE: u32 = 1;
192
193 /// destroy the pad object
194 ///
195 /// Destroy the wp_tablet_pad_group object. Objects created from this object
196 /// are unaffected and should be destroyed separately.
197 #[inline]
198 pub fn destroy(&self) {
199 let mut args = [];
200 // SAFETY: - self.proxy has the interface INTERFACE
201 // - 0 < INTERFACE.method_count = 1
202 // - the request signature is ``
203 unsafe {
204 self.proxy.send_destructor(0, &mut args);
205 }
206 }
207}
208
209impl ZwpTabletPadGroupV2 {
210 /// Since when the buttons event is available.
211 #[allow(dead_code)]
212 pub const EVT__BUTTONS__SINCE: u32 = 1;
213
214 /// Since when the ring event is available.
215 #[allow(dead_code)]
216 pub const EVT__RING__SINCE: u32 = 1;
217
218 /// Since when the strip event is available.
219 #[allow(dead_code)]
220 pub const EVT__STRIP__SINCE: u32 = 1;
221
222 /// Since when the modes event is available.
223 #[allow(dead_code)]
224 pub const EVT__MODES__SINCE: u32 = 1;
225
226 /// Since when the done event is available.
227 #[allow(dead_code)]
228 pub const EVT__DONE__SINCE: u32 = 1;
229
230 /// Since when the mode_switch event is available.
231 #[allow(dead_code)]
232 pub const EVT__MODE_SWITCH__SINCE: u32 = 1;
233}
234
235/// An event handler for [ZwpTabletPadGroupV2] proxies.
236#[allow(dead_code)]
237pub trait ZwpTabletPadGroupV2EventHandler {
238 /// buttons announced
239 ///
240 /// Sent on wp_tablet_pad_group initialization to announce the available
241 /// buttons in the group. Button indices start at 0, a button may only be
242 /// in one group at a time.
243 ///
244 /// This event is first sent in the initial burst of events before the
245 /// wp_tablet_pad_group.done event.
246 ///
247 /// Some buttons are reserved by the compositor. These buttons may not be
248 /// assigned to any wp_tablet_pad_group. Compositors may broadcast this
249 /// event in the case of changes to the mapping of these reserved buttons.
250 /// If the compositor happens to reserve all buttons in a group, this event
251 /// will be sent with an empty array.
252 ///
253 /// # Arguments
254 ///
255 /// - `buttons`: buttons in this group
256 #[inline]
257 fn buttons(&self, _slf: &ZwpTabletPadGroupV2Ref, buttons: &[u8]) {
258 let _ = buttons;
259 }
260
261 /// ring announced
262 ///
263 /// Sent on wp_tablet_pad_group initialization to announce available rings.
264 /// One event is sent for each ring available on this pad group.
265 ///
266 /// This event is sent in the initial burst of events before the
267 /// wp_tablet_pad_group.done event.
268 ///
269 /// # Arguments
270 ///
271 /// - `ring`:
272 #[inline]
273 fn ring(&self, _slf: &ZwpTabletPadGroupV2Ref, ring: ZwpTabletPadRingV2) {
274 let _ = ring;
275 }
276
277 /// strip announced
278 ///
279 /// Sent on wp_tablet_pad initialization to announce available strips.
280 /// One event is sent for each strip available on this pad group.
281 ///
282 /// This event is sent in the initial burst of events before the
283 /// wp_tablet_pad_group.done event.
284 ///
285 /// # Arguments
286 ///
287 /// - `strip`:
288 #[inline]
289 fn strip(&self, _slf: &ZwpTabletPadGroupV2Ref, strip: ZwpTabletPadStripV2) {
290 let _ = strip;
291 }
292
293 /// mode-switch ability announced
294 ///
295 /// Sent on wp_tablet_pad_group initialization to announce that the pad
296 /// group may switch between modes. A client may use a mode to store a
297 /// specific configuration for buttons, rings and strips and use the
298 /// wl_tablet_pad_group.mode_switch event to toggle between these
299 /// configurations. Mode indices start at 0.
300 ///
301 /// Switching modes is compositor-dependent. See the
302 /// wp_tablet_pad_group.mode_switch event for more details.
303 ///
304 /// This event is sent in the initial burst of events before the
305 /// wp_tablet_pad_group.done event. This event is only sent when more than
306 /// more than one mode is available.
307 ///
308 /// # Arguments
309 ///
310 /// - `modes`: the number of modes
311 #[inline]
312 fn modes(&self, _slf: &ZwpTabletPadGroupV2Ref, modes: u32) {
313 let _ = modes;
314 }
315
316 /// tablet group description events sequence complete
317 ///
318 /// This event is sent immediately to signal the end of the initial
319 /// burst of descriptive events. A client may consider the static
320 /// description of the tablet to be complete and finalize initialization
321 /// of the tablet group.
322 #[inline]
323 fn done(&self, _slf: &ZwpTabletPadGroupV2Ref) {}
324
325 /// mode switch event
326 ///
327 /// Notification that the mode was switched.
328 ///
329 /// A mode applies to all buttons, rings and strips in a group
330 /// simultaneously, but a client is not required to assign different actions
331 /// for each mode. For example, a client may have mode-specific button
332 /// mappings but map the ring to vertical scrolling in all modes. Mode
333 /// indices start at 0.
334 ///
335 /// Switching modes is compositor-dependent. The compositor may provide
336 /// visual cues to the user about the mode, e.g. by toggling LEDs on
337 /// the tablet device. Mode-switching may be software-controlled or
338 /// controlled by one or more physical buttons. For example, on a Wacom
339 /// Intuos Pro, the button inside the ring may be assigned to switch
340 /// between modes.
341 ///
342 /// The compositor will also send this event after wp_tablet_pad.enter on
343 /// each group in order to notify of the current mode. Groups that only
344 /// feature one mode will use mode=0 when emitting this event.
345 ///
346 /// If a button action in the new mode differs from the action in the
347 /// previous mode, the client should immediately issue a
348 /// wp_tablet_pad.set_feedback request for each changed button.
349 ///
350 /// If a ring or strip action in the new mode differs from the action
351 /// in the previous mode, the client should immediately issue a
352 /// wp_tablet_ring.set_feedback or wp_tablet_strip.set_feedback request
353 /// for each changed ring or strip.
354 ///
355 /// # Arguments
356 ///
357 /// - `time`: the time of the event with millisecond granularity
358 /// - `serial`:
359 /// - `mode`: the new mode of the pad
360 #[inline]
361 fn mode_switch(&self, _slf: &ZwpTabletPadGroupV2Ref, time: u32, serial: u32, mode: u32) {
362 let _ = time;
363 let _ = serial;
364 let _ = mode;
365 }
366}
367
368impl ZwpTabletPadGroupV2EventHandler for private::NoOpEventHandler {}
369
370// SAFETY: INTERFACE is a valid wl_interface
371unsafe impl<H> EventHandler for private::EventHandler<H>
372where
373 H: ZwpTabletPadGroupV2EventHandler,
374{
375 const WL_INTERFACE: &'static wl_interface = &INTERFACE;
376
377 #[allow(unused_variables)]
378 unsafe fn handle_event(
379 &self,
380 queue: &Queue,
381 slf: &UntypedBorrowedProxy,
382 opcode: u32,
383 args: *mut wl_argument,
384 ) {
385 // SAFETY: This function required that slf has the interface INTERFACE
386 let slf = unsafe { proxy::low_level::from_untyped_borrowed::<ZwpTabletPadGroupV2Ref>(slf) };
387 match opcode {
388 0 => {
389 // SAFETY: INTERFACE requires that there are 1 arguments
390 let args = unsafe { &*args.cast::<[wl_argument; 1]>() };
391 // SAFETY: - INTERFACE requires that args[0] contains an array
392 let arg0 = unsafe {
393 let a = &*args[0].a;
394 std::slice::from_raw_parts(a.data.cast(), a.size)
395 };
396 self.0.buttons(slf, arg0);
397 }
398 1 => {
399 // SAFETY: INTERFACE requires that there are 1 arguments
400 let args = unsafe { &*args.cast::<[wl_argument; 1]>() };
401 // SAFETY: - INTERFACE requires that args[0] contains an object
402 // - ownership is transferred to this function
403 // - INTERFACE requires that the object has the interface ZwpTabletPadRingV2::WL_INTERFACE
404 let arg0 = unsafe {
405 UntypedOwnedProxy::from_plain_wl_proxy(
406 queue,
407 NonNull::new_unchecked(args[0].o.cast()),
408 ZwpTabletPadRingV2::WL_INTERFACE,
409 )
410 };
411 // SAFETY: - INTERFACE requires that the object has the interface ZwpTabletPadRingV2::WL_INTERFACE
412 let arg0 =
413 unsafe { proxy::low_level::from_untyped_owned::<ZwpTabletPadRingV2>(arg0) };
414 self.0.ring(slf, arg0);
415 }
416 2 => {
417 // SAFETY: INTERFACE requires that there are 1 arguments
418 let args = unsafe { &*args.cast::<[wl_argument; 1]>() };
419 // SAFETY: - INTERFACE requires that args[0] contains an object
420 // - ownership is transferred to this function
421 // - INTERFACE requires that the object has the interface ZwpTabletPadStripV2::WL_INTERFACE
422 let arg0 = unsafe {
423 UntypedOwnedProxy::from_plain_wl_proxy(
424 queue,
425 NonNull::new_unchecked(args[0].o.cast()),
426 ZwpTabletPadStripV2::WL_INTERFACE,
427 )
428 };
429 // SAFETY: - INTERFACE requires that the object has the interface ZwpTabletPadStripV2::WL_INTERFACE
430 let arg0 =
431 unsafe { proxy::low_level::from_untyped_owned::<ZwpTabletPadStripV2>(arg0) };
432 self.0.strip(slf, arg0);
433 }
434 3 => {
435 // SAFETY: INTERFACE requires that there are 1 arguments
436 let args = unsafe { &*args.cast::<[wl_argument; 1]>() };
437 // SAFETY: - INTERFACE requires that args[0] contains a uint
438 let arg0 = unsafe { args[0].u };
439 self.0.modes(slf, arg0);
440 }
441 4 => {
442 self.0.done(slf);
443 }
444 5 => {
445 // SAFETY: INTERFACE requires that there are 3 arguments
446 let args = unsafe { &*args.cast::<[wl_argument; 3]>() };
447 // SAFETY: - INTERFACE requires that args[0] contains a uint
448 let arg0 = unsafe { args[0].u };
449 // SAFETY: - INTERFACE requires that args[1] contains a uint
450 let arg1 = unsafe { args[1].u };
451 // SAFETY: - INTERFACE requires that args[2] contains a uint
452 let arg2 = unsafe { args[2].u };
453 self.0.mode_switch(slf, arg0, arg1, arg2);
454 }
455 _ => {
456 invalid_opcode("zwp_tablet_pad_group_v2", opcode);
457 }
458 }
459 }
460}
461
462impl<H> CreateEventHandler<H> for private::ProxyApi
463where
464 H: ZwpTabletPadGroupV2EventHandler,
465{
466 type EventHandler = private::EventHandler<H>;
467
468 #[inline]
469 fn create_event_handler(handler: H) -> Self::EventHandler {
470 private::EventHandler(handler)
471 }
472}
473
474/// Functional event handlers.
475pub mod event_handlers {
476 use super::*;
477
478 /// Event handler for buttons events.
479 pub struct Buttons<F>(F);
480 impl<F> ZwpTabletPadGroupV2EventHandler for Buttons<F>
481 where
482 F: Fn(&ZwpTabletPadGroupV2Ref, &[u8]),
483 {
484 #[inline]
485 fn buttons(&self, _slf: &ZwpTabletPadGroupV2Ref, buttons: &[u8]) {
486 self.0(_slf, buttons)
487 }
488 }
489
490 /// Event handler for ring events.
491 pub struct Ring<F>(F);
492 impl<F> ZwpTabletPadGroupV2EventHandler for Ring<F>
493 where
494 F: Fn(&ZwpTabletPadGroupV2Ref, ZwpTabletPadRingV2),
495 {
496 #[inline]
497 fn ring(&self, _slf: &ZwpTabletPadGroupV2Ref, ring: ZwpTabletPadRingV2) {
498 self.0(_slf, ring)
499 }
500 }
501
502 /// Event handler for strip events.
503 pub struct Strip<F>(F);
504 impl<F> ZwpTabletPadGroupV2EventHandler for Strip<F>
505 where
506 F: Fn(&ZwpTabletPadGroupV2Ref, ZwpTabletPadStripV2),
507 {
508 #[inline]
509 fn strip(&self, _slf: &ZwpTabletPadGroupV2Ref, strip: ZwpTabletPadStripV2) {
510 self.0(_slf, strip)
511 }
512 }
513
514 /// Event handler for modes events.
515 pub struct Modes<F>(F);
516 impl<F> ZwpTabletPadGroupV2EventHandler for Modes<F>
517 where
518 F: Fn(&ZwpTabletPadGroupV2Ref, u32),
519 {
520 #[inline]
521 fn modes(&self, _slf: &ZwpTabletPadGroupV2Ref, modes: u32) {
522 self.0(_slf, modes)
523 }
524 }
525
526 /// Event handler for done events.
527 pub struct Done<F>(F);
528 impl<F> ZwpTabletPadGroupV2EventHandler for Done<F>
529 where
530 F: Fn(&ZwpTabletPadGroupV2Ref),
531 {
532 #[inline]
533 fn done(&self, _slf: &ZwpTabletPadGroupV2Ref) {
534 self.0(_slf)
535 }
536 }
537
538 /// Event handler for mode_switch events.
539 pub struct ModeSwitch<F>(F);
540 impl<F> ZwpTabletPadGroupV2EventHandler for ModeSwitch<F>
541 where
542 F: Fn(&ZwpTabletPadGroupV2Ref, u32, u32, u32),
543 {
544 #[inline]
545 fn mode_switch(&self, _slf: &ZwpTabletPadGroupV2Ref, time: u32, serial: u32, mode: u32) {
546 self.0(_slf, time, serial, mode)
547 }
548 }
549
550 impl ZwpTabletPadGroupV2 {
551 /// Creates an event handler for buttons events.
552 ///
553 /// The event handler ignores all other events.
554 #[allow(dead_code)]
555 pub fn on_buttons<F>(f: F) -> Buttons<F>
556 where
557 F: Fn(&ZwpTabletPadGroupV2Ref, &[u8]),
558 {
559 Buttons(f)
560 }
561
562 /// Creates an event handler for ring events.
563 ///
564 /// The event handler ignores all other events.
565 #[allow(dead_code)]
566 pub fn on_ring<F>(f: F) -> Ring<F>
567 where
568 F: Fn(&ZwpTabletPadGroupV2Ref, ZwpTabletPadRingV2),
569 {
570 Ring(f)
571 }
572
573 /// Creates an event handler for strip events.
574 ///
575 /// The event handler ignores all other events.
576 #[allow(dead_code)]
577 pub fn on_strip<F>(f: F) -> Strip<F>
578 where
579 F: Fn(&ZwpTabletPadGroupV2Ref, ZwpTabletPadStripV2),
580 {
581 Strip(f)
582 }
583
584 /// Creates an event handler for modes events.
585 ///
586 /// The event handler ignores all other events.
587 #[allow(dead_code)]
588 pub fn on_modes<F>(f: F) -> Modes<F>
589 where
590 F: Fn(&ZwpTabletPadGroupV2Ref, u32),
591 {
592 Modes(f)
593 }
594
595 /// Creates an event handler for done events.
596 ///
597 /// The event handler ignores all other events.
598 #[allow(dead_code)]
599 pub fn on_done<F>(f: F) -> Done<F>
600 where
601 F: Fn(&ZwpTabletPadGroupV2Ref),
602 {
603 Done(f)
604 }
605
606 /// Creates an event handler for mode_switch events.
607 ///
608 /// The event handler ignores all other events.
609 #[allow(dead_code)]
610 pub fn on_mode_switch<F>(f: F) -> ModeSwitch<F>
611 where
612 F: Fn(&ZwpTabletPadGroupV2Ref, u32, u32, u32),
613 {
614 ModeSwitch(f)
615 }
616 }
617}