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}