| 1 | //! Pointer event types |
| 2 | #![allow (deprecated)] |
| 3 | |
| 4 | use super::EventTrait; |
| 5 | use crate::{ffi, AsRaw, Context, FromRaw, Libinput}; |
| 6 | |
| 7 | /// Common functions for all Pointer-Events implement. |
| 8 | pub 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 | |
| 25 | impl<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 ] |
| 30 | pub 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 | |
| 54 | impl 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 | |
| 72 | impl 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 | |
| 115 | impl 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 | |
| 132 | impl 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 | |
| 149 | ffi_event_struct!( |
| 150 | /// An event related to moving a pointer |
| 151 | struct PointerMotionEvent, ffi::libinput_event_pointer, ffi::libinput_event_pointer_get_base_event); |
| 152 | |
| 153 | impl 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 | |
| 202 | ffi_event_struct!( |
| 203 | /// An event related to absolute pointer movement |
| 204 | struct PointerMotionAbsoluteEvent, ffi::libinput_event_pointer, ffi::libinput_event_pointer_get_base_event); |
| 205 | |
| 206 | impl 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)] |
| 245 | pub enum ButtonState { |
| 246 | /// Button is pressed |
| 247 | Pressed, |
| 248 | /// Button is released |
| 249 | Released, |
| 250 | } |
| 251 | |
| 252 | ffi_event_struct!( |
| 253 | /// An event related to button pressed on a pointer device |
| 254 | struct PointerButtonEvent, ffi::libinput_event_pointer, ffi::libinput_event_pointer_get_base_event); |
| 255 | |
| 256 | impl 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)] |
| 281 | pub 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)] |
| 305 | pub enum Axis { |
| 306 | /// Vertical axis |
| 307 | Vertical, |
| 308 | /// Horizontal axis |
| 309 | Horizontal, |
| 310 | } |
| 311 | |
| 312 | ffi_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" )] |
| 315 | struct PointerAxisEvent, ffi::libinput_event_pointer, ffi::libinput_event_pointer_get_base_event); |
| 316 | |
| 317 | impl 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" )] |
| 457 | ffi_event_struct!( |
| 458 | /// An event related to moving a scroll whell on a pointer device |
| 459 | struct PointerScrollWheelEvent, ffi::libinput_event_pointer, ffi::libinput_event_pointer_get_base_event); |
| 460 | |
| 461 | #[cfg (feature = "libinput_1_19" )] |
| 462 | ffi_event_struct!( |
| 463 | /// An event related to moving a finger on a pointer device |
| 464 | struct PointerScrollFingerEvent, ffi::libinput_event_pointer, ffi::libinput_event_pointer_get_base_event); |
| 465 | |
| 466 | #[cfg (feature = "libinput_1_19" )] |
| 467 | ffi_event_struct!( |
| 468 | /// An event related to a continuous scroll source on a pointer device |
| 469 | struct 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 |
| 473 | pub 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" )] |
| 529 | impl PointerScrollEvent for PointerScrollWheelEvent {} |
| 530 | #[cfg (feature = "libinput_1_19" )] |
| 531 | impl PointerScrollEvent for PointerScrollFingerEvent {} |
| 532 | #[cfg (feature = "libinput_1_19" )] |
| 533 | impl PointerScrollEvent for PointerScrollContinuousEvent {} |
| 534 | |
| 535 | #[cfg (feature = "libinput_1_19" )] |
| 536 | impl 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 | |