poll_integration/common/protocols/wayland/
wl_touch.rs

1//! touchscreen input device
2//!
3//! The wl_touch interface represents a touchscreen
4//! associated with a seat.
5//!
6//! Touch interactions can consist of one or more contacts.
7//! For each contact, a series of events is generated, starting
8//! with a down event, followed by zero or more motion events,
9//! and ending with an up event. Events relating to the same
10//! contact point can be identified by the ID of the sequence.
11
12use {super::super::all_types::*, ::wl_client::builder::prelude::*};
13
14static INTERFACE: wl_interface = wl_interface {
15    name: c"wl_touch".as_ptr(),
16    version: 10,
17    method_count: 1,
18    methods: {
19        static MESSAGES: [wl_message; 1] = [wl_message {
20            name: c"release".as_ptr(),
21            signature: c"".as_ptr(),
22            types: {
23                static TYPES: [Option<&'static wl_interface>; 0] = [];
24                TYPES.as_ptr().cast()
25            },
26        }];
27        MESSAGES.as_ptr()
28    },
29    event_count: 7,
30    events: {
31        static MESSAGES: [wl_message; 7] = [
32            wl_message {
33                name: c"down".as_ptr(),
34                signature: c"uuoiff".as_ptr(),
35                types: {
36                    static TYPES: [Option<&'static wl_interface>; 6] =
37                        [None, None, Some(WlSurface::WL_INTERFACE), None, None, None];
38                    TYPES.as_ptr().cast()
39                },
40            },
41            wl_message {
42                name: c"up".as_ptr(),
43                signature: c"uui".as_ptr(),
44                types: {
45                    static TYPES: [Option<&'static wl_interface>; 3] = [None, None, None];
46                    TYPES.as_ptr().cast()
47                },
48            },
49            wl_message {
50                name: c"motion".as_ptr(),
51                signature: c"uiff".as_ptr(),
52                types: {
53                    static TYPES: [Option<&'static wl_interface>; 4] = [None, None, None, None];
54                    TYPES.as_ptr().cast()
55                },
56            },
57            wl_message {
58                name: c"frame".as_ptr(),
59                signature: c"".as_ptr(),
60                types: {
61                    static TYPES: [Option<&'static wl_interface>; 0] = [];
62                    TYPES.as_ptr().cast()
63                },
64            },
65            wl_message {
66                name: c"cancel".as_ptr(),
67                signature: c"".as_ptr(),
68                types: {
69                    static TYPES: [Option<&'static wl_interface>; 0] = [];
70                    TYPES.as_ptr().cast()
71                },
72            },
73            wl_message {
74                name: c"shape".as_ptr(),
75                signature: c"iff".as_ptr(),
76                types: {
77                    static TYPES: [Option<&'static wl_interface>; 3] = [None, None, None];
78                    TYPES.as_ptr().cast()
79                },
80            },
81            wl_message {
82                name: c"orientation".as_ptr(),
83                signature: c"if".as_ptr(),
84                types: {
85                    static TYPES: [Option<&'static wl_interface>; 2] = [None, None];
86                    TYPES.as_ptr().cast()
87                },
88            },
89        ];
90        MESSAGES.as_ptr()
91    },
92};
93
94/// An owned wl_touch proxy.
95///
96/// See the documentation of [the module][self] for the interface description.
97#[derive(Clone, Eq, PartialEq)]
98#[repr(transparent)]
99pub struct WlTouch {
100    /// This proxy has the interface INTERFACE.
101    proxy: UntypedOwnedProxy,
102}
103
104/// A borrowed wl_touch proxy.
105///
106/// See the documentation of [the module][self] for the interface description.
107#[derive(Eq, PartialEq)]
108#[repr(transparent)]
109pub struct WlTouchRef {
110    /// This proxy has the interface INTERFACE.
111    proxy: UntypedBorrowedProxy,
112}
113
114// SAFETY: WlTouch is a transparent wrapper around UntypedOwnedProxy
115unsafe impl UntypedOwnedProxyWrapper for WlTouch {}
116
117// SAFETY: - INTERFACE is a valid wl_interface
118//         - The only invariant is that self.proxy has a compatible interface
119unsafe impl OwnedProxy for WlTouch {
120    const INTERFACE: &'static str = "wl_touch";
121    const WL_INTERFACE: &'static wl_interface = &INTERFACE;
122    const NO_OP_EVENT_HANDLER: Self::NoOpEventHandler =
123        private::EventHandler(private::NoOpEventHandler);
124    const MAX_VERSION: u32 = 10;
125
126    type Borrowed = WlTouchRef;
127    type Api = private::ProxyApi;
128    type NoOpEventHandler = private::EventHandler<private::NoOpEventHandler>;
129}
130
131// SAFETY: WlTouchRef is a transparent wrapper around UntypedBorrowedProxy
132unsafe impl UntypedBorrowedProxyWrapper for WlTouchRef {}
133
134// SAFETY: - The only invariant is that self.proxy has a compatible interface
135unsafe impl BorrowedProxy for WlTouchRef {
136    type Owned = WlTouch;
137}
138
139impl Deref for WlTouch {
140    type Target = WlTouchRef;
141
142    fn deref(&self) -> &Self::Target {
143        proxy::low_level::deref(self)
144    }
145}
146
147mod private {
148    pub struct ProxyApi;
149
150    #[allow(dead_code)]
151    pub struct EventHandler<H>(pub(super) H);
152
153    #[allow(dead_code)]
154    pub struct NoOpEventHandler;
155}
156
157impl Debug for WlTouch {
158    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
159        write!(f, "wl_touch#{}", self.proxy.id())
160    }
161}
162
163impl Debug for WlTouchRef {
164    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
165        write!(f, "wl_touch#{}", self.proxy.id())
166    }
167}
168
169impl PartialEq<WlTouchRef> for WlTouch {
170    fn eq(&self, other: &WlTouchRef) -> bool {
171        self.proxy == other.proxy
172    }
173}
174
175impl PartialEq<WlTouch> for WlTouchRef {
176    fn eq(&self, other: &WlTouch) -> bool {
177        self.proxy == other.proxy
178    }
179}
180
181#[allow(dead_code)]
182impl WlTouch {
183    /// Since when the release request is available.
184    #[allow(dead_code)]
185    pub const REQ__RELEASE__SINCE: u32 = 3;
186
187    /// release the touch object
188    #[inline]
189    pub fn release(&self) {
190        let mut args = [];
191        // SAFETY: - self.proxy has the interface INTERFACE
192        //         - 0 < INTERFACE.method_count = 1
193        //         - the request signature is ``
194        unsafe {
195            self.proxy.send_destructor(0, &mut args);
196        }
197    }
198}
199
200impl WlTouch {
201    /// Since when the down event is available.
202    #[allow(dead_code)]
203    pub const EVT__DOWN__SINCE: u32 = 1;
204
205    /// Since when the up event is available.
206    #[allow(dead_code)]
207    pub const EVT__UP__SINCE: u32 = 1;
208
209    /// Since when the motion event is available.
210    #[allow(dead_code)]
211    pub const EVT__MOTION__SINCE: u32 = 1;
212
213    /// Since when the frame event is available.
214    #[allow(dead_code)]
215    pub const EVT__FRAME__SINCE: u32 = 1;
216
217    /// Since when the cancel event is available.
218    #[allow(dead_code)]
219    pub const EVT__CANCEL__SINCE: u32 = 1;
220
221    /// Since when the shape event is available.
222    #[allow(dead_code)]
223    pub const EVT__SHAPE__SINCE: u32 = 6;
224
225    /// Since when the orientation event is available.
226    #[allow(dead_code)]
227    pub const EVT__ORIENTATION__SINCE: u32 = 6;
228}
229
230/// An event handler for [WlTouch] proxies.
231#[allow(dead_code)]
232pub trait WlTouchEventHandler {
233    /// touch down event and beginning of a touch sequence
234    ///
235    /// A new touch point has appeared on the surface. This touch point is
236    /// assigned a unique ID. Future events from this touch point reference
237    /// this ID. The ID ceases to be valid after a touch up event and may be
238    /// reused in the future.
239    ///
240    /// # Arguments
241    ///
242    /// - `serial`: serial number of the touch down event
243    /// - `time`: timestamp with millisecond granularity
244    /// - `surface`: surface touched
245    /// - `id`: the unique ID of this touch point
246    /// - `x`: surface-local x coordinate
247    /// - `y`: surface-local y coordinate
248    ///
249    /// All borrowed proxies passed to this function are guaranteed to be
250    /// immutable and non-null.
251    #[inline]
252    fn down(
253        &self,
254        _slf: &WlTouchRef,
255        serial: u32,
256        time: u32,
257        surface: Option<&WlSurfaceRef>,
258        id: i32,
259        x: Fixed,
260        y: Fixed,
261    ) {
262        let _ = serial;
263        let _ = time;
264        let _ = surface;
265        let _ = id;
266        let _ = x;
267        let _ = y;
268    }
269
270    /// end of a touch event sequence
271    ///
272    /// The touch point has disappeared. No further events will be sent for
273    /// this touch point and the touch point's ID is released and may be
274    /// reused in a future touch down event.
275    ///
276    /// # Arguments
277    ///
278    /// - `serial`: serial number of the touch up event
279    /// - `time`: timestamp with millisecond granularity
280    /// - `id`: the unique ID of this touch point
281    #[inline]
282    fn up(&self, _slf: &WlTouchRef, serial: u32, time: u32, id: i32) {
283        let _ = serial;
284        let _ = time;
285        let _ = id;
286    }
287
288    /// update of touch point coordinates
289    ///
290    /// A touch point has changed coordinates.
291    ///
292    /// # Arguments
293    ///
294    /// - `time`: timestamp with millisecond granularity
295    /// - `id`: the unique ID of this touch point
296    /// - `x`: surface-local x coordinate
297    /// - `y`: surface-local y coordinate
298    #[inline]
299    fn motion(&self, _slf: &WlTouchRef, time: u32, id: i32, x: Fixed, y: Fixed) {
300        let _ = time;
301        let _ = id;
302        let _ = x;
303        let _ = y;
304    }
305
306    /// end of touch frame event
307    ///
308    /// Indicates the end of a set of events that logically belong together.
309    /// A client is expected to accumulate the data in all events within the
310    /// frame before proceeding.
311    ///
312    /// A wl_touch.frame terminates at least one event but otherwise no
313    /// guarantee is provided about the set of events within a frame. A client
314    /// must assume that any state not updated in a frame is unchanged from the
315    /// previously known state.
316    #[inline]
317    fn frame(&self, _slf: &WlTouchRef) {}
318
319    /// touch session cancelled
320    ///
321    /// Sent if the compositor decides the touch stream is a global
322    /// gesture. No further events are sent to the clients from that
323    /// particular gesture. Touch cancellation applies to all touch points
324    /// currently active on this client's surface. The client is
325    /// responsible for finalizing the touch points, future touch points on
326    /// this surface may reuse the touch point ID.
327    ///
328    /// No frame event is required after the cancel event.
329    #[inline]
330    fn cancel(&self, _slf: &WlTouchRef) {}
331
332    /// update shape of touch point
333    ///
334    /// Sent when a touchpoint has changed its shape.
335    ///
336    /// This event does not occur on its own. It is sent before a
337    /// wl_touch.frame event and carries the new shape information for
338    /// any previously reported, or new touch points of that frame.
339    ///
340    /// Other events describing the touch point such as wl_touch.down,
341    /// wl_touch.motion or wl_touch.orientation may be sent within the
342    /// same wl_touch.frame. A client should treat these events as a single
343    /// logical touch point update. The order of wl_touch.shape,
344    /// wl_touch.orientation and wl_touch.motion is not guaranteed.
345    /// A wl_touch.down event is guaranteed to occur before the first
346    /// wl_touch.shape event for this touch ID but both events may occur within
347    /// the same wl_touch.frame.
348    ///
349    /// A touchpoint shape is approximated by an ellipse through the major and
350    /// minor axis length. The major axis length describes the longer diameter
351    /// of the ellipse, while the minor axis length describes the shorter
352    /// diameter. Major and minor are orthogonal and both are specified in
353    /// surface-local coordinates. The center of the ellipse is always at the
354    /// touchpoint location as reported by wl_touch.down or wl_touch.move.
355    ///
356    /// This event is only sent by the compositor if the touch device supports
357    /// shape reports. The client has to make reasonable assumptions about the
358    /// shape if it did not receive this event.
359    ///
360    /// # Arguments
361    ///
362    /// - `id`: the unique ID of this touch point
363    /// - `major`: length of the major axis in surface-local coordinates
364    /// - `minor`: length of the minor axis in surface-local coordinates
365    #[inline]
366    fn shape(&self, _slf: &WlTouchRef, id: i32, major: Fixed, minor: Fixed) {
367        let _ = id;
368        let _ = major;
369        let _ = minor;
370    }
371
372    /// update orientation of touch point
373    ///
374    /// Sent when a touchpoint has changed its orientation.
375    ///
376    /// This event does not occur on its own. It is sent before a
377    /// wl_touch.frame event and carries the new shape information for
378    /// any previously reported, or new touch points of that frame.
379    ///
380    /// Other events describing the touch point such as wl_touch.down,
381    /// wl_touch.motion or wl_touch.shape may be sent within the
382    /// same wl_touch.frame. A client should treat these events as a single
383    /// logical touch point update. The order of wl_touch.shape,
384    /// wl_touch.orientation and wl_touch.motion is not guaranteed.
385    /// A wl_touch.down event is guaranteed to occur before the first
386    /// wl_touch.orientation event for this touch ID but both events may occur
387    /// within the same wl_touch.frame.
388    ///
389    /// The orientation describes the clockwise angle of a touchpoint's major
390    /// axis to the positive surface y-axis and is normalized to the -180 to
391    /// +180 degree range. The granularity of orientation depends on the touch
392    /// device, some devices only support binary rotation values between 0 and
393    /// 90 degrees.
394    ///
395    /// This event is only sent by the compositor if the touch device supports
396    /// orientation reports.
397    ///
398    /// # Arguments
399    ///
400    /// - `id`: the unique ID of this touch point
401    /// - `orientation`: angle between major axis and positive surface y-axis in degrees
402    #[inline]
403    fn orientation(&self, _slf: &WlTouchRef, id: i32, orientation: Fixed) {
404        let _ = id;
405        let _ = orientation;
406    }
407}
408
409impl WlTouchEventHandler for private::NoOpEventHandler {}
410
411// SAFETY: INTERFACE is a valid wl_interface
412unsafe impl<H> EventHandler for private::EventHandler<H>
413where
414    H: WlTouchEventHandler,
415{
416    const WL_INTERFACE: &'static wl_interface = &INTERFACE;
417
418    #[allow(unused_variables)]
419    unsafe fn handle_event(
420        &self,
421        queue: &Queue,
422        slf: &UntypedBorrowedProxy,
423        opcode: u32,
424        args: *mut wl_argument,
425    ) {
426        // SAFETY: This function required that slf has the interface INTERFACE
427        let slf = unsafe { proxy::low_level::from_untyped_borrowed::<WlTouchRef>(slf) };
428        match opcode {
429            0 => {
430                // SAFETY: INTERFACE requires that there are 6 arguments
431                let args = unsafe { &*args.cast::<[wl_argument; 6]>() };
432                // SAFETY: - INTERFACE requires that args[0] contains a uint
433                let arg0 = unsafe { args[0].u };
434                // SAFETY: - INTERFACE requires that args[1] contains a uint
435                let arg1 = unsafe { args[1].u };
436                // SAFETY: - INTERFACE requires that args[2] contains an object
437                let arg2 = unsafe {
438                    if let Some(p) = NonNull::new(args[2].o.cast()) {
439                        Some(UntypedBorrowedProxy::new_immutable(queue.libwayland(), p))
440                    } else {
441                        None
442                    }
443                };
444                // SAFETY: - INTERFACE requires that the object has the interface WlSurface::WL_INTERFACE
445                let arg2 = arg2.as_ref().map(|arg2| unsafe {
446                    proxy::low_level::from_untyped_borrowed::<WlSurfaceRef>(arg2)
447                });
448                // SAFETY: - INTERFACE requires that args[3] contains an int
449                let arg3 = unsafe { args[3].i };
450                // SAFETY: - INTERFACE requires that args[4] contains a fixed
451                let arg4 = unsafe { Fixed::from_wire(args[4].f) };
452                // SAFETY: - INTERFACE requires that args[5] contains a fixed
453                let arg5 = unsafe { Fixed::from_wire(args[5].f) };
454                self.0.down(slf, arg0, arg1, arg2, arg3, arg4, arg5);
455            }
456            1 => {
457                // SAFETY: INTERFACE requires that there are 3 arguments
458                let args = unsafe { &*args.cast::<[wl_argument; 3]>() };
459                // SAFETY: - INTERFACE requires that args[0] contains a uint
460                let arg0 = unsafe { args[0].u };
461                // SAFETY: - INTERFACE requires that args[1] contains a uint
462                let arg1 = unsafe { args[1].u };
463                // SAFETY: - INTERFACE requires that args[2] contains an int
464                let arg2 = unsafe { args[2].i };
465                self.0.up(slf, arg0, arg1, arg2);
466            }
467            2 => {
468                // SAFETY: INTERFACE requires that there are 4 arguments
469                let args = unsafe { &*args.cast::<[wl_argument; 4]>() };
470                // SAFETY: - INTERFACE requires that args[0] contains a uint
471                let arg0 = unsafe { args[0].u };
472                // SAFETY: - INTERFACE requires that args[1] contains an int
473                let arg1 = unsafe { args[1].i };
474                // SAFETY: - INTERFACE requires that args[2] contains a fixed
475                let arg2 = unsafe { Fixed::from_wire(args[2].f) };
476                // SAFETY: - INTERFACE requires that args[3] contains a fixed
477                let arg3 = unsafe { Fixed::from_wire(args[3].f) };
478                self.0.motion(slf, arg0, arg1, arg2, arg3);
479            }
480            3 => {
481                self.0.frame(slf);
482            }
483            4 => {
484                self.0.cancel(slf);
485            }
486            5 => {
487                // SAFETY: INTERFACE requires that there are 3 arguments
488                let args = unsafe { &*args.cast::<[wl_argument; 3]>() };
489                // SAFETY: - INTERFACE requires that args[0] contains an int
490                let arg0 = unsafe { args[0].i };
491                // SAFETY: - INTERFACE requires that args[1] contains a fixed
492                let arg1 = unsafe { Fixed::from_wire(args[1].f) };
493                // SAFETY: - INTERFACE requires that args[2] contains a fixed
494                let arg2 = unsafe { Fixed::from_wire(args[2].f) };
495                self.0.shape(slf, arg0, arg1, arg2);
496            }
497            6 => {
498                // SAFETY: INTERFACE requires that there are 2 arguments
499                let args = unsafe { &*args.cast::<[wl_argument; 2]>() };
500                // SAFETY: - INTERFACE requires that args[0] contains an int
501                let arg0 = unsafe { args[0].i };
502                // SAFETY: - INTERFACE requires that args[1] contains a fixed
503                let arg1 = unsafe { Fixed::from_wire(args[1].f) };
504                self.0.orientation(slf, arg0, arg1);
505            }
506            _ => {
507                invalid_opcode("wl_touch", opcode);
508            }
509        }
510    }
511}
512
513impl<H> CreateEventHandler<H> for private::ProxyApi
514where
515    H: WlTouchEventHandler,
516{
517    type EventHandler = private::EventHandler<H>;
518
519    #[inline]
520    fn create_event_handler(handler: H) -> Self::EventHandler {
521        private::EventHandler(handler)
522    }
523}
524
525/// Functional event handlers.
526pub mod event_handlers {
527    use super::*;
528
529    /// Event handler for down events.
530    pub struct Down<F>(F);
531    impl<F> WlTouchEventHandler for Down<F>
532    where
533        F: Fn(&WlTouchRef, u32, u32, Option<&WlSurfaceRef>, i32, Fixed, Fixed),
534    {
535        #[inline]
536        fn down(
537            &self,
538            _slf: &WlTouchRef,
539            serial: u32,
540            time: u32,
541            surface: Option<&WlSurfaceRef>,
542            id: i32,
543            x: Fixed,
544            y: Fixed,
545        ) {
546            self.0(_slf, serial, time, surface, id, x, y)
547        }
548    }
549
550    /// Event handler for up events.
551    pub struct Up<F>(F);
552    impl<F> WlTouchEventHandler for Up<F>
553    where
554        F: Fn(&WlTouchRef, u32, u32, i32),
555    {
556        #[inline]
557        fn up(&self, _slf: &WlTouchRef, serial: u32, time: u32, id: i32) {
558            self.0(_slf, serial, time, id)
559        }
560    }
561
562    /// Event handler for motion events.
563    pub struct Motion<F>(F);
564    impl<F> WlTouchEventHandler for Motion<F>
565    where
566        F: Fn(&WlTouchRef, u32, i32, Fixed, Fixed),
567    {
568        #[inline]
569        fn motion(&self, _slf: &WlTouchRef, time: u32, id: i32, x: Fixed, y: Fixed) {
570            self.0(_slf, time, id, x, y)
571        }
572    }
573
574    /// Event handler for frame events.
575    pub struct Frame<F>(F);
576    impl<F> WlTouchEventHandler for Frame<F>
577    where
578        F: Fn(&WlTouchRef),
579    {
580        #[inline]
581        fn frame(&self, _slf: &WlTouchRef) {
582            self.0(_slf)
583        }
584    }
585
586    /// Event handler for cancel events.
587    pub struct Cancel<F>(F);
588    impl<F> WlTouchEventHandler for Cancel<F>
589    where
590        F: Fn(&WlTouchRef),
591    {
592        #[inline]
593        fn cancel(&self, _slf: &WlTouchRef) {
594            self.0(_slf)
595        }
596    }
597
598    /// Event handler for shape events.
599    pub struct Shape<F>(F);
600    impl<F> WlTouchEventHandler for Shape<F>
601    where
602        F: Fn(&WlTouchRef, i32, Fixed, Fixed),
603    {
604        #[inline]
605        fn shape(&self, _slf: &WlTouchRef, id: i32, major: Fixed, minor: Fixed) {
606            self.0(_slf, id, major, minor)
607        }
608    }
609
610    /// Event handler for orientation events.
611    pub struct Orientation<F>(F);
612    impl<F> WlTouchEventHandler for Orientation<F>
613    where
614        F: Fn(&WlTouchRef, i32, Fixed),
615    {
616        #[inline]
617        fn orientation(&self, _slf: &WlTouchRef, id: i32, orientation: Fixed) {
618            self.0(_slf, id, orientation)
619        }
620    }
621
622    impl WlTouch {
623        /// Creates an event handler for down events.
624        ///
625        /// The event handler ignores all other events.
626        #[allow(dead_code)]
627        pub fn on_down<F>(f: F) -> Down<F>
628        where
629            F: Fn(&WlTouchRef, u32, u32, Option<&WlSurfaceRef>, i32, Fixed, Fixed),
630        {
631            Down(f)
632        }
633
634        /// Creates an event handler for up events.
635        ///
636        /// The event handler ignores all other events.
637        #[allow(dead_code)]
638        pub fn on_up<F>(f: F) -> Up<F>
639        where
640            F: Fn(&WlTouchRef, u32, u32, i32),
641        {
642            Up(f)
643        }
644
645        /// Creates an event handler for motion events.
646        ///
647        /// The event handler ignores all other events.
648        #[allow(dead_code)]
649        pub fn on_motion<F>(f: F) -> Motion<F>
650        where
651            F: Fn(&WlTouchRef, u32, i32, Fixed, Fixed),
652        {
653            Motion(f)
654        }
655
656        /// Creates an event handler for frame events.
657        ///
658        /// The event handler ignores all other events.
659        #[allow(dead_code)]
660        pub fn on_frame<F>(f: F) -> Frame<F>
661        where
662            F: Fn(&WlTouchRef),
663        {
664            Frame(f)
665        }
666
667        /// Creates an event handler for cancel events.
668        ///
669        /// The event handler ignores all other events.
670        #[allow(dead_code)]
671        pub fn on_cancel<F>(f: F) -> Cancel<F>
672        where
673            F: Fn(&WlTouchRef),
674        {
675            Cancel(f)
676        }
677
678        /// Creates an event handler for shape events.
679        ///
680        /// The event handler ignores all other events.
681        #[allow(dead_code)]
682        pub fn on_shape<F>(f: F) -> Shape<F>
683        where
684            F: Fn(&WlTouchRef, i32, Fixed, Fixed),
685        {
686            Shape(f)
687        }
688
689        /// Creates an event handler for orientation events.
690        ///
691        /// The event handler ignores all other events.
692        #[allow(dead_code)]
693        pub fn on_orientation<F>(f: F) -> Orientation<F>
694        where
695            F: Fn(&WlTouchRef, i32, Fixed),
696        {
697            Orientation(f)
698        }
699    }
700}