simple_window/common/protocols/tablet_v2/
zwp_tablet_pad_ring_v2.rs

1//! pad ring
2//!
3//! A circular interaction area, such as the touch ring on the Wacom Intuos
4//! Pro series tablets.
5//!
6//! Events on a ring are logically grouped by the wl_tablet_pad_ring.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_ring_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"angle".as_ptr(),
49                signature: c"f".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_ring_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 ZwpTabletPadRingV2 {
82    /// This proxy has the interface INTERFACE.
83    proxy: UntypedOwnedProxy,
84}
85
86/// A borrowed zwp_tablet_pad_ring_v2 proxy.
87///
88/// See the documentation of [the module][self] for the interface description.
89#[derive(Eq, PartialEq)]
90#[repr(transparent)]
91pub struct ZwpTabletPadRingV2Ref {
92    /// This proxy has the interface INTERFACE.
93    proxy: UntypedBorrowedProxy,
94}
95
96// SAFETY: ZwpTabletPadRingV2 is a transparent wrapper around UntypedOwnedProxy
97unsafe impl UntypedOwnedProxyWrapper for ZwpTabletPadRingV2 {}
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 ZwpTabletPadRingV2 {
102    const INTERFACE: &'static str = "zwp_tablet_pad_ring_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 = ZwpTabletPadRingV2Ref;
109    type Api = private::ProxyApi;
110    type NoOpEventHandler = private::EventHandler<private::NoOpEventHandler>;
111}
112
113// SAFETY: ZwpTabletPadRingV2Ref is a transparent wrapper around UntypedBorrowedProxy
114unsafe impl UntypedBorrowedProxyWrapper for ZwpTabletPadRingV2Ref {}
115
116// SAFETY: - The only invariant is that self.proxy has a compatible interface
117unsafe impl BorrowedProxy for ZwpTabletPadRingV2Ref {
118    type Owned = ZwpTabletPadRingV2;
119}
120
121impl Deref for ZwpTabletPadRingV2 {
122    type Target = ZwpTabletPadRingV2Ref;
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 ZwpTabletPadRingV2 {
140    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
141        write!(f, "zwp_tablet_pad_ring_v2#{}", self.proxy.id())
142    }
143}
144
145impl Debug for ZwpTabletPadRingV2Ref {
146    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
147        write!(f, "zwp_tablet_pad_ring_v2#{}", self.proxy.id())
148    }
149}
150
151impl PartialEq<ZwpTabletPadRingV2Ref> for ZwpTabletPadRingV2 {
152    fn eq(&self, other: &ZwpTabletPadRingV2Ref) -> bool {
153        self.proxy == other.proxy
154    }
155}
156
157impl PartialEq<ZwpTabletPadRingV2> for ZwpTabletPadRingV2Ref {
158    fn eq(&self, other: &ZwpTabletPadRingV2) -> bool {
159        self.proxy == other.proxy
160    }
161}
162
163#[allow(dead_code)]
164impl ZwpTabletPadRingV2 {
165    /// Since when the destroy request is available.
166    #[allow(dead_code)]
167    pub const REQ__DESTROY__SINCE: u32 = 1;
168
169    /// destroy the ring object
170    ///
171    /// This destroys the client's resource for this ring 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 ZwpTabletPadRingV2Ref {
186    /// set compositor feedback
187    ///
188    /// Request that the compositor use the provided feedback string
189    /// associated with this ring. 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 ring 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 ring; 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    /// ring. Requests providing other serials than the most recent one will be
206    /// ignored.
207    ///
208    /// # Arguments
209    ///
210    /// - `description`: ring 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 ZwpTabletPadRingV2 {
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 angle event is available.
237    #[allow(dead_code)]
238    pub const EVT__ANGLE__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 [ZwpTabletPadRingV2] proxies.
250#[allow(dead_code)]
251pub trait ZwpTabletPadRingV2EventHandler {
252    /// ring event source
253    ///
254    /// Source information for ring events.
255    ///
256    /// This event does not occur on its own. It is sent before a
257    /// wp_tablet_pad_ring.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_ring.source.finger, a wp_tablet_pad_ring.stop event
262    /// will be sent when the user lifts the 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: &ZwpTabletPadRingV2Ref, source: ZwpTabletPadRingV2Source) {
272        let _ = source;
273    }
274
275    /// angle changed
276    ///
277    /// Sent whenever the angle on a ring changes.
278    ///
279    /// The angle is provided in degrees clockwise from the logical
280    /// north of the ring in the pad's current rotation.
281    ///
282    /// # Arguments
283    ///
284    /// - `degrees`: the current angle in degrees
285    #[inline]
286    fn angle(&self, _slf: &ZwpTabletPadRingV2Ref, degrees: Fixed) {
287        let _ = degrees;
288    }
289
290    /// interaction stopped
291    ///
292    /// Stop notification for ring events.
293    ///
294    /// For some wp_tablet_pad_ring.source types, a wp_tablet_pad_ring.stop
295    /// event is sent to notify a client that the interaction with the ring
296    /// has terminated. This enables the client to implement kinetic scrolling.
297    /// See the wp_tablet_pad_ring.source documentation for information on
298    /// when this event may be generated.
299    ///
300    /// Any wp_tablet_pad_ring.angle events with the same source after this
301    /// event should be considered as the start of a new interaction.
302    #[inline]
303    fn stop(&self, _slf: &ZwpTabletPadRingV2Ref) {}
304
305    /// end of a ring event sequence
306    ///
307    /// Indicates the end of a set of ring events that logically belong
308    /// together. A client is expected to accumulate the data in all events
309    /// within the frame before proceeding.
310    ///
311    /// All wp_tablet_pad_ring events before a wp_tablet_pad_ring.frame event belong
312    /// logically together. For example, on termination of a finger interaction
313    /// on a ring the compositor will send a wp_tablet_pad_ring.source event,
314    /// a wp_tablet_pad_ring.stop event and a wp_tablet_pad_ring.frame event.
315    ///
316    /// A wp_tablet_pad_ring.frame event is sent for every logical event
317    /// group, even if the group only contains a single wp_tablet_pad_ring
318    /// event. Specifically, a client may get a sequence: angle, frame,
319    /// angle, frame, etc.
320    ///
321    /// # Arguments
322    ///
323    /// - `time`: timestamp with millisecond granularity
324    #[inline]
325    fn frame(&self, _slf: &ZwpTabletPadRingV2Ref, time: u32) {
326        let _ = time;
327    }
328}
329
330impl ZwpTabletPadRingV2EventHandler for private::NoOpEventHandler {}
331
332// SAFETY: - INTERFACE is a valid wl_interface
333unsafe impl<H> EventHandler for private::EventHandler<H>
334where
335    H: ZwpTabletPadRingV2EventHandler,
336{
337    const WL_INTERFACE: &'static wl_interface = &INTERFACE;
338
339    #[allow(unused_variables)]
340    unsafe fn handle_event(
341        &self,
342        queue: &Queue,
343        data: *mut u8,
344        slf: &UntypedBorrowedProxy,
345        opcode: u32,
346        args: *mut wl_argument,
347    ) {
348        // SAFETY: This function requires that slf has the interface INTERFACE
349        let slf = unsafe { proxy::low_level::from_untyped_borrowed::<ZwpTabletPadRingV2Ref>(slf) };
350        match opcode {
351            0 => {
352                // SAFETY: INTERFACE requires that there are 1 arguments
353                let args = unsafe { &*args.cast::<[wl_argument; 1]>() };
354                // SAFETY: - INTERFACE requires that args[0] contains a uint
355                let arg0 = unsafe { ZwpTabletPadRingV2Source(args[0].u) };
356                self.0.source(slf, arg0);
357            }
358            1 => {
359                // SAFETY: INTERFACE requires that there are 1 arguments
360                let args = unsafe { &*args.cast::<[wl_argument; 1]>() };
361                // SAFETY: - INTERFACE requires that args[0] contains a fixed
362                let arg0 = unsafe { Fixed::from_wire(args[0].f) };
363                self.0.angle(slf, arg0);
364            }
365            2 => {
366                self.0.stop(slf);
367            }
368            3 => {
369                // SAFETY: INTERFACE requires that there are 1 arguments
370                let args = unsafe { &*args.cast::<[wl_argument; 1]>() };
371                // SAFETY: - INTERFACE requires that args[0] contains a uint
372                let arg0 = unsafe { args[0].u };
373                self.0.frame(slf, arg0);
374            }
375            _ => {
376                invalid_opcode("zwp_tablet_pad_ring_v2", opcode);
377            }
378        }
379    }
380}
381
382impl<H> CreateEventHandler<H> for private::ProxyApi
383where
384    H: ZwpTabletPadRingV2EventHandler,
385{
386    type EventHandler = private::EventHandler<H>;
387
388    #[inline]
389    fn create_event_handler(handler: H) -> Self::EventHandler {
390        private::EventHandler(handler)
391    }
392}
393
394impl ZwpTabletPadRingV2 {
395    /// Since when the source.finger enum variant is available.
396    #[allow(dead_code)]
397    pub const ENM__SOURCE_FINGER__SINCE: u32 = 1;
398}
399
400/// ring axis source
401///
402/// Describes the source types for ring events. This indicates to the
403/// client how a ring event was physically generated; a client may
404/// adjust the user interface accordingly. For example, events
405/// from a "finger" source may trigger kinetic scrolling.
406#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
407#[allow(dead_code)]
408pub struct ZwpTabletPadRingV2Source(pub u32);
409
410impl ZwpTabletPadRingV2Source {
411    /// finger
412    #[allow(dead_code)]
413    pub const FINGER: Self = Self(1);
414}
415
416impl Debug for ZwpTabletPadRingV2Source {
417    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
418        let name = match *self {
419            Self::FINGER => "FINGER",
420            _ => return Debug::fmt(&self.0, f),
421        };
422        f.write_str(name)
423    }
424}
425
426/// Functional event handlers.
427pub mod event_handlers {
428    use super::*;
429
430    /// Event handler for source events.
431    pub struct Source<F>(F);
432    impl<F> ZwpTabletPadRingV2EventHandler for Source<F>
433    where
434        F: Fn(&ZwpTabletPadRingV2Ref, ZwpTabletPadRingV2Source),
435    {
436        #[inline]
437        fn source(&self, _slf: &ZwpTabletPadRingV2Ref, source: ZwpTabletPadRingV2Source) {
438            self.0(_slf, source)
439        }
440    }
441
442    /// Event handler for angle events.
443    pub struct Angle<F>(F);
444    impl<F> ZwpTabletPadRingV2EventHandler for Angle<F>
445    where
446        F: Fn(&ZwpTabletPadRingV2Ref, Fixed),
447    {
448        #[inline]
449        fn angle(&self, _slf: &ZwpTabletPadRingV2Ref, degrees: Fixed) {
450            self.0(_slf, degrees)
451        }
452    }
453
454    /// Event handler for stop events.
455    pub struct Stop<F>(F);
456    impl<F> ZwpTabletPadRingV2EventHandler for Stop<F>
457    where
458        F: Fn(&ZwpTabletPadRingV2Ref),
459    {
460        #[inline]
461        fn stop(&self, _slf: &ZwpTabletPadRingV2Ref) {
462            self.0(_slf)
463        }
464    }
465
466    /// Event handler for frame events.
467    pub struct Frame<F>(F);
468    impl<F> ZwpTabletPadRingV2EventHandler for Frame<F>
469    where
470        F: Fn(&ZwpTabletPadRingV2Ref, u32),
471    {
472        #[inline]
473        fn frame(&self, _slf: &ZwpTabletPadRingV2Ref, time: u32) {
474            self.0(_slf, time)
475        }
476    }
477
478    impl ZwpTabletPadRingV2 {
479        /// Creates an event handler for source events.
480        ///
481        /// The event handler ignores all other events.
482        #[allow(dead_code)]
483        pub fn on_source<F>(f: F) -> Source<F>
484        where
485            F: Fn(&ZwpTabletPadRingV2Ref, ZwpTabletPadRingV2Source),
486        {
487            Source(f)
488        }
489
490        /// Creates an event handler for angle events.
491        ///
492        /// The event handler ignores all other events.
493        #[allow(dead_code)]
494        pub fn on_angle<F>(f: F) -> Angle<F>
495        where
496            F: Fn(&ZwpTabletPadRingV2Ref, Fixed),
497        {
498            Angle(f)
499        }
500
501        /// Creates an event handler for stop events.
502        ///
503        /// The event handler ignores all other events.
504        #[allow(dead_code)]
505        pub fn on_stop<F>(f: F) -> Stop<F>
506        where
507            F: Fn(&ZwpTabletPadRingV2Ref),
508        {
509            Stop(f)
510        }
511
512        /// Creates an event handler for frame events.
513        ///
514        /// The event handler ignores all other events.
515        #[allow(dead_code)]
516        pub fn on_frame<F>(f: F) -> Frame<F>
517        where
518            F: Fn(&ZwpTabletPadRingV2Ref, u32),
519        {
520            Frame(f)
521        }
522    }
523}