tawasuyu

tawasuyu/mirada

Sovereign tiling Wayland compositor + window manager in Rust, on Llimphi.

Rust 50Markdown 30TOML 211282 Definiciones

⎇ main vendor/smithay/src/backend/libinput/mod.rs Rust · 891 líneas · 30.6 KB Historia Quién tocó qué crudo

chore: refresco desde el monorepo (pin tawasuyu.git v0.2.0) a91da3fea · Sergio ·

1//! Implementation of input backend trait for types provided by `libinput`
2
3use crate::backend::input::{
4    self as backend, Axis, AxisRelativeDirection, AxisSource, InputBackend, InputEvent,
5};
6#[cfg(feature = "backend_session")]
7use crate::backend::session::{AsErrno, Session};
8use input as libinput;
9use input::event;
10
11use std::{
12    io,
13    os::unix::io::{AsFd, BorrowedFd},
14    path::PathBuf,
15};
16#[cfg(feature = "backend_session")]
17use std::{os::unix::io::OwnedFd, path::Path};
18
19use calloop::{EventSource, Interest, Mode, Poll, PostAction, Readiness, Token, TokenFactory};
20
21use tracing::{debug_span, info, trace};
22
23mod tablet;
24
25/// Libinput based [`InputBackend`].
26///
27/// Tracks input of all devices given manually or via a udev seat to a provided libinput
28/// context.
29#[derive(Debug)]
30pub struct LibinputInputBackend {
31    context: libinput::Libinput,
32    token: Option<Token>,
33    span: tracing::Span,
34}
35
36impl LibinputInputBackend {
37    /// Initialize a new [`LibinputInputBackend`] from a given already initialized
38    /// [libinput context](libinput::Libinput).
39    pub fn new(context: libinput::Libinput) -> Self {
40        let span = debug_span!("backend_libinput");
41        let _guard = span.enter();
42
43        info!("Initializing a libinput backend");
44
45        drop(_guard);
46        LibinputInputBackend {
47            context,
48            token: None,
49            span,
50        }
51    }
52
53    /// Returns a reference to the underlying libinput context
54    pub fn context(&self) -> &libinput::Libinput {
55        &self.context
56    }
57}
58
59impl backend::Device for libinput::Device {
60    fn id(&self) -> String {
61        self.sysname().into()
62    }
63
64    fn name(&self) -> String {
65        self.name().into()
66    }
67
68    fn has_capability(&self, capability: backend::DeviceCapability) -> bool {
69        libinput::Device::has_capability(self, capability.into())
70    }
71
72    fn usb_id(&self) -> Option<(u32, u32)> {
73        Some((
74            libinput::Device::id_product(self),
75            libinput::Device::id_vendor(self),
76        ))
77    }
78
79    fn syspath(&self) -> Option<PathBuf> {
80        #[cfg(feature = "udev")]
81        return unsafe { libinput::Device::udev_device(self) }.map(|d| d.syspath().to_owned());
82
83        #[cfg(not(feature = "udev"))]
84        None
85    }
86}
87
88impl From<backend::DeviceCapability> for libinput::DeviceCapability {
89    #[inline]
90    fn from(other: backend::DeviceCapability) -> libinput::DeviceCapability {
91        match other {
92            backend::DeviceCapability::Gesture => libinput::DeviceCapability::Gesture,
93            backend::DeviceCapability::Keyboard => libinput::DeviceCapability::Keyboard,
94            backend::DeviceCapability::Pointer => libinput::DeviceCapability::Pointer,
95            backend::DeviceCapability::Switch => libinput::DeviceCapability::Switch,
96            backend::DeviceCapability::TabletPad => libinput::DeviceCapability::TabletPad,
97            backend::DeviceCapability::TabletTool => libinput::DeviceCapability::TabletTool,
98            backend::DeviceCapability::Touch => libinput::DeviceCapability::Touch,
99        }
100    }
101}
102
103impl backend::Event<LibinputInputBackend> for event::keyboard::KeyboardKeyEvent {
104    fn time(&self) -> u64 {
105        event::keyboard::KeyboardEventTrait::time_usec(self)
106    }
107
108    fn device(&self) -> libinput::Device {
109        event::EventTrait::device(self)
110    }
111}
112
113impl backend::KeyboardKeyEvent<LibinputInputBackend> for event::keyboard::KeyboardKeyEvent {
114    fn key_code(&self) -> backend::Keycode {
115        use input::event::keyboard::KeyboardEventTrait;
116        (self.key() + 8).into()
117    }
118
119    fn state(&self) -> backend::KeyState {
120        use input::event::keyboard::KeyboardEventTrait;
121        self.key_state().into()
122    }
123
124    fn count(&self) -> u32 {
125        self.seat_key_count()
126    }
127}
128
129impl backend::Event<LibinputInputBackend> for event::switch::SwitchToggleEvent {
130    fn time(&self) -> u64 {
131        event::switch::SwitchEventTrait::time_usec(self)
132    }
133
134    fn device(&self) -> <LibinputInputBackend as InputBackend>::Device {
135        event::EventTrait::device(self)
136    }
137}
138
139impl backend::SwitchToggleEvent<LibinputInputBackend> for event::switch::SwitchToggleEvent {
140    fn switch(&self) -> Option<backend::Switch> {
141        event::switch::SwitchToggleEvent::switch(self).and_then(|switch| {
142            Some(match switch {
143                event::switch::Switch::Lid => backend::Switch::Lid,
144                event::switch::Switch::TabletMode => backend::Switch::TabletMode,
145                _ => return None,
146            })
147        })
148    }
149
150    fn state(&self) -> backend::SwitchState {
151        match event::switch::SwitchToggleEvent::switch_state(self) {
152            event::switch::SwitchState::Off => backend::SwitchState::Off,
153            event::switch::SwitchState::On => backend::SwitchState::On,
154        }
155    }
156}
157
158/// Generic pointer scroll event from libinput
159#[derive(Debug, PartialEq, Eq, Hash)]
160pub enum PointerScrollAxis {
161    /// Scroll event from pointer wheel
162    Wheel(event::pointer::PointerScrollWheelEvent),
163    /// Scroll event from pointer finger
164    Finger(event::pointer::PointerScrollFingerEvent),
165    /// Continuous scroll event
166    Continuous(event::pointer::PointerScrollContinuousEvent),
167}
168
169impl PointerScrollAxis {
170    fn has_axis(&self, axis: event::pointer::Axis) -> bool {
171        use input::event::pointer::PointerScrollEvent;
172        match self {
173            Self::Wheel(evt) => evt.has_axis(axis),
174            Self::Finger(evt) => evt.has_axis(axis),
175            Self::Continuous(evt) => evt.has_axis(axis),
176        }
177    }
178}
179
180impl backend::Event<LibinputInputBackend> for PointerScrollAxis {
181    fn time(&self) -> u64 {
182        match self {
183            Self::Wheel(evt) => event::pointer::PointerEventTrait::time_usec(evt),
184            Self::Finger(evt) => event::pointer::PointerEventTrait::time_usec(evt),
185            Self::Continuous(evt) => event::pointer::PointerEventTrait::time_usec(evt),
186        }
187    }
188
189    fn device(&self) -> libinput::Device {
190        match self {
191            Self::Wheel(evt) => event::EventTrait::device(evt),
192            Self::Finger(evt) => event::EventTrait::device(evt),
193            Self::Continuous(evt) => event::EventTrait::device(evt),
194        }
195    }
196}
197
198impl backend::PointerAxisEvent<LibinputInputBackend> for PointerScrollAxis {
199    fn amount(&self, axis: Axis) -> Option<f64> {
200        use input::event::pointer::PointerScrollEvent;
201        let axis = axis.into();
202        if self.has_axis(axis) {
203            Some(match self {
204                Self::Wheel(evt) => evt.scroll_value(axis),
205                Self::Finger(evt) => evt.scroll_value(axis),
206                Self::Continuous(evt) => evt.scroll_value(axis),
207            })
208        } else {
209            None
210        }
211    }
212
213    fn amount_v120(&self, axis: Axis) -> Option<f64> {
214        let axis = axis.into();
215        if self.has_axis(axis) {
216            match self {
217                Self::Wheel(evt) => Some(evt.scroll_value_v120(axis)),
218                Self::Finger(_evt) => None,
219                Self::Continuous(_evt) => None,
220            }
221        } else {
222            None
223        }
224    }
225
226    fn source(&self) -> AxisSource {
227        match self {
228            Self::Wheel(_) => AxisSource::Wheel,
229            Self::Finger(_) => AxisSource::Finger,
230            Self::Continuous(_) => AxisSource::Continuous,
231        }
232    }
233
234    fn relative_direction(&self, _axis: Axis) -> backend::AxisRelativeDirection {
235        let device = backend::Event::<LibinputInputBackend>::device(self);
236        if device.config_scroll_natural_scroll_enabled() {
237            AxisRelativeDirection::Inverted
238        } else {
239            AxisRelativeDirection::Identical
240        }
241    }
242}
243
244impl backend::Event<LibinputInputBackend> for event::pointer::PointerButtonEvent {
245    fn time(&self) -> u64 {
246        event::pointer::PointerEventTrait::time_usec(self)
247    }
248
249    fn device(&self) -> libinput::Device {
250        event::EventTrait::device(self)
251    }
252}
253
254impl backend::PointerButtonEvent<LibinputInputBackend> for event::pointer::PointerButtonEvent {
255    fn button_code(&self) -> u32 {
256        self.button()
257    }
258
259    fn state(&self) -> backend::ButtonState {
260        self.button_state().into()
261    }
262}
263
264impl backend::Event<LibinputInputBackend> for event::pointer::PointerMotionEvent {
265    fn time(&self) -> u64 {
266        event::pointer::PointerEventTrait::time_usec(self)
267    }
268
269    fn device(&self) -> libinput::Device {
270        event::EventTrait::device(self)
271    }
272}
273
274impl backend::PointerMotionEvent<LibinputInputBackend> for event::pointer::PointerMotionEvent {
275    fn delta_x(&self) -> f64 {
276        self.dx()
277    }
278
279    fn delta_y(&self) -> f64 {
280        self.dy()
281    }
282
283    fn delta_x_unaccel(&self) -> f64 {
284        self.dx_unaccelerated()
285    }
286
287    fn delta_y_unaccel(&self) -> f64 {
288        self.dy_unaccelerated()
289    }
290}
291
292impl backend::Event<LibinputInputBackend> for event::pointer::PointerMotionAbsoluteEvent {
293    fn time(&self) -> u64 {
294        event::pointer::PointerEventTrait::time_usec(self)
295    }
296
297    fn device(&self) -> libinput::Device {
298        event::EventTrait::device(self)
299    }
300}
301
302impl backend::PointerMotionAbsoluteEvent<LibinputInputBackend>
303    for event::pointer::PointerMotionAbsoluteEvent
304{
305}
306
307impl backend::AbsolutePositionEvent<LibinputInputBackend> for event::pointer::PointerMotionAbsoluteEvent {
308    fn x(&self) -> f64 {
309        self.absolute_x()
310    }
311
312    fn y(&self) -> f64 {
313        self.absolute_y()
314    }
315
316    fn x_transformed(&self, width: i32) -> f64 {
317        self.absolute_x_transformed(width as u32)
318    }
319
320    fn y_transformed(&self, height: i32) -> f64 {
321        self.absolute_y_transformed(height as u32)
322    }
323}
324
325impl<T> backend::GestureBeginEvent<LibinputInputBackend> for T
326where
327    T: event::gesture::GestureEventTrait + backend::Event<LibinputInputBackend>,
328{
329    fn fingers(&self) -> u32 {
330        self.finger_count() as u32
331    }
332}
333
334impl<T> backend::GestureEndEvent<LibinputInputBackend> for T
335where
336    T: event::gesture::GestureEndEvent + backend::Event<LibinputInputBackend>,
337{
338    fn cancelled(&self) -> bool {
339        self.cancelled()
340    }
341}
342
343impl backend::Event<LibinputInputBackend> for event::gesture::GestureSwipeBeginEvent {
344    fn time(&self) -> u64 {
345        event::gesture::GestureEventTrait::time_usec(self)
346    }
347
348    fn device(&self) -> libinput::Device {
349        event::EventTrait::device(self)
350    }
351}
352
353impl backend::GestureSwipeBeginEvent<LibinputInputBackend> for event::gesture::GestureSwipeBeginEvent {}
354
355impl backend::Event<LibinputInputBackend> for event::gesture::GestureSwipeUpdateEvent {
356    fn time(&self) -> u64 {
357        event::gesture::GestureEventTrait::time_usec(self)
358    }
359
360    fn device(&self) -> libinput::Device {
361        event::EventTrait::device(self)
362    }
363}
364
365impl backend::GestureSwipeUpdateEvent<LibinputInputBackend> for event::gesture::GestureSwipeUpdateEvent {
366    fn delta_x(&self) -> f64 {
367        event::gesture::GestureEventCoordinates::dx(self)
368    }
369
370    fn delta_y(&self) -> f64 {
371        event::gesture::GestureEventCoordinates::dy(self)
372    }
373}
374
375impl backend::Event<LibinputInputBackend> for event::gesture::GestureSwipeEndEvent {
376    fn time(&self) -> u64 {
377        event::gesture::GestureEventTrait::time_usec(self)
378    }
379
380    fn device(&self) -> libinput::Device {
381        event::EventTrait::device(self)
382    }
383}
384
385impl backend::GestureSwipeEndEvent<LibinputInputBackend> for event::gesture::GestureSwipeEndEvent {}
386
387impl backend::Event<LibinputInputBackend> for event::gesture::GesturePinchBeginEvent {
388    fn time(&self) -> u64 {
389        event::gesture::GestureEventTrait::time_usec(self)
390    }
391
392    fn device(&self) -> libinput::Device {
393        event::EventTrait::device(self)
394    }
395}
396
397impl backend::GesturePinchBeginEvent<LibinputInputBackend> for event::gesture::GesturePinchBeginEvent {}
398
399impl backend::Event<LibinputInputBackend> for event::gesture::GesturePinchUpdateEvent {
400    fn time(&self) -> u64 {
401        event::gesture::GestureEventTrait::time_usec(self)
402    }
403
404    fn device(&self) -> libinput::Device {
405        event::EventTrait::device(self)
406    }
407}
408
409impl backend::GesturePinchUpdateEvent<LibinputInputBackend> for event::gesture::GesturePinchUpdateEvent {
410    fn delta_x(&self) -> f64 {
411        event::gesture::GestureEventCoordinates::dx(self)
412    }
413
414    fn delta_y(&self) -> f64 {
415        event::gesture::GestureEventCoordinates::dy(self)
416    }
417
418    fn scale(&self) -> f64 {
419        event::gesture::GesturePinchEventTrait::scale(self)
420    }
421
422    fn rotation(&self) -> f64 {
423        self.angle_delta()
424    }
425}
426
427impl backend::Event<LibinputInputBackend> for event::gesture::GesturePinchEndEvent {
428    fn time(&self) -> u64 {
429        event::gesture::GestureEventTrait::time_usec(self)
430    }
431
432    fn device(&self) -> libinput::Device {
433        event::EventTrait::device(self)
434    }
435}
436
437impl backend::GesturePinchEndEvent<LibinputInputBackend> for event::gesture::GesturePinchEndEvent {}
438
439impl backend::Event<LibinputInputBackend> for event::gesture::GestureHoldBeginEvent {
440    fn time(&self) -> u64 {
441        event::gesture::GestureEventTrait::time_usec(self)
442    }
443
444    fn device(&self) -> libinput::Device {
445        event::EventTrait::device(self)
446    }
447}
448
449impl backend::GestureHoldBeginEvent<LibinputInputBackend> for event::gesture::GestureHoldBeginEvent {}
450
451impl backend::Event<LibinputInputBackend> for event::gesture::GestureHoldEndEvent {
452    fn time(&self) -> u64 {
453        event::gesture::GestureEventTrait::time_usec(self)
454    }
455
456    fn device(&self) -> libinput::Device {
457        event::EventTrait::device(self)
458    }
459}
460
461impl backend::GestureHoldEndEvent<LibinputInputBackend> for event::gesture::GestureHoldEndEvent {}
462
463impl backend::Event<LibinputInputBackend> for event::touch::TouchDownEvent {
464    fn time(&self) -> u64 {
465        event::touch::TouchEventTrait::time_usec(self)
466    }
467
468    fn device(&self) -> libinput::Device {
469        event::EventTrait::device(self)
470    }
471}
472
473impl backend::TouchDownEvent<LibinputInputBackend> for event::touch::TouchDownEvent {}
474
475impl backend::TouchEvent<LibinputInputBackend> for event::touch::TouchDownEvent {
476    fn slot(&self) -> backend::TouchSlot {
477        event::touch::TouchEventSlot::slot(self).into()
478    }
479}
480
481impl backend::AbsolutePositionEvent<LibinputInputBackend> for event::touch::TouchDownEvent {
482    fn x(&self) -> f64 {
483        event::touch::TouchEventPosition::x(self)
484    }
485
486    fn y(&self) -> f64 {
487        event::touch::TouchEventPosition::y(self)
488    }
489
490    fn x_transformed(&self, width: i32) -> f64 {
491        event::touch::TouchEventPosition::x_transformed(self, width as u32)
492    }
493
494    fn y_transformed(&self, height: i32) -> f64 {
495        event::touch::TouchEventPosition::y_transformed(self, height as u32)
496    }
497}
498
499impl backend::Event<LibinputInputBackend> for event::touch::TouchMotionEvent {
500    fn time(&self) -> u64 {
501        event::touch::TouchEventTrait::time_usec(self)
502    }
503
504    fn device(&self) -> libinput::Device {
505        event::EventTrait::device(self)
506    }
507}
508
509impl backend::TouchMotionEvent<LibinputInputBackend> for event::touch::TouchMotionEvent {}
510
511impl backend::TouchEvent<LibinputInputBackend> for event::touch::TouchMotionEvent {
512    fn slot(&self) -> backend::TouchSlot {
513        event::touch::TouchEventSlot::slot(self).into()
514    }
515}
516
517impl backend::AbsolutePositionEvent<LibinputInputBackend> for event::touch::TouchMotionEvent {
518    fn x(&self) -> f64 {
519        event::touch::TouchEventPosition::x(self)
520    }
521
522    fn y(&self) -> f64 {
523        event::touch::TouchEventPosition::y(self)
524    }
525
526    fn x_transformed(&self, width: i32) -> f64 {
527        event::touch::TouchEventPosition::x_transformed(self, width as u32)
528    }
529
530    fn y_transformed(&self, height: i32) -> f64 {
531        event::touch::TouchEventPosition::y_transformed(self, height as u32)
532    }
533}
534
535impl backend::Event<LibinputInputBackend> for event::touch::TouchUpEvent {
536    fn time(&self) -> u64 {
537        event::touch::TouchEventTrait::time_usec(self)
538    }
539
540    fn device(&self) -> libinput::Device {
541        event::EventTrait::device(self)
542    }
543}
544
545impl backend::TouchUpEvent<LibinputInputBackend> for event::touch::TouchUpEvent {}
546
547impl backend::TouchEvent<LibinputInputBackend> for event::touch::TouchUpEvent {
548    fn slot(&self) -> backend::TouchSlot {
549        event::touch::TouchEventSlot::slot(self).into()
550    }
551}
552
553impl backend::Event<LibinputInputBackend> for event::touch::TouchCancelEvent {
554    fn time(&self) -> u64 {
555        event::touch::TouchEventTrait::time_usec(self)
556    }
557
558    fn device(&self) -> libinput::Device {
559        event::EventTrait::device(self)
560    }
561}
562
563impl backend::TouchCancelEvent<LibinputInputBackend> for event::touch::TouchCancelEvent {}
564
565impl backend::TouchEvent<LibinputInputBackend> for event::touch::TouchCancelEvent {
566    fn slot(&self) -> backend::TouchSlot {
567        event::touch::TouchEventSlot::slot(self).into()
568    }
569}
570
571impl backend::Event<LibinputInputBackend> for event::touch::TouchFrameEvent {
572    fn time(&self) -> u64 {
573        event::touch::TouchEventTrait::time_usec(self)
574    }
575
576    fn device(&self) -> libinput::Device {
577        event::EventTrait::device(self)
578    }
579}
580
581impl backend::TouchFrameEvent<LibinputInputBackend> for event::touch::TouchFrameEvent {}
582
583impl InputBackend for LibinputInputBackend {
584    type Device = libinput::Device;
585    type KeyboardKeyEvent = event::keyboard::KeyboardKeyEvent;
586    type PointerAxisEvent = PointerScrollAxis;
587    type PointerButtonEvent = event::pointer::PointerButtonEvent;
588    type PointerMotionEvent = event::pointer::PointerMotionEvent;
589    type PointerMotionAbsoluteEvent = event::pointer::PointerMotionAbsoluteEvent;
590
591    type GestureSwipeBeginEvent = event::gesture::GestureSwipeBeginEvent;
592    type GestureSwipeUpdateEvent = event::gesture::GestureSwipeUpdateEvent;
593    type GestureSwipeEndEvent = event::gesture::GestureSwipeEndEvent;
594    type GesturePinchBeginEvent = event::gesture::GesturePinchBeginEvent;
595    type GesturePinchUpdateEvent = event::gesture::GesturePinchUpdateEvent;
596    type GesturePinchEndEvent = event::gesture::GesturePinchEndEvent;
597    type GestureHoldBeginEvent = event::gesture::GestureHoldBeginEvent;
598    type GestureHoldEndEvent = event::gesture::GestureHoldEndEvent;
599
600    type TouchDownEvent = event::touch::TouchDownEvent;
601    type TouchUpEvent = event::touch::TouchUpEvent;
602    type TouchMotionEvent = event::touch::TouchMotionEvent;
603    type TouchCancelEvent = event::touch::TouchCancelEvent;
604    type TouchFrameEvent = event::touch::TouchFrameEvent;
605    type TabletToolAxisEvent = event::tablet_tool::TabletToolAxisEvent;
606    type TabletToolProximityEvent = event::tablet_tool::TabletToolProximityEvent;
607    type TabletToolTipEvent = event::tablet_tool::TabletToolTipEvent;
608    type TabletToolButtonEvent = event::tablet_tool::TabletToolButtonEvent;
609
610    type SwitchToggleEvent = event::switch::SwitchToggleEvent;
611
612    type SpecialEvent = backend::UnusedEvent;
613}
614
615impl From<event::keyboard::KeyState> for backend::KeyState {
616    #[inline]
617    fn from(libinput: event::keyboard::KeyState) -> Self {
618        match libinput {
619            event::keyboard::KeyState::Pressed => backend::KeyState::Pressed,
620            event::keyboard::KeyState::Released => backend::KeyState::Released,
621        }
622    }
623}
624
625impl From<event::pointer::Axis> for backend::Axis {
626    #[inline]
627    fn from(libinput: event::pointer::Axis) -> Self {
628        match libinput {
629            event::pointer::Axis::Vertical => backend::Axis::Vertical,
630            event::pointer::Axis::Horizontal => backend::Axis::Horizontal,
631        }
632    }
633}
634
635impl From<backend::Axis> for event::pointer::Axis {
636    #[inline]
637    fn from(axis: backend::Axis) -> Self {
638        match axis {
639            backend::Axis::Vertical => event::pointer::Axis::Vertical,
640            backend::Axis::Horizontal => event::pointer::Axis::Horizontal,
641        }
642    }
643}
644
645impl From<event::pointer::ButtonState> for backend::ButtonState {
646    #[inline]
647    fn from(libinput: event::pointer::ButtonState) -> Self {
648        match libinput {
649            event::pointer::ButtonState::Pressed => backend::ButtonState::Pressed,
650            event::pointer::ButtonState::Released => backend::ButtonState::Released,
651        }
652    }
653}
654
655impl From<crate::input::keyboard::LedState> for libinput::Led {
656    #[inline]
657    fn from(value: crate::input::keyboard::LedState) -> Self {
658        let mut leds = libinput::Led::empty();
659        if value.num.unwrap_or_default() {
660            leds |= libinput::Led::NUMLOCK;
661        }
662        if value.caps.unwrap_or_default() {
663            leds |= libinput::Led::CAPSLOCK;
664        }
665        if value.scroll.unwrap_or_default() {
666            leds |= libinput::Led::SCROLLLOCK;
667        }
668        leds
669    }
670}
671
672/// Wrapper for types implementing the [`Session`] trait to provide
673/// a [`libinput::LibinputInterface`] implementation.
674#[cfg(feature = "backend_session")]
675#[derive(Debug)]
676pub struct LibinputSessionInterface<S: Session>(S);
677
678#[cfg(feature = "backend_session")]
679impl<S: Session> From<S> for LibinputSessionInterface<S> {
680    #[inline]
681    fn from(session: S) -> LibinputSessionInterface<S> {
682        LibinputSessionInterface(session)
683    }
684}
685
686#[cfg(feature = "backend_session")]
687impl<S: Session> libinput::LibinputInterface for LibinputSessionInterface<S> {
688    fn open_restricted(&mut self, path: &Path, flags: i32) -> Result<OwnedFd, i32> {
689        use rustix::fs::OFlags;
690        self.0
691            .open(path, OFlags::from_bits_truncate(flags as u32))
692            .map_err(|err| err.as_errno().unwrap_or(1 /*Use EPERM by default*/))
693    }
694
695    fn close_restricted(&mut self, fd: OwnedFd) {
696        let _ = self.0.close(fd);
697    }
698}
699
700impl AsFd for LibinputInputBackend {
701    #[inline]
702    fn as_fd(&self) -> BorrowedFd<'_> {
703        self.context.as_fd()
704    }
705}
706
707impl EventSource for LibinputInputBackend {
708    type Event = InputEvent<LibinputInputBackend>;
709    type Metadata = ();
710    type Ret = ();
711    type Error = io::Error;
712
713    #[profiling::function]
714    fn process_events<F>(&mut self, _: Readiness, token: Token, mut callback: F) -> io::Result<PostAction>
715    where
716        F: FnMut(Self::Event, &mut ()) -> Self::Ret,
717    {
718        if Some(token) == self.token {
719            let _guard = self.span.enter();
720            self.context.dispatch()?;
721
722            for event in &mut self.context {
723                match event {
724                    libinput::Event::Device(device_event) => match device_event {
725                        event::DeviceEvent::Added(device_added_event) => {
726                            let added = event::EventTrait::device(&device_added_event);
727
728                            info!("New device {:?}", added.sysname(),);
729
730                            callback(InputEvent::DeviceAdded { device: added }, &mut ());
731                        }
732                        event::DeviceEvent::Removed(device_removed_event) => {
733                            let removed = event::EventTrait::device(&device_removed_event);
734
735                            info!("Removed device {:?}", removed.sysname(),);
736
737                            callback(InputEvent::DeviceRemoved { device: removed }, &mut ());
738                        }
739                        _ => {
740                            trace!("Unknown libinput device event");
741                        }
742                    },
743                    libinput::Event::Touch(touch_event) => match touch_event {
744                        event::TouchEvent::Down(down_event) => {
745                            callback(InputEvent::TouchDown { event: down_event }, &mut ());
746                        }
747                        event::TouchEvent::Motion(motion_event) => {
748                            callback(InputEvent::TouchMotion { event: motion_event }, &mut ());
749                        }
750                        event::TouchEvent::Up(up_event) => {
751                            callback(InputEvent::TouchUp { event: up_event }, &mut ());
752                        }
753                        event::TouchEvent::Cancel(cancel_event) => {
754                            callback(InputEvent::TouchCancel { event: cancel_event }, &mut ());
755                        }
756                        event::TouchEvent::Frame(frame_event) => {
757                            callback(InputEvent::TouchFrame { event: frame_event }, &mut ());
758                        }
759                        _ => {
760                            trace!("Unknown libinput touch event");
761                        }
762                    },
763                    libinput::Event::Keyboard(keyboard_event) => match keyboard_event {
764                        event::KeyboardEvent::Key(key_event) => {
765                            callback(InputEvent::Keyboard { event: key_event }, &mut ());
766                        }
767                        _ => {
768                            trace!("Unknown libinput keyboard event");
769                        }
770                    },
771                    libinput::Event::Pointer(pointer_event) => match pointer_event {
772                        event::PointerEvent::Motion(motion_event) => {
773                            callback(InputEvent::PointerMotion { event: motion_event }, &mut ());
774                        }
775                        event::PointerEvent::MotionAbsolute(motion_abs_event) => {
776                            callback(
777                                InputEvent::PointerMotionAbsolute {
778                                    event: motion_abs_event,
779                                },
780                                &mut (),
781                            );
782                        }
783                        event::PointerEvent::ScrollWheel(scroll_event) => {
784                            callback(
785                                InputEvent::PointerAxis {
786                                    event: PointerScrollAxis::Wheel(scroll_event),
787                                },
788                                &mut (),
789                            );
790                        }
791                        event::PointerEvent::ScrollFinger(scroll_event) => {
792                            callback(
793                                InputEvent::PointerAxis {
794                                    event: PointerScrollAxis::Finger(scroll_event),
795                                },
796                                &mut (),
797                            );
798                        }
799                        event::PointerEvent::ScrollContinuous(scroll_event) => {
800                            callback(
801                                InputEvent::PointerAxis {
802                                    event: PointerScrollAxis::Continuous(scroll_event),
803                                },
804                                &mut (),
805                            );
806                        }
807                        event::PointerEvent::Button(button_event) => {
808                            callback(InputEvent::PointerButton { event: button_event }, &mut ());
809                        }
810                        _ => {
811                            trace!("Unknown libinput pointer event");
812                        }
813                    },
814                    libinput::Event::Gesture(gesture_event) => match gesture_event {
815                        event::GestureEvent::Swipe(event::gesture::GestureSwipeEvent::Begin(event)) => {
816                            callback(InputEvent::GestureSwipeBegin { event }, &mut ());
817                        }
818                        event::GestureEvent::Swipe(event::gesture::GestureSwipeEvent::Update(event)) => {
819                            callback(InputEvent::GestureSwipeUpdate { event }, &mut ());
820                        }
821                        event::GestureEvent::Swipe(event::gesture::GestureSwipeEvent::End(event)) => {
822                            callback(InputEvent::GestureSwipeEnd { event }, &mut ());
823                        }
824                        event::GestureEvent::Pinch(event::gesture::GesturePinchEvent::Begin(event)) => {
825                            callback(InputEvent::GesturePinchBegin { event }, &mut ());
826                        }
827                        event::GestureEvent::Pinch(event::gesture::GesturePinchEvent::Update(event)) => {
828                            callback(InputEvent::GesturePinchUpdate { event }, &mut ());
829                        }
830                        event::GestureEvent::Pinch(event::gesture::GesturePinchEvent::End(event)) => {
831                            callback(InputEvent::GesturePinchEnd { event }, &mut ());
832                        }
833                        event::GestureEvent::Hold(event::gesture::GestureHoldEvent::Begin(event)) => {
834                            callback(InputEvent::GestureHoldBegin { event }, &mut ());
835                        }
836                        event::GestureEvent::Hold(event::gesture::GestureHoldEvent::End(event)) => {
837                            callback(InputEvent::GestureHoldEnd { event }, &mut ());
838                        }
839                        _ => {
840                            trace!("Unknown libinput gesture event");
841                        }
842                    },
843                    libinput::Event::Tablet(tablet_event) => match tablet_event {
844                        event::TabletToolEvent::Axis(event) => {
845                            callback(InputEvent::TabletToolAxis { event }, &mut ());
846                        }
847                        event::TabletToolEvent::Proximity(event) => {
848                            callback(InputEvent::TabletToolProximity { event }, &mut ());
849                        }
850                        event::TabletToolEvent::Tip(event) => {
851                            callback(InputEvent::TabletToolTip { event }, &mut ());
852                        }
853                        event::TabletToolEvent::Button(event) => {
854                            callback(InputEvent::TabletToolButton { event }, &mut ());
855                        }
856                        _ => {
857                            trace!("Unknown libinput tablet event");
858                        }
859                    },
860                    libinput::Event::Switch(switch_event) => match switch_event {
861                        event::SwitchEvent::Toggle(event) => {
862                            callback(InputEvent::SwitchToggle { event }, &mut ());
863                        }
864                        _ => {
865                            trace!("Unknown libinput switch event");
866                        }
867                    },
868                    _ => {} //FIXME: What to do with the rest.
869                }
870            }
871        }
872
873        Ok(PostAction::Continue)
874    }
875
876    fn register(&mut self, poll: &mut Poll, factory: &mut TokenFactory) -> calloop::Result<()> {
877        self.token = Some(factory.token());
878        // Safety: the FD cannot be closed without removing the LibinputInputBackend from the event loop
879        unsafe { poll.register(self.as_fd(), Interest::READ, Mode::Level, self.token.unwrap()) }
880    }
881
882    fn reregister(&mut self, poll: &mut Poll, factory: &mut TokenFactory) -> calloop::Result<()> {
883        self.token = Some(factory.token());
884        poll.reregister(self.as_fd(), Interest::READ, Mode::Level, self.token.unwrap())
885    }
886
887    fn unregister(&mut self, poll: &mut Poll) -> calloop::Result<()> {
888        self.token = None;
889        poll.unregister(self.as_fd())
890    }
891}