poll_integration/common/protocols/tablet_v2/
zwp_tablet_pad_strip_v2.rs

1//! pad strip
2//!
3//! A linear interaction area, such as the strips found in Wacom Cintiq
4//! models.
5//!
6//! Events on a strip are logically grouped by the wl_tablet_pad_strip.frame
7//! event.
8
9use {super::super::all_types::*, ::wl_client::builder::prelude::*};
10
11static INTERFACE: wl_interface = wl_interface {
12    name: c"zwp_tablet_pad_strip_v2".as_ptr(),
13    version: 1,
14    method_count: 2,
15    methods: {
16        static MESSAGES: [wl_message; 2] = [
17            wl_message {
18                name: c"set_feedback".as_ptr(),
19                signature: c"su".as_ptr(),
20                types: {
21                    static TYPES: [Option<&'static wl_interface>; 2] = [None, None];
22                    TYPES.as_ptr().cast()
23                },
24            },
25            wl_message {
26                name: c"destroy".as_ptr(),
27                signature: c"".as_ptr(),
28                types: {
29                    static TYPES: [Option<&'static wl_interface>; 0] = [];
30                    TYPES.as_ptr().cast()
31                },
32            },
33        ];
34        MESSAGES.as_ptr()
35    },
36    event_count: 4,
37    events: {
38        static MESSAGES: [wl_message; 4] = [
39            wl_message {
40                name: c"source".as_ptr(),
41                signature: c"u".as_ptr(),
42                types: {
43                    static TYPES: [Option<&'static wl_interface>; 1] = [None];
44                    TYPES.as_ptr().cast()
45                },
46            },
47            wl_message {
48                name: c"position".as_ptr(),
49                signature: c"u".as_ptr(),
50                types: {
51                    static TYPES: [Option<&'static wl_interface>; 1] = [None];
52                    TYPES.as_ptr().cast()
53                },
54            },
55            wl_message {
56                name: c"stop".as_ptr(),
57                signature: c"".as_ptr(),
58                types: {
59                    static TYPES: [Option<&'static wl_interface>; 0] = [];
60                    TYPES.as_ptr().cast()
61                },
62            },
63            wl_message {
64                name: c"frame".as_ptr(),
65                signature: c"u".as_ptr(),
66                types: {
67                    static TYPES: [Option<&'static wl_interface>; 1] = [None];
68                    TYPES.as_ptr().cast()
69                },
70            },
71        ];
72        MESSAGES.as_ptr()
73    },
74};
75
76/// An owned zwp_tablet_pad_strip_v2 proxy.
77///
78/// See the documentation of [the module][self] for the interface description.
79#[derive(Clone, Eq, PartialEq)]
80#[repr(transparent)]
81pub struct ZwpTabletPadStripV2 {
82    /// This proxy has the interface INTERFACE.
83    proxy: UntypedOwnedProxy,
84}
85
86/// A borrowed zwp_tablet_pad_strip_v2 proxy.
87///
88/// See the documentation of [the module][self] for the interface description.
89#[derive(Eq, PartialEq)]
90#[repr(transparent)]
91pub struct ZwpTabletPadStripV2Ref {
92    /// This proxy has the interface INTERFACE.
93    proxy: UntypedBorrowedProxy,
94}
95
96// SAFETY: ZwpTabletPadStripV2 is a transparent wrapper around UntypedOwnedProxy
97unsafe impl UntypedOwnedProxyWrapper for ZwpTabletPadStripV2 {}
98
99// SAFETY: - INTERFACE is a valid wl_interface
100//         - The only invariant is that self.proxy has a compatible interface
101unsafe impl OwnedProxy for ZwpTabletPadStripV2 {
102    const INTERFACE: &'static str = "zwp_tablet_pad_strip_v2";
103    const WL_INTERFACE: &'static wl_interface = &INTERFACE;
104    const NO_OP_EVENT_HANDLER: Self::NoOpEventHandler =
105        private::EventHandler(private::NoOpEventHandler);
106    const MAX_VERSION: u32 = 1;
107
108    type Borrowed = ZwpTabletPadStripV2Ref;
109    type Api = private::ProxyApi;
110    type NoOpEventHandler = private::EventHandler<private::NoOpEventHandler>;
111}
112
113// SAFETY: ZwpTabletPadStripV2Ref is a transparent wrapper around UntypedBorrowedProxy
114unsafe impl UntypedBorrowedProxyWrapper for ZwpTabletPadStripV2Ref {}
115
116// SAFETY: - The only invariant is that self.proxy has a compatible interface
117unsafe impl BorrowedProxy for ZwpTabletPadStripV2Ref {
118    type Owned = ZwpTabletPadStripV2;
119}
120
121impl Deref for ZwpTabletPadStripV2 {
122    type Target = ZwpTabletPadStripV2Ref;
123
124    fn deref(&self) -> &Self::Target {
125        proxy::low_level::deref(self)
126    }
127}
128
129mod private {
130    pub struct ProxyApi;
131
132    #[allow(dead_code)]
133    pub struct EventHandler<H>(pub(super) H);
134
135    #[allow(dead_code)]
136    pub struct NoOpEventHandler;
137}
138
139impl Debug for ZwpTabletPadStripV2 {
140    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
141        write!(f, "zwp_tablet_pad_strip_v2#{}", self.proxy.id())
142    }
143}
144
145impl Debug for ZwpTabletPadStripV2Ref {
146    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
147        write!(f, "zwp_tablet_pad_strip_v2#{}", self.proxy.id())
148    }
149}
150
151impl PartialEq<ZwpTabletPadStripV2Ref> for ZwpTabletPadStripV2 {
152    fn eq(&self, other: &ZwpTabletPadStripV2Ref) -> bool {
153        self.proxy == other.proxy
154    }
155}
156
157impl PartialEq<ZwpTabletPadStripV2> for ZwpTabletPadStripV2Ref {
158    fn eq(&self, other: &ZwpTabletPadStripV2) -> bool {
159        self.proxy == other.proxy
160    }
161}
162
163#[allow(dead_code)]
164impl ZwpTabletPadStripV2 {
165    /// Since when the destroy request is available.
166    #[allow(dead_code)]
167    pub const REQ__DESTROY__SINCE: u32 = 1;
168
169    /// destroy the strip object
170    ///
171    /// This destroys the client's resource for this strip object.
172    #[inline]
173    pub fn destroy(&self) {
174        let mut args = [];
175        // SAFETY: - self.proxy has the interface INTERFACE
176        //         - 1 < INTERFACE.method_count = 2
177        //         - the request signature is ``
178        unsafe {
179            self.proxy.send_destructor(1, &mut args);
180        }
181    }
182}
183
184#[allow(dead_code)]
185impl ZwpTabletPadStripV2Ref {
186    /// set compositor feedback
187    ///
188    /// Requests the compositor to use the provided feedback string
189    /// associated with this strip. This request should be issued immediately
190    /// after a wp_tablet_pad_group.mode_switch event from the corresponding
191    /// group is received, or whenever the strip is mapped to a different
192    /// action. See wp_tablet_pad_group.mode_switch for more details.
193    ///
194    /// Clients are encouraged to provide context-aware descriptions for
195    /// the actions associated with the strip, and compositors may use this
196    /// information to offer visual feedback about the button layout
197    /// (eg. on-screen displays).
198    ///
199    /// The provided string 'description' is a UTF-8 encoded string to be
200    /// associated with this ring, and is considered user-visible; general
201    /// internationalization rules apply.
202    ///
203    /// The serial argument will be that of the last
204    /// wp_tablet_pad_group.mode_switch event received for the group of this
205    /// strip. Requests providing other serials than the most recent one will be
206    /// ignored.
207    ///
208    /// # Arguments
209    ///
210    /// - `description`: strip description
211    /// - `serial`: serial of the mode switch event
212    #[inline]
213    pub fn set_feedback(&self, description: &str, serial: u32) {
214        let (arg0, arg1) = (description, serial);
215        with_cstr_cache(|cache| {
216            let str0_offset = cache.len();
217            cache.extend_from_slice(arg0.as_bytes());
218            cache.push(0);
219            let str0 = cache[str0_offset..].as_ptr().cast();
220            let mut args = [wl_argument { s: str0 }, wl_argument { u: arg1 }];
221            // SAFETY: - self.proxy has the interface INTERFACE
222            //         - 0 < INTERFACE.method_count = 2
223            //         - the request signature is `su`
224            unsafe {
225                self.proxy.send_request(0, &mut args);
226            }
227        })
228    }
229}
230
231impl ZwpTabletPadStripV2 {
232    /// Since when the source event is available.
233    #[allow(dead_code)]
234    pub const EVT__SOURCE__SINCE: u32 = 1;
235
236    /// Since when the position event is available.
237    #[allow(dead_code)]
238    pub const EVT__POSITION__SINCE: u32 = 1;
239
240    /// Since when the stop event is available.
241    #[allow(dead_code)]
242    pub const EVT__STOP__SINCE: u32 = 1;
243
244    /// Since when the frame event is available.
245    #[allow(dead_code)]
246    pub const EVT__FRAME__SINCE: u32 = 1;
247}
248
249/// An event handler for [ZwpTabletPadStripV2] proxies.
250#[allow(dead_code)]
251pub trait ZwpTabletPadStripV2EventHandler {
252    /// strip event source
253    ///
254    /// Source information for strip events.
255    ///
256    /// This event does not occur on its own. It is sent before a
257    /// wp_tablet_pad_strip.frame event and carries the source information
258    /// for all events within that frame.
259    ///
260    /// The source specifies how this event was generated. If the source is
261    /// wp_tablet_pad_strip.source.finger, a wp_tablet_pad_strip.stop event
262    /// will be sent when the user lifts their finger off the device.
263    ///
264    /// This event is optional. If the source is unknown for an interaction,
265    /// no event is sent.
266    ///
267    /// # Arguments
268    ///
269    /// - `source`: the event source
270    #[inline]
271    fn source(&self, _slf: &ZwpTabletPadStripV2Ref, source: ZwpTabletPadStripV2Source) {
272        let _ = source;
273    }
274
275    /// position changed
276    ///
277    /// Sent whenever the position on a strip changes.
278    ///
279    /// The position is normalized to a range of [0, 65535], the 0-value
280    /// represents the top-most and/or left-most position of the strip in
281    /// the pad's current rotation.
282    ///
283    /// # Arguments
284    ///
285    /// - `position`: the current position
286    #[inline]
287    fn position(&self, _slf: &ZwpTabletPadStripV2Ref, position: u32) {
288        let _ = position;
289    }
290
291    /// interaction stopped
292    ///
293    /// Stop notification for strip events.
294    ///
295    /// For some wp_tablet_pad_strip.source types, a wp_tablet_pad_strip.stop
296    /// event is sent to notify a client that the interaction with the strip
297    /// has terminated. This enables the client to implement kinetic
298    /// scrolling. See the wp_tablet_pad_strip.source documentation for
299    /// information on when this event may be generated.
300    ///
301    /// Any wp_tablet_pad_strip.position events with the same source after this
302    /// event should be considered as the start of a new interaction.
303    #[inline]
304    fn stop(&self, _slf: &ZwpTabletPadStripV2Ref) {}
305
306    /// end of a strip event sequence
307    ///
308    /// Indicates the end of a set of events that represent one logical
309    /// hardware strip event. A client is expected to accumulate the data
310    /// in all events within the frame before proceeding.
311    ///
312    /// All wp_tablet_pad_strip events before a wp_tablet_pad_strip.frame event belong
313    /// logically together. For example, on termination of a finger interaction
314    /// on a strip the compositor will send a wp_tablet_pad_strip.source event,
315    /// a wp_tablet_pad_strip.stop event and a wp_tablet_pad_strip.frame
316    /// event.
317    ///
318    /// A wp_tablet_pad_strip.frame event is sent for every logical event
319    /// group, even if the group only contains a single wp_tablet_pad_strip
320    /// event. Specifically, a client may get a sequence: position, frame,
321    /// position, frame, etc.
322    ///
323    /// # Arguments
324    ///
325    /// - `time`: timestamp with millisecond granularity
326    #[inline]
327    fn frame(&self, _slf: &ZwpTabletPadStripV2Ref, time: u32) {
328        let _ = time;
329    }
330}
331
332impl ZwpTabletPadStripV2EventHandler for private::NoOpEventHandler {}
333
334// SAFETY: INTERFACE is a valid wl_interface
335unsafe impl<H> EventHandler for private::EventHandler<H>
336where
337    H: ZwpTabletPadStripV2EventHandler,
338{
339    const WL_INTERFACE: &'static wl_interface = &INTERFACE;
340
341    #[allow(unused_variables)]
342    unsafe fn handle_event(
343        &self,
344        queue: &Queue,
345        slf: &UntypedBorrowedProxy,
346        opcode: u32,
347        args: *mut wl_argument,
348    ) {
349        // SAFETY: This function required that slf has the interface INTERFACE
350        let slf = unsafe { proxy::low_level::from_untyped_borrowed::<ZwpTabletPadStripV2Ref>(slf) };
351        match opcode {
352            0 => {
353                // SAFETY: INTERFACE requires that there are 1 arguments
354                let args = unsafe { &*args.cast::<[wl_argument; 1]>() };
355                // SAFETY: - INTERFACE requires that args[0] contains a uint
356                let arg0 = unsafe { ZwpTabletPadStripV2Source(args[0].u) };
357                self.0.source(slf, arg0);
358            }
359            1 => {
360                // SAFETY: INTERFACE requires that there are 1 arguments
361                let args = unsafe { &*args.cast::<[wl_argument; 1]>() };
362                // SAFETY: - INTERFACE requires that args[0] contains a uint
363                let arg0 = unsafe { args[0].u };
364                self.0.position(slf, arg0);
365            }
366            2 => {
367                self.0.stop(slf);
368            }
369            3 => {
370                // SAFETY: INTERFACE requires that there are 1 arguments
371                let args = unsafe { &*args.cast::<[wl_argument; 1]>() };
372                // SAFETY: - INTERFACE requires that args[0] contains a uint
373                let arg0 = unsafe { args[0].u };
374                self.0.frame(slf, arg0);
375            }
376            _ => {
377                invalid_opcode("zwp_tablet_pad_strip_v2", opcode);
378            }
379        }
380    }
381}
382
383impl<H> CreateEventHandler<H> for private::ProxyApi
384where
385    H: ZwpTabletPadStripV2EventHandler,
386{
387    type EventHandler = private::EventHandler<H>;
388
389    #[inline]
390    fn create_event_handler(handler: H) -> Self::EventHandler {
391        private::EventHandler(handler)
392    }
393}
394
395impl ZwpTabletPadStripV2 {
396    /// Since when the source.finger enum variant is available.
397    #[allow(dead_code)]
398    pub const ENM__SOURCE_FINGER__SINCE: u32 = 1;
399}
400
401/// strip axis source
402///
403/// Describes the source types for strip events. This indicates to the
404/// client how a strip event was physically generated; a client may
405/// adjust the user interface accordingly. For example, events
406/// from a "finger" source may trigger kinetic scrolling.
407#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
408#[allow(dead_code)]
409pub struct ZwpTabletPadStripV2Source(pub u32);
410
411impl ZwpTabletPadStripV2Source {
412    /// finger
413    #[allow(dead_code)]
414    pub const FINGER: Self = Self(1);
415}
416
417impl Debug for ZwpTabletPadStripV2Source {
418    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
419        let name = match *self {
420            Self::FINGER => "FINGER",
421            _ => return Debug::fmt(&self.0, f),
422        };
423        f.write_str(name)
424    }
425}
426
427/// Functional event handlers.
428pub mod event_handlers {
429    use super::*;
430
431    /// Event handler for source events.
432    pub struct Source<F>(F);
433    impl<F> ZwpTabletPadStripV2EventHandler for Source<F>
434    where
435        F: Fn(&ZwpTabletPadStripV2Ref, ZwpTabletPadStripV2Source),
436    {
437        #[inline]
438        fn source(&self, _slf: &ZwpTabletPadStripV2Ref, source: ZwpTabletPadStripV2Source) {
439            self.0(_slf, source)
440        }
441    }
442
443    /// Event handler for position events.
444    pub struct Position<F>(F);
445    impl<F> ZwpTabletPadStripV2EventHandler for Position<F>
446    where
447        F: Fn(&ZwpTabletPadStripV2Ref, u32),
448    {
449        #[inline]
450        fn position(&self, _slf: &ZwpTabletPadStripV2Ref, position: u32) {
451            self.0(_slf, position)
452        }
453    }
454
455    /// Event handler for stop events.
456    pub struct Stop<F>(F);
457    impl<F> ZwpTabletPadStripV2EventHandler for Stop<F>
458    where
459        F: Fn(&ZwpTabletPadStripV2Ref),
460    {
461        #[inline]
462        fn stop(&self, _slf: &ZwpTabletPadStripV2Ref) {
463            self.0(_slf)
464        }
465    }
466
467    /// Event handler for frame events.
468    pub struct Frame<F>(F);
469    impl<F> ZwpTabletPadStripV2EventHandler for Frame<F>
470    where
471        F: Fn(&ZwpTabletPadStripV2Ref, u32),
472    {
473        #[inline]
474        fn frame(&self, _slf: &ZwpTabletPadStripV2Ref, time: u32) {
475            self.0(_slf, time)
476        }
477    }
478
479    impl ZwpTabletPadStripV2 {
480        /// Creates an event handler for source events.
481        ///
482        /// The event handler ignores all other events.
483        #[allow(dead_code)]
484        pub fn on_source<F>(f: F) -> Source<F>
485        where
486            F: Fn(&ZwpTabletPadStripV2Ref, ZwpTabletPadStripV2Source),
487        {
488            Source(f)
489        }
490
491        /// Creates an event handler for position events.
492        ///
493        /// The event handler ignores all other events.
494        #[allow(dead_code)]
495        pub fn on_position<F>(f: F) -> Position<F>
496        where
497            F: Fn(&ZwpTabletPadStripV2Ref, u32),
498        {
499            Position(f)
500        }
501
502        /// Creates an event handler for stop events.
503        ///
504        /// The event handler ignores all other events.
505        #[allow(dead_code)]
506        pub fn on_stop<F>(f: F) -> Stop<F>
507        where
508            F: Fn(&ZwpTabletPadStripV2Ref),
509        {
510            Stop(f)
511        }
512
513        /// Creates an event handler for frame events.
514        ///
515        /// The event handler ignores all other events.
516        #[allow(dead_code)]
517        pub fn on_frame<F>(f: F) -> Frame<F>
518        where
519            F: Fn(&ZwpTabletPadStripV2Ref, u32),
520        {
521            Frame(f)
522        }
523    }
524}