simple_window/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        data: *mut u8,
346        slf: &UntypedBorrowedProxy,
347        opcode: u32,
348        args: *mut wl_argument,
349    ) {
350        // SAFETY: This function requires that slf has the interface INTERFACE
351        let slf = unsafe { proxy::low_level::from_untyped_borrowed::<ZwpTabletPadStripV2Ref>(slf) };
352        match opcode {
353            0 => {
354                // SAFETY: INTERFACE requires that there are 1 arguments
355                let args = unsafe { &*args.cast::<[wl_argument; 1]>() };
356                // SAFETY: - INTERFACE requires that args[0] contains a uint
357                let arg0 = unsafe { ZwpTabletPadStripV2Source(args[0].u) };
358                self.0.source(slf, arg0);
359            }
360            1 => {
361                // SAFETY: INTERFACE requires that there are 1 arguments
362                let args = unsafe { &*args.cast::<[wl_argument; 1]>() };
363                // SAFETY: - INTERFACE requires that args[0] contains a uint
364                let arg0 = unsafe { args[0].u };
365                self.0.position(slf, arg0);
366            }
367            2 => {
368                self.0.stop(slf);
369            }
370            3 => {
371                // SAFETY: INTERFACE requires that there are 1 arguments
372                let args = unsafe { &*args.cast::<[wl_argument; 1]>() };
373                // SAFETY: - INTERFACE requires that args[0] contains a uint
374                let arg0 = unsafe { args[0].u };
375                self.0.frame(slf, arg0);
376            }
377            _ => {
378                invalid_opcode("zwp_tablet_pad_strip_v2", opcode);
379            }
380        }
381    }
382}
383
384impl<H> CreateEventHandler<H> for private::ProxyApi
385where
386    H: ZwpTabletPadStripV2EventHandler,
387{
388    type EventHandler = private::EventHandler<H>;
389
390    #[inline]
391    fn create_event_handler(handler: H) -> Self::EventHandler {
392        private::EventHandler(handler)
393    }
394}
395
396impl ZwpTabletPadStripV2 {
397    /// Since when the source.finger enum variant is available.
398    #[allow(dead_code)]
399    pub const ENM__SOURCE_FINGER__SINCE: u32 = 1;
400}
401
402/// strip axis source
403///
404/// Describes the source types for strip events. This indicates to the
405/// client how a strip event was physically generated; a client may
406/// adjust the user interface accordingly. For example, events
407/// from a "finger" source may trigger kinetic scrolling.
408#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
409#[allow(dead_code)]
410pub struct ZwpTabletPadStripV2Source(pub u32);
411
412impl ZwpTabletPadStripV2Source {
413    /// finger
414    #[allow(dead_code)]
415    pub const FINGER: Self = Self(1);
416}
417
418impl Debug for ZwpTabletPadStripV2Source {
419    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
420        let name = match *self {
421            Self::FINGER => "FINGER",
422            _ => return Debug::fmt(&self.0, f),
423        };
424        f.write_str(name)
425    }
426}
427
428/// Functional event handlers.
429pub mod event_handlers {
430    use super::*;
431
432    /// Event handler for source events.
433    pub struct Source<F>(F);
434    impl<F> ZwpTabletPadStripV2EventHandler for Source<F>
435    where
436        F: Fn(&ZwpTabletPadStripV2Ref, ZwpTabletPadStripV2Source),
437    {
438        #[inline]
439        fn source(&self, _slf: &ZwpTabletPadStripV2Ref, source: ZwpTabletPadStripV2Source) {
440            self.0(_slf, source)
441        }
442    }
443
444    /// Event handler for position events.
445    pub struct Position<F>(F);
446    impl<F> ZwpTabletPadStripV2EventHandler for Position<F>
447    where
448        F: Fn(&ZwpTabletPadStripV2Ref, u32),
449    {
450        #[inline]
451        fn position(&self, _slf: &ZwpTabletPadStripV2Ref, position: u32) {
452            self.0(_slf, position)
453        }
454    }
455
456    /// Event handler for stop events.
457    pub struct Stop<F>(F);
458    impl<F> ZwpTabletPadStripV2EventHandler for Stop<F>
459    where
460        F: Fn(&ZwpTabletPadStripV2Ref),
461    {
462        #[inline]
463        fn stop(&self, _slf: &ZwpTabletPadStripV2Ref) {
464            self.0(_slf)
465        }
466    }
467
468    /// Event handler for frame events.
469    pub struct Frame<F>(F);
470    impl<F> ZwpTabletPadStripV2EventHandler for Frame<F>
471    where
472        F: Fn(&ZwpTabletPadStripV2Ref, u32),
473    {
474        #[inline]
475        fn frame(&self, _slf: &ZwpTabletPadStripV2Ref, time: u32) {
476            self.0(_slf, time)
477        }
478    }
479
480    impl ZwpTabletPadStripV2 {
481        /// Creates an event handler for source events.
482        ///
483        /// The event handler ignores all other events.
484        #[allow(dead_code)]
485        pub fn on_source<F>(f: F) -> Source<F>
486        where
487            F: Fn(&ZwpTabletPadStripV2Ref, ZwpTabletPadStripV2Source),
488        {
489            Source(f)
490        }
491
492        /// Creates an event handler for position events.
493        ///
494        /// The event handler ignores all other events.
495        #[allow(dead_code)]
496        pub fn on_position<F>(f: F) -> Position<F>
497        where
498            F: Fn(&ZwpTabletPadStripV2Ref, u32),
499        {
500            Position(f)
501        }
502
503        /// Creates an event handler for stop events.
504        ///
505        /// The event handler ignores all other events.
506        #[allow(dead_code)]
507        pub fn on_stop<F>(f: F) -> Stop<F>
508        where
509            F: Fn(&ZwpTabletPadStripV2Ref),
510        {
511            Stop(f)
512        }
513
514        /// Creates an event handler for frame events.
515        ///
516        /// The event handler ignores all other events.
517        #[allow(dead_code)]
518        pub fn on_frame<F>(f: F) -> Frame<F>
519        where
520            F: Fn(&ZwpTabletPadStripV2Ref, u32),
521        {
522            Frame(f)
523        }
524    }
525}