1//! Pointer event types
2#![allow(deprecated)]
3
4use super::EventTrait;
5use crate::{ffi, AsRaw, Context, FromRaw, Libinput};
6
7/// Common functions for all Pointer-Events implement.
8pub trait PointerEventTrait: AsRaw<ffi::libinput_event_pointer> + Context {
9 ffi_func!(
10 /// The event time for this event
11 fn time, ffi::libinput_event_pointer_get_time, u32);
12 ffi_func!(
13 /// The event time for this event in microseconds
14 fn time_usec, ffi::libinput_event_pointer_get_time_usec, u64);
15
16 /// Convert into a general `TouchEvent` again
17 fn into_pointer_event(self) -> PointerEvent
18 where
19 Self: Sized,
20 {
21 unsafe { PointerEvent::from_raw(self.as_raw_mut(), self.context()) }
22 }
23}
24
25impl<T: AsRaw<ffi::libinput_event_pointer> + Context> PointerEventTrait for T {}
26
27/// A pointer related `Event`
28#[derive(Debug, PartialEq, Eq, Hash)]
29#[non_exhaustive]
30pub enum PointerEvent {
31 /// An event related to moving a pointer
32 Motion(PointerMotionEvent),
33 /// An event related to absolute pointer movement
34 MotionAbsolute(PointerMotionAbsoluteEvent),
35 /// An event related to button pressed on a pointer device
36 Button(PointerButtonEvent),
37 /// An event related to moving axis on a pointer device
38 #[cfg_attr(
39 feature = "libinput_1_19",
40 deprecated = "Use `PointerEvent::Scroll*` events instead"
41 )]
42 Axis(PointerAxisEvent),
43 /// A scroll event from a wheel.
44 #[cfg(feature = "libinput_1_19")]
45 ScrollWheel(PointerScrollWheelEvent),
46 /// A scroll event caused by the movement of one or more fingers on a device.
47 #[cfg(feature = "libinput_1_19")]
48 ScrollFinger(PointerScrollFingerEvent),
49 /// A scroll event from a continuous scroll source, e.g. button scrolling.
50 #[cfg(feature = "libinput_1_19")]
51 ScrollContinuous(PointerScrollContinuousEvent),
52}
53
54impl EventTrait for PointerEvent {
55 #[doc(hidden)]
56 fn as_raw_event(&self) -> *mut ffi::libinput_event {
57 match self {
58 PointerEvent::Motion(event: &PointerMotionEvent) => event.as_raw_event(),
59 PointerEvent::MotionAbsolute(event: &PointerMotionAbsoluteEvent) => event.as_raw_event(),
60 PointerEvent::Button(event: &PointerButtonEvent) => event.as_raw_event(),
61 PointerEvent::Axis(event: &PointerAxisEvent) => event.as_raw_event(),
62 #[cfg(feature = "libinput_1_19")]
63 PointerEvent::ScrollWheel(event: &PointerScrollWheelEvent) => event.as_raw_event(),
64 #[cfg(feature = "libinput_1_19")]
65 PointerEvent::ScrollFinger(event: &PointerScrollFingerEvent) => event.as_raw_event(),
66 #[cfg(feature = "libinput_1_19")]
67 PointerEvent::ScrollContinuous(event: &PointerScrollContinuousEvent) => event.as_raw_event(),
68 }
69 }
70}
71
72impl FromRaw<ffi::libinput_event_pointer> for PointerEvent {
73 unsafe fn try_from_raw(
74 event: *mut ffi::libinput_event_pointer,
75 context: &Libinput,
76 ) -> Option<Self> {
77 let base = ffi::libinput_event_pointer_get_base_event(event);
78 match ffi::libinput_event_get_type(base) {
79 ffi::libinput_event_type_LIBINPUT_EVENT_POINTER_MOTION => Some(PointerEvent::Motion(
80 PointerMotionEvent::try_from_raw(event, context)?,
81 )),
82 ffi::libinput_event_type_LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE => {
83 Some(PointerEvent::MotionAbsolute(
84 PointerMotionAbsoluteEvent::try_from_raw(event, context)?,
85 ))
86 }
87 ffi::libinput_event_type_LIBINPUT_EVENT_POINTER_BUTTON => Some(PointerEvent::Button(
88 PointerButtonEvent::try_from_raw(event, context)?,
89 )),
90 ffi::libinput_event_type_LIBINPUT_EVENT_POINTER_AXIS => Some(PointerEvent::Axis(
91 PointerAxisEvent::try_from_raw(event, context)?,
92 )),
93 #[cfg(feature = "libinput_1_19")]
94 ffi::libinput_event_type_LIBINPUT_EVENT_POINTER_SCROLL_WHEEL => Some(
95 PointerEvent::ScrollWheel(PointerScrollWheelEvent::try_from_raw(event, context)?),
96 ),
97 #[cfg(feature = "libinput_1_19")]
98 ffi::libinput_event_type_LIBINPUT_EVENT_POINTER_SCROLL_FINGER => Some(
99 PointerEvent::ScrollFinger(PointerScrollFingerEvent::try_from_raw(event, context)?),
100 ),
101 #[cfg(feature = "libinput_1_19")]
102 ffi::libinput_event_type_LIBINPUT_EVENT_POINTER_SCROLL_CONTINUOUS => {
103 Some(PointerEvent::ScrollContinuous(
104 PointerScrollContinuousEvent::try_from_raw(event, context)?,
105 ))
106 }
107 _ => None,
108 }
109 }
110 unsafe fn from_raw(event: *mut ffi::libinput_event_pointer, context: &Libinput) -> Self {
111 Self::try_from_raw(event, context).expect("Unknown pointer event type")
112 }
113}
114
115impl AsRaw<ffi::libinput_event_pointer> for PointerEvent {
116 fn as_raw(&self) -> *const ffi::libinput_event_pointer {
117 match self {
118 PointerEvent::Motion(event: &PointerMotionEvent) => event.as_raw(),
119 PointerEvent::MotionAbsolute(event: &PointerMotionAbsoluteEvent) => event.as_raw(),
120 PointerEvent::Button(event: &PointerButtonEvent) => event.as_raw(),
121 PointerEvent::Axis(event: &PointerAxisEvent) => event.as_raw(),
122 #[cfg(feature = "libinput_1_19")]
123 PointerEvent::ScrollWheel(event: &PointerScrollWheelEvent) => event.as_raw(),
124 #[cfg(feature = "libinput_1_19")]
125 PointerEvent::ScrollFinger(event: &PointerScrollFingerEvent) => event.as_raw(),
126 #[cfg(feature = "libinput_1_19")]
127 PointerEvent::ScrollContinuous(event: &PointerScrollContinuousEvent) => event.as_raw(),
128 }
129 }
130}
131
132impl Context for PointerEvent {
133 fn context(&self) -> &Libinput {
134 match self {
135 PointerEvent::Motion(event: &PointerMotionEvent) => event.context(),
136 PointerEvent::MotionAbsolute(event: &PointerMotionAbsoluteEvent) => event.context(),
137 PointerEvent::Button(event: &PointerButtonEvent) => event.context(),
138 PointerEvent::Axis(event: &PointerAxisEvent) => event.context(),
139 #[cfg(feature = "libinput_1_19")]
140 PointerEvent::ScrollWheel(event: &PointerScrollWheelEvent) => event.context(),
141 #[cfg(feature = "libinput_1_19")]
142 PointerEvent::ScrollFinger(event: &PointerScrollFingerEvent) => event.context(),
143 #[cfg(feature = "libinput_1_19")]
144 PointerEvent::ScrollContinuous(event: &PointerScrollContinuousEvent) => event.context(),
145 }
146 }
147}
148
149ffi_event_struct!(
150/// An event related to moving a pointer
151struct PointerMotionEvent, ffi::libinput_event_pointer, ffi::libinput_event_pointer_get_base_event);
152
153impl PointerMotionEvent {
154 ffi_func!(
155 /// Return the delta between the last event and the current event.
156 ///
157 /// If a device employs pointer acceleration, the delta returned by this
158 /// function is the accelerated delta.
159 ///
160 /// Relative motion deltas are to be interpreted as pixel movement of a
161 /// standardized mouse. See [Normalization of relative motion](https://wayland.freedesktop.org/libinput/doc/latest/motion_normalization.html)
162 /// for more details.
163 pub fn dx, ffi::libinput_event_pointer_get_dx, f64);
164 ffi_func!(
165 /// Return the relative delta of the unaccelerated motion vector of the
166 /// current event.
167 ///
168 /// Relative unaccelerated motion deltas are raw device coordinates. Note that
169 /// these coordinates are subject to the device's native resolution. Touchpad
170 /// coordinates represent raw device coordinates in the X resolution of the
171 /// touchpad. See [Normalization of relative motion](https://wayland.freedesktop.org/libinput/doc/latest/motion_normalization.html)
172 /// for more details.
173 ///
174 /// Any rotation applied to the device also applies to unaccelerated motion
175 /// (see `Device::rotation_set_angle`).
176 pub fn dx_unaccelerated, ffi::libinput_event_pointer_get_dx_unaccelerated, f64);
177 ffi_func!(
178 /// Return the delta between the last event and the current event.
179 ///
180 /// If a device employs pointer acceleration, the delta returned by this
181 /// function is the accelerated delta.
182 ///
183 /// Relative motion deltas are to be interpreted as pixel movement of a
184 /// standardized mouse. See [Normalization of relative motion](https://wayland.freedesktop.org/libinput/doc/latest/motion_normalization.html)
185 /// for more details.
186 pub fn dy, ffi::libinput_event_pointer_get_dy, f64);
187 ffi_func!(
188 /// Return the relative delta of the unaccelerated motion vector of the
189 /// current event.
190 ///
191 /// Relative unaccelerated motion deltas are raw device coordinates. Note that
192 /// these coordinates are subject to the device's native resolution. Touchpad
193 /// coordinates represent raw device coordinates in the X resolution of the
194 /// touchpad. See [Normalization of relative motion](https://wayland.freedesktop.org/libinput/doc/latest/motion_normalization.html)
195 /// for more details.
196 ///
197 /// Any rotation applied to the device also applies to unaccelerated motion
198 /// (see `Device::rotation_set_angle`).
199 pub fn dy_unaccelerated, ffi::libinput_event_pointer_get_dy_unaccelerated, f64);
200}
201
202ffi_event_struct!(
203/// An event related to absolute pointer movement
204struct PointerMotionAbsoluteEvent, ffi::libinput_event_pointer, ffi::libinput_event_pointer_get_base_event);
205
206impl PointerMotionAbsoluteEvent {
207 ffi_func!(
208 /// Return the current absolute x coordinate of the pointer event, in mm from
209 /// the top left corner of the device.
210 ///
211 /// To get the corresponding output screen coordinate, use
212 /// `absolute_x_transformed`.
213 pub fn absolute_x, ffi::libinput_event_pointer_get_absolute_x, f64);
214 ffi_func!(
215 /// Return the current absolute y coordinate of the pointer event, in mm from
216 /// the top left corner of the device.
217 ///
218 /// To get the corresponding output screen coordinate, use
219 /// `absolute_y_transformed`.
220 pub fn absolute_y, ffi::libinput_event_pointer_get_absolute_y, f64);
221
222 /// Return the current absolute x coordinate of the pointer event, transformed
223 /// to screen coordinates.
224 ///
225 /// ## Arguments
226 ///
227 /// - width - The current output screen width
228 pub fn absolute_x_transformed(&self, width: u32) -> f64 {
229 unsafe { ffi::libinput_event_pointer_get_absolute_x_transformed(self.as_raw_mut(), width) }
230 }
231
232 /// Return the current absolute y coordinate of the pointer event, transformed
233 /// to screen coordinates.
234 ///
235 /// ## Arguments
236 ///
237 /// - height - The current output screen height
238 pub fn absolute_y_transformed(&self, height: u32) -> f64 {
239 unsafe { ffi::libinput_event_pointer_get_absolute_y_transformed(self.as_raw_mut(), height) }
240 }
241}
242
243/// State of a Button
244#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
245pub enum ButtonState {
246 /// Button is pressed
247 Pressed,
248 /// Button is released
249 Released,
250}
251
252ffi_event_struct!(
253/// An event related to button pressed on a pointer device
254struct PointerButtonEvent, ffi::libinput_event_pointer, ffi::libinput_event_pointer_get_base_event);
255
256impl PointerButtonEvent {
257 ffi_func!(
258 /// Return the button that triggered this event.
259 pub fn button, ffi::libinput_event_pointer_get_button, u32);
260 ffi_func!(
261 /// For the button returns the total number of buttons pressed on all devices
262 /// on the associated seat after the event was triggered.
263 pub fn seat_button_count, ffi::libinput_event_pointer_get_seat_button_count, u32);
264
265 /// Return the button state that triggered this event.
266 pub fn button_state(&self) -> ButtonState {
267 match unsafe { ffi::libinput_event_pointer_get_button_state(self.as_raw_mut()) } {
268 ffi::libinput_button_state_LIBINPUT_BUTTON_STATE_PRESSED => ButtonState::Pressed,
269 ffi::libinput_button_state_LIBINPUT_BUTTON_STATE_RELEASED => ButtonState::Released,
270 _ => panic!("libinput returned invalid 'libinput_button_state'"),
271 }
272 }
273}
274
275/// The source for a `PointerAxisEvent`.
276#[cfg_attr(
277 feature = "libinput_1_19",
278 deprecated = "Use `PointerEvent::Scroll*` events instead"
279)]
280#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
281pub enum AxisSource {
282 /// The event is caused by the rotation of a wheel.
283 Wheel,
284 /// The event is caused by the movement of one or more fingers on a device.
285 Finger,
286 /// The event is caused by the motion of some device.
287 Continuous,
288 /// The event is caused by the tilting of a mouse wheel rather than its rotation.
289 ///
290 /// This method is commonly used on mice without separate horizontal scroll wheels.
291 #[cfg_attr(
292 feature = "libinput_1_19",
293 deprecated = "No device has ever sent this source."
294 )]
295 WheelTilt,
296}
297
298/// Axes on a device with the pointer capability that are not x or y coordinates.
299///
300/// The two scroll axes `Vertical` and `Horizontal` are engaged separately,
301/// depending on the device. libinput provides some scroll direction locking but
302/// it is up to the caller to determine which axis is needed and appropriate in
303/// the current interaction
304#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
305pub enum Axis {
306 /// Vertical axis
307 Vertical,
308 /// Horizontal axis
309 Horizontal,
310}
311
312ffi_event_struct!(
313/// An event related to moving axis on a pointer device
314#[cfg_attr(feature = "libinput_1_19", deprecated = "Use `PointerEvent::Scroll*` events instead")]
315struct PointerAxisEvent, ffi::libinput_event_pointer, ffi::libinput_event_pointer_get_base_event);
316
317impl PointerAxisEvent {
318 /// Check if the event has a valid value for the given axis.
319 ///
320 /// If this function returns true for an axis and `axis_value` returns a
321 /// value of 0, the event is a scroll stop event.
322 #[cfg_attr(
323 feature = "libinput_1_19",
324 deprecated = "Use `PointerScrollEvent::has_axis` instead"
325 )]
326 pub fn has_axis(&self, axis: Axis) -> bool {
327 unsafe {
328 ffi::libinput_event_pointer_has_axis(
329 self.as_raw_mut(),
330 match axis {
331 Axis::Vertical => {
332 ffi::libinput_pointer_axis_LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL
333 }
334 Axis::Horizontal => {
335 ffi::libinput_pointer_axis_LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL
336 }
337 },
338 ) != 0
339 }
340 }
341
342 /// Return the source for a given axis event.
343 ///
344 /// Axis events (scroll events) can be caused by a hardware item such as a
345 /// scroll wheel or emulated from other input sources, such as two-finger or
346 /// edge scrolling on a touchpad.
347 ///
348 /// If the source is `Finger`, libinput guarantees that a scroll sequence is
349 /// terminated with a scroll value of 0. A caller may use this information to
350 /// decide on whether kinetic scrolling should be triggered on this scroll
351 /// sequence. The coordinate system is identical to the cursor movement, i.e.
352 /// a scroll value of 1 represents the equivalent relative motion of 1.
353 ///
354 /// If the source is `Wheel`, no terminating event is guaranteed (though it
355 /// may happen). Scrolling is in discrete steps, the value is the angle the
356 /// wheel moved in degrees. The default is 15 degrees per wheel click, but
357 /// some mice may have differently grained wheels. It is up to the caller how
358 /// to interpret such different step sizes.
359 ///
360 /// If the source is `Continuous`, no terminating event is guaranteed (though
361 /// it may happen). The coordinate system is identical to the cursor movement,
362 /// i.e. a scroll value of 1 represents the equivalent relative motion of 1.
363 ///
364 /// If the source is `WheelTilt`, no terminating event is guaranteed (though
365 /// it may happen). Scrolling is in discrete steps and there is no physical
366 /// equivalent for the value returned here. For backwards compatibility, the
367 /// value returned by this function is identical to a single mouse wheel
368 /// rotation by this device (see the documentation for `WheelTilt` above).
369 /// Callers should not use this value but instead exclusively refer to the
370 //. value returned by `axis_value_discrete`.
371 #[cfg_attr(
372 feature = "libinput_1_19",
373 deprecated = "Use `PointerScroll*` events instead"
374 )]
375 pub fn axis_source(&self) -> AxisSource {
376 match unsafe { ffi::libinput_event_pointer_get_axis_source(self.as_raw_mut()) } {
377 ffi::libinput_pointer_axis_source_LIBINPUT_POINTER_AXIS_SOURCE_WHEEL => {
378 AxisSource::Wheel
379 }
380 ffi::libinput_pointer_axis_source_LIBINPUT_POINTER_AXIS_SOURCE_FINGER => {
381 AxisSource::Finger
382 }
383 ffi::libinput_pointer_axis_source_LIBINPUT_POINTER_AXIS_SOURCE_CONTINUOUS => {
384 AxisSource::Continuous
385 }
386 ffi::libinput_pointer_axis_source_LIBINPUT_POINTER_AXIS_SOURCE_WHEEL_TILT => {
387 AxisSource::WheelTilt
388 }
389 // Axis Event is deprecated, no new variants will be added
390 _ => unreachable!(),
391 }
392 }
393
394 /// Return the axis value of the given axis.
395 ///
396 /// The interpretation of the value depends on the axis. For the two scrolling
397 /// axes `Vertical` and `Horizontal`, the value of the event is in relative
398 /// scroll units, with the positive direction being down or right,
399 /// respectively. For the interpretation of the value, see `axis_source`.
400 ///
401 /// If `has_axis` returns `false` for an axis, this function returns 0 for
402 /// that axis.
403 #[cfg_attr(
404 feature = "libinput_1_19",
405 deprecated = "Use `PointerScrollEvent::scroll_value` instead"
406 )]
407 pub fn axis_value(&self, axis: Axis) -> f64 {
408 unsafe {
409 ffi::libinput_event_pointer_get_axis_value(
410 self.as_raw_mut(),
411 match axis {
412 Axis::Vertical => {
413 ffi::libinput_pointer_axis_LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL
414 }
415 Axis::Horizontal => {
416 ffi::libinput_pointer_axis_LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL
417 }
418 },
419 )
420 }
421 }
422
423 /// Return the axis value in discrete steps for a given axis event.
424 ///
425 /// How a value translates into a discrete step depends on the source.
426 ///
427 /// If the source is `Wheel`, the discrete value correspond to the number of
428 /// physical mouse wheel clicks.
429 ///
430 /// If the source is `Continuous` or `Finger`, the discrete value is always
431 /// `None`.
432 #[cfg_attr(
433 feature = "libinput_1_19",
434 deprecated = "Use `PointerScrollWheelEvent::scroll_value_v120` instead"
435 )]
436 pub fn axis_value_discrete(&self, axis: Axis) -> Option<f64> {
437 match self.axis_source() {
438 AxisSource::Continuous | AxisSource::Finger => None,
439 _ => Some(unsafe {
440 ffi::libinput_event_pointer_get_axis_value_discrete(
441 self.as_raw_mut(),
442 match axis {
443 Axis::Vertical => {
444 ffi::libinput_pointer_axis_LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL
445 }
446 Axis::Horizontal => {
447 ffi::libinput_pointer_axis_LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL
448 }
449 },
450 )
451 }),
452 }
453 }
454}
455
456#[cfg(feature = "libinput_1_19")]
457ffi_event_struct!(
458/// An event related to moving a scroll whell on a pointer device
459struct PointerScrollWheelEvent, ffi::libinput_event_pointer, ffi::libinput_event_pointer_get_base_event);
460
461#[cfg(feature = "libinput_1_19")]
462ffi_event_struct!(
463/// An event related to moving a finger on a pointer device
464struct PointerScrollFingerEvent, ffi::libinput_event_pointer, ffi::libinput_event_pointer_get_base_event);
465
466#[cfg(feature = "libinput_1_19")]
467ffi_event_struct!(
468/// An event related to a continuous scroll source on a pointer device
469struct PointerScrollContinuousEvent, ffi::libinput_event_pointer, ffi::libinput_event_pointer_get_base_event);
470
471#[cfg(feature = "libinput_1_19")]
472/// Common functions of PointerScroll type events
473pub trait PointerScrollEvent: AsRaw<ffi::libinput_event_pointer> {
474 /// Check if the event has a valid value for the given axis.
475 ///
476 /// If this function returns true for an axis and `axis_value` returns a
477 /// value of 0, the event is a scroll stop event.
478 fn has_axis(&self, axis: Axis) -> bool {
479 unsafe {
480 ffi::libinput_event_pointer_has_axis(
481 self.as_raw_mut(),
482 match axis {
483 Axis::Vertical => {
484 ffi::libinput_pointer_axis_LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL
485 }
486 Axis::Horizontal => {
487 ffi::libinput_pointer_axis_LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL
488 }
489 },
490 ) != 0
491 }
492 }
493
494 /// Return the axis value of the given axis.
495 ///
496 /// The interpretation of the value depends on the axis. For the two scrolling axes [`Axis::Vertical`] and [`Axis::Horizontal`],
497 /// the value of the event is in relative scroll units, with the positive direction being down or right,
498 /// respectively. If [`PointerScrollEvent::has_axis`] returns false for an axis, this function returns 0 for that axis.
499 ///
500 /// If the event is a [`PointerScrollFingerEvent`], libinput guarantees that a scroll sequence is terminated with a scroll value of 0.
501 /// A caller may use this information to decide on whether kinetic scrolling should be triggered on this scroll sequence.
502 /// The coordinate system is identical to the cursor movement, i.e. a scroll value of 1 represents the equivalent relative motion of 1.
503 ///
504 /// If the event is a [`PointerScrollWheelEvent`], no terminating event is guaranteed (though it may happen).
505 /// Scrolling is in discrete steps, the value is the angle the wheel moved in degrees. The default is 15 degrees per wheel click,
506 /// but some mice may have differently grained wheels. It is up to the caller how to interpret such different step sizes.
507 /// Callers should use [`PointerScrollWheelEvent::scroll_value_v120`] for a simpler API of handling scroll wheel events of different step sizes.
508 ///
509 /// If the event is a [`PointerScrollContinuousEvent`], libinput guarantees that a scroll sequence is terminated with a scroll value of 0.
510 /// The coordinate system is identical to the cursor movement, i.e. a scroll value of 1 represents the equivalent relative motion of 1.
511 fn scroll_value(&self, axis: Axis) -> f64 {
512 unsafe {
513 ffi::libinput_event_pointer_get_scroll_value(
514 self.as_raw_mut(),
515 match axis {
516 Axis::Vertical => {
517 ffi::libinput_pointer_axis_LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL
518 }
519 Axis::Horizontal => {
520 ffi::libinput_pointer_axis_LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL
521 }
522 },
523 )
524 }
525 }
526}
527
528#[cfg(feature = "libinput_1_19")]
529impl PointerScrollEvent for PointerScrollWheelEvent {}
530#[cfg(feature = "libinput_1_19")]
531impl PointerScrollEvent for PointerScrollFingerEvent {}
532#[cfg(feature = "libinput_1_19")]
533impl PointerScrollEvent for PointerScrollContinuousEvent {}
534
535#[cfg(feature = "libinput_1_19")]
536impl PointerScrollWheelEvent {
537 /// Return the axis value as a v120-normalized value, that represents the movement in logical mouse wheel clicks, normalized to the -120..+120 range.
538 ///
539 /// A value that is a fraction of ±120 indicates a wheel movement less than one logical click,
540 /// a caller should either scroll by the respective fraction of the normal scroll distance or accumulate
541 /// that value until a multiple of 120 is reached.
542 ///
543 /// For most callers, this is the preferred way of handling high-resolution scroll events.
544 ///
545 /// The normalized v120 value does not take device-specific physical angles or distances into account,
546 /// i.e. a wheel with a click angle of 20 degrees produces only 18 logical clicks per 360 degree rotation,
547 /// a wheel with a click angle of 15 degrees produces 24 logical clicks per 360 degree rotation.
548 /// Where the physical angle matters, use [`PointerScrollEvent::scroll_value`] instead.
549 ///
550 /// The magic number 120 originates from the [Windows Vista Mouse Wheel design document](http://download.microsoft.com/download/b/d/1/bd1f7ef4-7d72-419e-bc5c-9f79ad7bb66e/wheel.docx).
551 pub fn scroll_value_v120(&self, axis: Axis) -> f64 {
552 unsafe {
553 ffi::libinput_event_pointer_get_scroll_value_v120(
554 self.as_raw_mut(),
555 match axis {
556 Axis::Vertical => {
557 ffi::libinput_pointer_axis_LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL
558 }
559 Axis::Horizontal => {
560 ffi::libinput_pointer_axis_LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL
561 }
562 },
563 )
564 }
565 }
566}
567