chore: refresco desde el monorepo (pin tawasuyu.git v0.2.0)
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}