simple_window/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        data: *mut u8,
382        slf: &UntypedBorrowedProxy,
383        opcode: u32,
384        args: *mut wl_argument,
385    ) {
386        // SAFETY: This function requires that slf has the interface INTERFACE
387        let slf = unsafe { proxy::low_level::from_untyped_borrowed::<ZwpTabletPadGroupV2Ref>(slf) };
388        match opcode {
389            0 => {
390                // SAFETY: INTERFACE requires that there are 1 arguments
391                let args = unsafe { &*args.cast::<[wl_argument; 1]>() };
392                // SAFETY: - INTERFACE requires that args[0] contains an array
393                let arg0 = unsafe {
394                    let a = &*args[0].a;
395                    std::slice::from_raw_parts(a.data.cast(), a.size)
396                };
397                self.0.buttons(slf, arg0);
398            }
399            1 => {
400                // SAFETY: INTERFACE requires that there are 1 arguments
401                let args = unsafe { &*args.cast::<[wl_argument; 1]>() };
402                // SAFETY: - INTERFACE requires that args[0] contains an object
403                //         - ownership is transferred to this function
404                //         - INTERFACE requires that the object has the interface ZwpTabletPadRingV2::WL_INTERFACE
405                let arg0 = unsafe {
406                    UntypedOwnedProxy::from_plain_wl_proxy(
407                        queue,
408                        NonNull::new_unchecked(args[0].o.cast()),
409                        ZwpTabletPadRingV2::WL_INTERFACE,
410                    )
411                };
412                // SAFETY: - INTERFACE requires that the object has the interface ZwpTabletPadRingV2::WL_INTERFACE
413                let arg0 =
414                    unsafe { proxy::low_level::from_untyped_owned::<ZwpTabletPadRingV2>(arg0) };
415                self.0.ring(slf, arg0);
416            }
417            2 => {
418                // SAFETY: INTERFACE requires that there are 1 arguments
419                let args = unsafe { &*args.cast::<[wl_argument; 1]>() };
420                // SAFETY: - INTERFACE requires that args[0] contains an object
421                //         - ownership is transferred to this function
422                //         - INTERFACE requires that the object has the interface ZwpTabletPadStripV2::WL_INTERFACE
423                let arg0 = unsafe {
424                    UntypedOwnedProxy::from_plain_wl_proxy(
425                        queue,
426                        NonNull::new_unchecked(args[0].o.cast()),
427                        ZwpTabletPadStripV2::WL_INTERFACE,
428                    )
429                };
430                // SAFETY: - INTERFACE requires that the object has the interface ZwpTabletPadStripV2::WL_INTERFACE
431                let arg0 =
432                    unsafe { proxy::low_level::from_untyped_owned::<ZwpTabletPadStripV2>(arg0) };
433                self.0.strip(slf, arg0);
434            }
435            3 => {
436                // SAFETY: INTERFACE requires that there are 1 arguments
437                let args = unsafe { &*args.cast::<[wl_argument; 1]>() };
438                // SAFETY: - INTERFACE requires that args[0] contains a uint
439                let arg0 = unsafe { args[0].u };
440                self.0.modes(slf, arg0);
441            }
442            4 => {
443                self.0.done(slf);
444            }
445            5 => {
446                // SAFETY: INTERFACE requires that there are 3 arguments
447                let args = unsafe { &*args.cast::<[wl_argument; 3]>() };
448                // SAFETY: - INTERFACE requires that args[0] contains a uint
449                let arg0 = unsafe { args[0].u };
450                // SAFETY: - INTERFACE requires that args[1] contains a uint
451                let arg1 = unsafe { args[1].u };
452                // SAFETY: - INTERFACE requires that args[2] contains a uint
453                let arg2 = unsafe { args[2].u };
454                self.0.mode_switch(slf, arg0, arg1, arg2);
455            }
456            _ => {
457                invalid_opcode("zwp_tablet_pad_group_v2", opcode);
458            }
459        }
460    }
461}
462
463impl<H> CreateEventHandler<H> for private::ProxyApi
464where
465    H: ZwpTabletPadGroupV2EventHandler,
466{
467    type EventHandler = private::EventHandler<H>;
468
469    #[inline]
470    fn create_event_handler(handler: H) -> Self::EventHandler {
471        private::EventHandler(handler)
472    }
473}
474
475/// Functional event handlers.
476pub mod event_handlers {
477    use super::*;
478
479    /// Event handler for buttons events.
480    pub struct Buttons<F>(F);
481    impl<F> ZwpTabletPadGroupV2EventHandler for Buttons<F>
482    where
483        F: Fn(&ZwpTabletPadGroupV2Ref, &[u8]),
484    {
485        #[inline]
486        fn buttons(&self, _slf: &ZwpTabletPadGroupV2Ref, buttons: &[u8]) {
487            self.0(_slf, buttons)
488        }
489    }
490
491    /// Event handler for ring events.
492    pub struct Ring<F>(F);
493    impl<F> ZwpTabletPadGroupV2EventHandler for Ring<F>
494    where
495        F: Fn(&ZwpTabletPadGroupV2Ref, ZwpTabletPadRingV2),
496    {
497        #[inline]
498        fn ring(&self, _slf: &ZwpTabletPadGroupV2Ref, ring: ZwpTabletPadRingV2) {
499            self.0(_slf, ring)
500        }
501    }
502
503    /// Event handler for strip events.
504    pub struct Strip<F>(F);
505    impl<F> ZwpTabletPadGroupV2EventHandler for Strip<F>
506    where
507        F: Fn(&ZwpTabletPadGroupV2Ref, ZwpTabletPadStripV2),
508    {
509        #[inline]
510        fn strip(&self, _slf: &ZwpTabletPadGroupV2Ref, strip: ZwpTabletPadStripV2) {
511            self.0(_slf, strip)
512        }
513    }
514
515    /// Event handler for modes events.
516    pub struct Modes<F>(F);
517    impl<F> ZwpTabletPadGroupV2EventHandler for Modes<F>
518    where
519        F: Fn(&ZwpTabletPadGroupV2Ref, u32),
520    {
521        #[inline]
522        fn modes(&self, _slf: &ZwpTabletPadGroupV2Ref, modes: u32) {
523            self.0(_slf, modes)
524        }
525    }
526
527    /// Event handler for done events.
528    pub struct Done<F>(F);
529    impl<F> ZwpTabletPadGroupV2EventHandler for Done<F>
530    where
531        F: Fn(&ZwpTabletPadGroupV2Ref),
532    {
533        #[inline]
534        fn done(&self, _slf: &ZwpTabletPadGroupV2Ref) {
535            self.0(_slf)
536        }
537    }
538
539    /// Event handler for mode_switch events.
540    pub struct ModeSwitch<F>(F);
541    impl<F> ZwpTabletPadGroupV2EventHandler for ModeSwitch<F>
542    where
543        F: Fn(&ZwpTabletPadGroupV2Ref, u32, u32, u32),
544    {
545        #[inline]
546        fn mode_switch(&self, _slf: &ZwpTabletPadGroupV2Ref, time: u32, serial: u32, mode: u32) {
547            self.0(_slf, time, serial, mode)
548        }
549    }
550
551    impl ZwpTabletPadGroupV2 {
552        /// Creates an event handler for buttons events.
553        ///
554        /// The event handler ignores all other events.
555        #[allow(dead_code)]
556        pub fn on_buttons<F>(f: F) -> Buttons<F>
557        where
558            F: Fn(&ZwpTabletPadGroupV2Ref, &[u8]),
559        {
560            Buttons(f)
561        }
562
563        /// Creates an event handler for ring events.
564        ///
565        /// The event handler ignores all other events.
566        #[allow(dead_code)]
567        pub fn on_ring<F>(f: F) -> Ring<F>
568        where
569            F: Fn(&ZwpTabletPadGroupV2Ref, ZwpTabletPadRingV2),
570        {
571            Ring(f)
572        }
573
574        /// Creates an event handler for strip events.
575        ///
576        /// The event handler ignores all other events.
577        #[allow(dead_code)]
578        pub fn on_strip<F>(f: F) -> Strip<F>
579        where
580            F: Fn(&ZwpTabletPadGroupV2Ref, ZwpTabletPadStripV2),
581        {
582            Strip(f)
583        }
584
585        /// Creates an event handler for modes events.
586        ///
587        /// The event handler ignores all other events.
588        #[allow(dead_code)]
589        pub fn on_modes<F>(f: F) -> Modes<F>
590        where
591            F: Fn(&ZwpTabletPadGroupV2Ref, u32),
592        {
593            Modes(f)
594        }
595
596        /// Creates an event handler for done events.
597        ///
598        /// The event handler ignores all other events.
599        #[allow(dead_code)]
600        pub fn on_done<F>(f: F) -> Done<F>
601        where
602            F: Fn(&ZwpTabletPadGroupV2Ref),
603        {
604            Done(f)
605        }
606
607        /// Creates an event handler for mode_switch events.
608        ///
609        /// The event handler ignores all other events.
610        #[allow(dead_code)]
611        pub fn on_mode_switch<F>(f: F) -> ModeSwitch<F>
612        where
613            F: Fn(&ZwpTabletPadGroupV2Ref, u32, u32, u32),
614        {
615            ModeSwitch(f)
616        }
617    }
618}