| 1 | //! Tablet tool event types |
| 2 | |
| 3 | use super::{pointer::ButtonState, EventTrait}; |
| 4 | use crate::{ffi, AsRaw, Context, FromRaw, Libinput}; |
| 5 | |
| 6 | mod tool; |
| 7 | pub use self::tool::*; |
| 8 | |
| 9 | /// Common functions all TabletTool-Events implement. |
| 10 | pub trait TabletToolEventTrait: AsRaw<ffi::libinput_event_tablet_tool> + Context { |
| 11 | ffi_func!( |
| 12 | /// The event time for this event |
| 13 | fn time, ffi::libinput_event_tablet_tool_get_time, u32); |
| 14 | ffi_func!( |
| 15 | /// The event time for this event in microseconds |
| 16 | fn time_usec, ffi::libinput_event_tablet_tool_get_time_usec, u64); |
| 17 | ffi_func!( |
| 18 | /// Check if the distance axis was updated in this event. |
| 19 | /// |
| 20 | /// For `TabletToolProximityEvent`s this function always returns `true`. For |
| 21 | /// `TabletToolButtonEvent`s this function always returns `false`. |
| 22 | fn distance_has_changed, ffi::libinput_event_tablet_tool_distance_has_changed, bool); |
| 23 | ffi_func!( |
| 24 | /// Returns the current distance from the tablet's sensor, normalized to the range |
| 25 | /// [0, 1]. |
| 26 | /// |
| 27 | /// If this axis does not exist on the current tool, this function returns 0. |
| 28 | fn distance, ffi::libinput_event_tablet_tool_get_distance, f64); |
| 29 | ffi_func!( |
| 30 | /// Return the delta between the last event and the current event. |
| 31 | /// |
| 32 | /// If the tool employs pointer acceleration, the delta returned by this function is |
| 33 | /// the accelerated delta. |
| 34 | /// |
| 35 | /// This value is in screen coordinate space, the delta is to be interpreted like |
| 36 | /// the return value of `PointerMotionEvent::dx`. See |
| 37 | /// [Relative motion for tablet tools](https://wayland.freedesktop.org/libinput/doc/latest/tablet-support.html#tablet-relative-motion) |
| 38 | /// for more details. |
| 39 | fn dx, ffi::libinput_event_tablet_tool_get_dx, f64); |
| 40 | ffi_func!( |
| 41 | /// Return the delta between the last event and the current event. |
| 42 | /// |
| 43 | /// If the tool employs pointer acceleration, the delta returned by this function is |
| 44 | /// the accelerated delta. |
| 45 | /// |
| 46 | /// This value is in screen coordinate space, the delta is to be interpreted like |
| 47 | /// the return value of `PointerMotionEvent::dy`. See |
| 48 | /// [Relative motion for tablet tools](https://wayland.freedesktop.org/libinput/doc/latest/tablet-support.html#tablet-relative-motion) |
| 49 | /// for more details. |
| 50 | fn dy, ffi::libinput_event_tablet_tool_get_dy, f64); |
| 51 | ffi_func!( |
| 52 | /// Check if the pressure axis was updated in this event. For `TabletToolButtonEvent`s this function always returns `false`. |
| 53 | fn pressure_has_changed, ffi::libinput_event_tablet_tool_pressure_has_changed, bool); |
| 54 | ffi_func!( |
| 55 | /// Returns the current pressure being applied on the tool in use, normalized to the |
| 56 | /// range [0, 1]. |
| 57 | /// |
| 58 | /// If this axis does not exist on the current tool, this function returns 0. |
| 59 | fn pressure, ffi::libinput_event_tablet_tool_get_pressure, f64); |
| 60 | ffi_func!( |
| 61 | /// Check if the z-rotation axis was updated in this event. |
| 62 | /// |
| 63 | /// For `TabletToolButtonEvent`s this function always returns `false`. |
| 64 | fn rotation_has_changed, ffi::libinput_event_tablet_tool_rotation_has_changed, bool); |
| 65 | ffi_func!( |
| 66 | /// Returns the current z rotation of the tool in degrees, clockwise from the tool's |
| 67 | /// logical neutral position. |
| 68 | /// |
| 69 | /// For tools of type `TabletToolType::Mouse` and `TabletToolType::Lens` the logical |
| 70 | /// neutral position is pointing to the current logical north of the tablet. For |
| 71 | /// tools of type `TabletToolType::Brush`, the logical neutral position is with the |
| 72 | /// buttons pointing up. |
| 73 | /// |
| 74 | /// If this axis does not exist on the current tool, this function returns 0. |
| 75 | fn rotation, ffi::libinput_event_tablet_tool_get_rotation, f64); |
| 76 | ffi_func!( |
| 77 | /// Check if the slider axis was updated in this event. |
| 78 | /// |
| 79 | /// For `TabletToolButtonEvent`s this function always returns `false`. |
| 80 | fn slider_has_changed, ffi::libinput_event_tablet_tool_slider_has_changed, bool); |
| 81 | ffi_func!( |
| 82 | /// Returns the current position of the slider on the tool, normalized to the range |
| 83 | /// [-1, 1]. |
| 84 | /// |
| 85 | /// The logical zero is the neutral position of the slider, or the logical center of |
| 86 | /// the axis. This axis is available on e.g. the Wacom Airbrush. |
| 87 | /// |
| 88 | /// If this axis does not exist on the current tool, this function returns 0. |
| 89 | fn slider_position, ffi::libinput_event_tablet_tool_get_slider_position, f64); |
| 90 | ffi_func!( |
| 91 | /// Check if the tilt x axis was updated in this event. |
| 92 | /// |
| 93 | /// For `TabletToolButtonEvent`s this function always returns `false`. |
| 94 | fn tilt_x_has_changed, ffi::libinput_event_tablet_tool_tilt_x_has_changed, bool); |
| 95 | ffi_func!( |
| 96 | /// Check if the tilt y axis was updated in this event. |
| 97 | /// |
| 98 | /// For `TabletToolButtonEvent`s this function always returns `false`. |
| 99 | fn tilt_y_has_changed, ffi::libinput_event_tablet_tool_tilt_y_has_changed, bool); |
| 100 | ffi_func!( |
| 101 | /// Returns the current tilt along the X axis of the tablet's current logical |
| 102 | /// orientation, in degrees off the tablet's z axis. |
| 103 | /// |
| 104 | /// That is, if the tool is perfectly orthogonal to the tablet, the tilt angle is 0. |
| 105 | /// When the top tilts towards the logical top/left of the tablet, the x/y tilt |
| 106 | /// angles are negative, if the top tilts towards the logical bottom/right of the |
| 107 | /// tablet, the x/y tilt angles are positive. |
| 108 | /// |
| 109 | /// If this axis does not exist on the current tool, this function returns 0. |
| 110 | fn tilt_x, ffi::libinput_event_tablet_tool_get_tilt_x, f64); |
| 111 | ffi_func!( |
| 112 | /// Returns the current tilt along the Y axis of the tablet's current logical |
| 113 | /// orientation, in degrees off the tablet's z axis. |
| 114 | /// |
| 115 | /// That is, if the tool is perfectly orthogonal to the tablet, the tilt angle is 0. |
| 116 | /// When the top tilts towards the logical top/left of the tablet, the x/y tilt |
| 117 | /// angles are negative, if the top tilts towards the logical bottom/right of the |
| 118 | /// tablet, the x/y tilt angles are positive. |
| 119 | /// |
| 120 | /// If this axis does not exist on the current tool, this function returns 0. |
| 121 | fn tilt_y, ffi::libinput_event_tablet_tool_get_tilt_y, f64); |
| 122 | #[cfg (feature = "libinput_1_14" )] |
| 123 | ffi_func!( |
| 124 | /// Check if the size major axis was updated in this event. |
| 125 | /// |
| 126 | /// For `TabletToolButtonEvent`s this function always returns false |
| 127 | fn size_major_has_changed, ffi::libinput_event_tablet_tool_size_major_has_changed, bool); |
| 128 | #[cfg (feature = "libinput_1_14" )] |
| 129 | ffi_func!( |
| 130 | /// Check if the size minor axis was updated in this event. |
| 131 | /// |
| 132 | /// For `TabletToolButtonEvent`s this function always returns false |
| 133 | fn size_minor_has_changed, ffi::libinput_event_tablet_tool_size_minor_has_changed, bool); |
| 134 | #[cfg (feature = "libinput_1_14" )] |
| 135 | ffi_func!( |
| 136 | /// Returns the current size in mm along the major axis of the touching ellipse. |
| 137 | /// This axis is not necessarily aligned with either x or y, the rotation must |
| 138 | /// be taken into account. |
| 139 | /// |
| 140 | /// Where no rotation is available on a tool, or where rotation is zero, the major |
| 141 | /// axis aligns with the y axis and the minor axis with the x axis. |
| 142 | /// |
| 143 | /// If the axis does not exist on the current tool, this function returns 0. |
| 144 | fn size_major, ffi::libinput_event_tablet_tool_get_size_major, f64); |
| 145 | #[cfg (feature = "libinput_1_14" )] |
| 146 | ffi_func!( |
| 147 | /// Returns the current size in mm along the minor axis of the touching ellipse. |
| 148 | /// This axis is not necessarily aligned with either x or y, the rotation must |
| 149 | /// be taken into account. |
| 150 | /// |
| 151 | /// Where no rotation is available on a tool, or where rotation is zero, the minor |
| 152 | /// axis aligns with the y axis and the major axis with the x axis. |
| 153 | /// |
| 154 | /// If the axis does not exist on the current tool, this function returns 0. |
| 155 | fn size_minor, ffi::libinput_event_tablet_tool_get_size_minor, f64); |
| 156 | ffi_func!( |
| 157 | /// Check if the wheel axis was updated in this event. |
| 158 | /// |
| 159 | /// For `TabletToolButtonEvent`s this function always returns `false`. |
| 160 | fn wheel_has_changed, ffi::libinput_event_tablet_tool_wheel_has_changed, bool); |
| 161 | ffi_func!( |
| 162 | /// Return the delta for the wheel in degrees. |
| 163 | fn wheel_delta, ffi::libinput_event_tablet_tool_get_wheel_delta, f64); |
| 164 | ffi_func!( |
| 165 | /// Return the delta for the wheel in discrete steps (e.g. wheel clicks). |
| 166 | fn wheel_delta_discrete, ffi::libinput_event_tablet_tool_get_wheel_delta_discrete, f64); |
| 167 | ffi_func!( |
| 168 | /// Check if the x axis was updated in this event. |
| 169 | /// |
| 170 | /// For `TabletToolButtonEvent`s this function always returns `false`. |
| 171 | fn x_has_changed, ffi::libinput_event_tablet_tool_x_has_changed, bool); |
| 172 | ffi_func!( |
| 173 | /// Check if the y axis was updated in this event. |
| 174 | /// |
| 175 | /// For `TabletToolButtonEvent`s this function always returns `false`. |
| 176 | fn y_has_changed, ffi::libinput_event_tablet_tool_y_has_changed, bool); |
| 177 | ffi_func!( |
| 178 | /// Returns the X coordinate of the tablet tool, in mm from the top left corner of |
| 179 | /// the tablet in its current logical orientation. |
| 180 | /// |
| 181 | /// Use `x_transformed` for transforming the axis value into a different coordinate |
| 182 | /// space. |
| 183 | /// |
| 184 | /// ## Note |
| 185 | /// |
| 186 | /// On some devices, returned value may be negative or larger than the width of the |
| 187 | /// device. See [Out-of-bounds motion events](https://wayland.freedesktop.org/libinput/doc/latest/tablet-support.html#tablet-bounds) |
| 188 | /// for more details. |
| 189 | fn x, ffi::libinput_event_tablet_tool_get_x, f64); |
| 190 | ffi_func!( |
| 191 | /// Returns the Y coordinate of the tablet tool, in mm from the top left corner of |
| 192 | /// the tablet in its current logical orientation. |
| 193 | /// |
| 194 | /// Use `y_transformed` for transforming the axis value into a different coordinate |
| 195 | /// space. |
| 196 | /// |
| 197 | /// ## Note |
| 198 | /// |
| 199 | /// On some devices, returned value may be negative or larger than the width of the |
| 200 | /// device. See [Out-of-bounds motion events](https://wayland.freedesktop.org/libinput/doc/latest/tablet-support.html#tablet-bounds) |
| 201 | /// for more details. |
| 202 | fn y, ffi::libinput_event_tablet_tool_get_y, f64); |
| 203 | |
| 204 | /// Return the current absolute x coordinate of the tablet tool event, transformed |
| 205 | /// to screen coordinates. |
| 206 | /// |
| 207 | /// ## Note |
| 208 | /// |
| 209 | /// This function may be called for a specific axis even if `x_has_changed` returns |
| 210 | /// `false` for that axis. libinput always includes all device axes in the event. |
| 211 | /// |
| 212 | /// On some devices, returned value may be negative or larger than the width of the |
| 213 | /// device. See [Out-of-bounds motion events](https://wayland.freedesktop.org/libinput/doc/latest/tablet-support.html#tablet-bounds) |
| 214 | /// for more details. |
| 215 | fn x_transformed(&self, width: u32) -> f64 { |
| 216 | unsafe { ffi::libinput_event_tablet_tool_get_x_transformed(self.as_raw_mut(), width) } |
| 217 | } |
| 218 | |
| 219 | /// Return the current absolute y coordinate of the tablet tool event, transformed |
| 220 | /// to screen coordinates. |
| 221 | /// |
| 222 | /// ## Note |
| 223 | /// |
| 224 | /// This function may be called for a specific axis even if `y_has_changed` returns |
| 225 | /// `false` for that axis. libinput always includes all device axes in the event. |
| 226 | /// |
| 227 | /// On some devices, returned value may be negative or larger than the width of the |
| 228 | /// device. See [Out-of-bounds motion events](https://wayland.freedesktop.org/libinput/doc/latest/tablet-support.html#tablet-bounds) |
| 229 | /// for more details. |
| 230 | fn y_transformed(&self, height: u32) -> f64 { |
| 231 | unsafe { ffi::libinput_event_tablet_tool_get_y_transformed(self.as_raw_mut(), height) } |
| 232 | } |
| 233 | |
| 234 | /// Returns the tool that was in use during this event. |
| 235 | /// |
| 236 | /// ## Note |
| 237 | /// |
| 238 | /// Physical tool tracking requires hardware support. If unavailable, libinput |
| 239 | /// creates one tool per type per tablet. See [Tracking unique tools](https://wayland.freedesktop.org/libinput/doc/latest/tablet-support.html#tablet-serial-numbers) |
| 240 | /// for more details. |
| 241 | fn tool(&self) -> TabletTool { |
| 242 | unsafe { |
| 243 | TabletTool::from_raw( |
| 244 | ffi::libinput_event_tablet_tool_get_tool(self.as_raw_mut()), |
| 245 | self.context(), |
| 246 | ) |
| 247 | } |
| 248 | } |
| 249 | |
| 250 | /// Convert into a general `TabletToolEvent` again |
| 251 | fn into_tablet_tool_event(self) -> TabletToolEvent |
| 252 | where |
| 253 | Self: Sized, |
| 254 | { |
| 255 | unsafe { TabletToolEvent::from_raw(self.as_raw_mut(), self.context()) } |
| 256 | } |
| 257 | } |
| 258 | |
| 259 | impl<T: AsRaw<ffi::libinput_event_tablet_tool> + Context> TabletToolEventTrait for T {} |
| 260 | |
| 261 | /// An event related to a tablet tool |
| 262 | #[derive (Debug, PartialEq, Eq, Hash)] |
| 263 | #[non_exhaustive ] |
| 264 | pub enum TabletToolEvent { |
| 265 | /// One or more axes have changed state on a device with the |
| 266 | /// `DeviceCapability::TabletTool` capability. |
| 267 | /// |
| 268 | /// This event is only sent when the tool is in proximity, see |
| 269 | /// `TabletToolProximityEvent` for details. |
| 270 | /// |
| 271 | /// The proximity event contains the initial state of the axis as the tool comes into |
| 272 | /// proximity. An event of type `TabletToolAxisEvent` is only sent when an axis value |
| 273 | /// changes from this initial state. It is possible for a tool to enter and leave |
| 274 | /// proximity without sending an event of type `TabletToolAxisEvent`. |
| 275 | /// |
| 276 | /// An event of type `TabletToolAxisEvent` is sent when the tip state does not |
| 277 | /// change. See the documentation for `TabletToolTipEvent` for more details. |
| 278 | Axis(TabletToolAxisEvent), |
| 279 | /// Signals that a tool has come in or out of proximity of a device with the |
| 280 | /// `DeviceCapability::TabletTool` capability. |
| 281 | /// |
| 282 | /// Proximity events contain each of the current values for each axis, and these |
| 283 | /// values may be extracted from them in the same way they are with |
| 284 | /// `TabletToolAxisEvent` events. |
| 285 | /// |
| 286 | /// Some tools may always be in proximity. For these tools, proximity events with |
| 287 | /// `ProximityState::In` are sent only once after `DeviceAddedEvent`, and proximity |
| 288 | /// events with `ProximityState::Out` are sent only once before `DeviceRemovedEvent`. |
| 289 | /// |
| 290 | /// If the tool that comes into proximity supports x/y coordinates, libinput |
| 291 | /// guarantees that both x and y are set in the proximity event. |
| 292 | /// |
| 293 | /// When a tool goes out of proximity, the value of every axis should be assumed to |
| 294 | /// have an undefined state and any buttons that are currently held down on the |
| 295 | /// stylus are marked as released. Button release events for each button that was |
| 296 | /// held down on the stylus are sent before the proximity out event. |
| 297 | Proximity(TabletToolProximityEvent), |
| 298 | /// Signals that a tool has come in contact with the surface of a device with the |
| 299 | /// `DeviceCapability::TabletTool` capability. |
| 300 | /// |
| 301 | /// On devices without distance proximity detection, the `TabletToolTipEvent` is sent |
| 302 | /// immediately after `TabletToolProximityEvent` for the tip down event, and |
| 303 | /// immediately before for the tip up event. |
| 304 | /// |
| 305 | /// The decision when a tip touches the surface is device-dependent and may be |
| 306 | /// derived from pressure data or other means. If the tip state is changed by axes |
| 307 | /// changing state, the `TabletToolTipEvent` includes the changed axes and no |
| 308 | /// additional axis event is sent for this state change. In other words, a caller |
| 309 | /// must look at both `TabletToolAxisEvent` and `TabletToolTipEvent` events to know |
| 310 | /// the current state of the axes. |
| 311 | /// |
| 312 | /// If a button state change occurs at the same time as a tip state change, the order |
| 313 | /// of events is device-dependent. |
| 314 | Tip(TabletToolTipEvent), |
| 315 | /// Signals that a tool has changed a logical button state on a device with the |
| 316 | /// `DeviceCapability::TabletTool` capability. |
| 317 | /// |
| 318 | /// Button state changes occur on their own and do not include axis state changes. If |
| 319 | /// button and axis state changes occur within the same logical hardware event, the |
| 320 | /// order of the `TabletToolButtonEvent` and `TabletToolAxisEvent` is device-specific. |
| 321 | /// |
| 322 | /// This event is not to be confused with the button events emitted by the tablet |
| 323 | /// pad. See `TabletPadButtonEvent`. |
| 324 | Button(TabletToolButtonEvent), |
| 325 | } |
| 326 | |
| 327 | impl EventTrait for TabletToolEvent { |
| 328 | #[doc (hidden)] |
| 329 | fn as_raw_event(&self) -> *mut ffi::libinput_event { |
| 330 | match self { |
| 331 | TabletToolEvent::Axis(event: &TabletToolAxisEvent) => event.as_raw_event(), |
| 332 | TabletToolEvent::Proximity(event: &TabletToolProximityEvent) => event.as_raw_event(), |
| 333 | TabletToolEvent::Tip(event: &TabletToolTipEvent) => event.as_raw_event(), |
| 334 | TabletToolEvent::Button(event: &TabletToolButtonEvent) => event.as_raw_event(), |
| 335 | } |
| 336 | } |
| 337 | } |
| 338 | |
| 339 | impl FromRaw<ffi::libinput_event_tablet_tool> for TabletToolEvent { |
| 340 | unsafe fn try_from_raw( |
| 341 | event: *mut ffi::libinput_event_tablet_tool, |
| 342 | context: &Libinput, |
| 343 | ) -> Option<Self> { |
| 344 | let base = ffi::libinput_event_tablet_tool_get_base_event(event); |
| 345 | match ffi::libinput_event_get_type(base) { |
| 346 | ffi::libinput_event_type_LIBINPUT_EVENT_TABLET_TOOL_AXIS => Some( |
| 347 | TabletToolEvent::Axis(TabletToolAxisEvent::try_from_raw(event, context)?), |
| 348 | ), |
| 349 | ffi::libinput_event_type_LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY => Some( |
| 350 | TabletToolEvent::Proximity(TabletToolProximityEvent::try_from_raw(event, context)?), |
| 351 | ), |
| 352 | ffi::libinput_event_type_LIBINPUT_EVENT_TABLET_TOOL_TIP => Some(TabletToolEvent::Tip( |
| 353 | TabletToolTipEvent::try_from_raw(event, context)?, |
| 354 | )), |
| 355 | ffi::libinput_event_type_LIBINPUT_EVENT_TABLET_TOOL_BUTTON => Some( |
| 356 | TabletToolEvent::Button(TabletToolButtonEvent::try_from_raw(event, context)?), |
| 357 | ), |
| 358 | _ => None, |
| 359 | } |
| 360 | } |
| 361 | unsafe fn from_raw(event: *mut ffi::libinput_event_tablet_tool, context: &Libinput) -> Self { |
| 362 | Self::try_from_raw(event, context).expect("Unknown tablet tool event type" ) |
| 363 | } |
| 364 | } |
| 365 | |
| 366 | impl AsRaw<ffi::libinput_event_tablet_tool> for TabletToolEvent { |
| 367 | fn as_raw(&self) -> *const ffi::libinput_event_tablet_tool { |
| 368 | match self { |
| 369 | TabletToolEvent::Axis(event: &TabletToolAxisEvent) => event.as_raw(), |
| 370 | TabletToolEvent::Proximity(event: &TabletToolProximityEvent) => event.as_raw(), |
| 371 | TabletToolEvent::Tip(event: &TabletToolTipEvent) => event.as_raw(), |
| 372 | TabletToolEvent::Button(event: &TabletToolButtonEvent) => event.as_raw(), |
| 373 | } |
| 374 | } |
| 375 | } |
| 376 | |
| 377 | impl Context for TabletToolEvent { |
| 378 | fn context(&self) -> &Libinput { |
| 379 | match self { |
| 380 | TabletToolEvent::Axis(event: &TabletToolAxisEvent) => event.context(), |
| 381 | TabletToolEvent::Proximity(event: &TabletToolProximityEvent) => event.context(), |
| 382 | TabletToolEvent::Tip(event: &TabletToolTipEvent) => event.context(), |
| 383 | TabletToolEvent::Button(event: &TabletToolButtonEvent) => event.context(), |
| 384 | } |
| 385 | } |
| 386 | } |
| 387 | |
| 388 | ffi_event_struct! { |
| 389 | /// One or more axes have changed state on a device with the |
| 390 | /// `DeviceCapability::TabletTool` capability. |
| 391 | /// |
| 392 | /// This event is only sent when the tool is in proximity, see |
| 393 | /// `TabletToolProximityEvent` for details. |
| 394 | /// |
| 395 | /// The proximity event contains the initial state of the axis as the tool comes into |
| 396 | /// proximity. An event of type `TabletToolAxisEvent` is only sent when an axis value |
| 397 | /// changes from this initial state. It is possible for a tool to enter and leave |
| 398 | /// proximity without sending an event of type `TabletToolAxisEvent`. |
| 399 | /// |
| 400 | /// An event of type `TabletToolAxisEvent` is sent when the tip state does not |
| 401 | /// change. See the documentation for `TabletToolTipEvent` for more details. |
| 402 | struct TabletToolAxisEvent, ffi::libinput_event_tablet_tool, ffi::libinput_event_tablet_tool_get_base_event |
| 403 | } |
| 404 | |
| 405 | /// The state of proximity for a tool on a device. |
| 406 | /// |
| 407 | /// The proximity of a tool is a binary state signalling whether the tool is within a |
| 408 | /// detectable distance of the tablet device. A tool that is out of proximity cannot |
| 409 | /// generate events. |
| 410 | /// |
| 411 | /// On some hardware a tool goes out of proximity when it ceases to touch the surface. On /// other hardware, the tool is still detectable within a short distance (a few cm) off |
| 412 | /// the surface. |
| 413 | #[derive (Debug, Clone, Copy, PartialEq, Eq, Hash)] |
| 414 | pub enum ProximityState { |
| 415 | /// Out of proximity |
| 416 | Out, |
| 417 | /// In proximity |
| 418 | In, |
| 419 | } |
| 420 | |
| 421 | ffi_event_struct! { |
| 422 | /// Signals that a tool has come in or out of proximity of a device with the |
| 423 | /// `DeviceCapability::TabletTool` capability. |
| 424 | /// |
| 425 | /// Proximity events contain each of the current values for each axis, and these |
| 426 | /// values may be extracted from them in the same way they are with |
| 427 | /// `TabletToolAxisEvent` events. |
| 428 | /// |
| 429 | /// Some tools may always be in proximity. For these tools, proximity events with |
| 430 | /// `ProximityState::In` are sent only once after `DeviceAddedEvent`, and proximity |
| 431 | /// events with `ProximityState::Out` are sent only once before `DeviceRemovedEvent`. |
| 432 | /// |
| 433 | /// If the tool that comes into proximity supports x/y coordinates, libinput |
| 434 | /// guarantees that both x and y are set in the proximity event. |
| 435 | /// |
| 436 | /// When a tool goes out of proximity, the value of every axis should be assumed to |
| 437 | /// have an undefined state and any buttons that are currently held down on the |
| 438 | /// stylus are marked as released. Button release events for each button that was |
| 439 | /// held down on the stylus are sent before the proximity out event. |
| 440 | struct TabletToolProximityEvent, ffi::libinput_event_tablet_tool, ffi::libinput_event_tablet_tool_get_base_event |
| 441 | } |
| 442 | |
| 443 | impl TabletToolProximityEvent { |
| 444 | /// Returns the new proximity state of a tool from a proximity event. |
| 445 | /// |
| 446 | /// Used to check whether or not a tool came in or out of proximity during an |
| 447 | /// `TabletToolProximityEvent`. |
| 448 | /// |
| 449 | /// See [Handling of proximity events](https://wayland.freedesktop.org/libinput/doc/latest/tablet-support.html#tablet-fake-proximity) |
| 450 | /// for recommendations on proximity handling. |
| 451 | pub fn proximity_state(&self) -> ProximityState { |
| 452 | match unsafe { ffi::libinput_event_tablet_tool_get_proximity_state(self.as_raw_mut()) } { |
| 453 | ffi::libinput_tablet_tool_proximity_state_LIBINPUT_TABLET_TOOL_PROXIMITY_STATE_OUT => { |
| 454 | ProximityState::Out |
| 455 | } |
| 456 | ffi::libinput_tablet_tool_proximity_state_LIBINPUT_TABLET_TOOL_PROXIMITY_STATE_IN => { |
| 457 | ProximityState::In |
| 458 | } |
| 459 | _ => panic!("libinput returned invalid 'libinput_tablet_tool_proximity_state'" ), |
| 460 | } |
| 461 | } |
| 462 | } |
| 463 | |
| 464 | /// The tip contact state for a tool on a device. |
| 465 | /// |
| 466 | /// The tip contact state of a tool is a binary state signalling whether the tool is |
| 467 | /// touching the surface of the tablet device. |
| 468 | #[derive (Debug, Clone, Copy, PartialEq, Eq, Hash)] |
| 469 | pub enum TipState { |
| 470 | /// Not touching the surface |
| 471 | Up, |
| 472 | /// Touching the surface |
| 473 | Down, |
| 474 | } |
| 475 | |
| 476 | ffi_event_struct! { |
| 477 | /// Signals that a tool has come in contact with the surface of a device with the |
| 478 | /// `DeviceCapability::TabletTool` capability. |
| 479 | /// |
| 480 | /// On devices without distance proximity detection, the `TabletToolTipEvent` is sent |
| 481 | /// immediately after `TabletToolProximityEvent` for the tip down event, and |
| 482 | /// immediately before for the tip up event. |
| 483 | /// |
| 484 | /// The decision when a tip touches the surface is device-dependent and may be |
| 485 | /// derived from pressure data or other means. If the tip state is changed by axes |
| 486 | /// changing state, the `TabletToolTipEvent` includes the changed axes and no |
| 487 | /// additional axis event is sent for this state change. In other words, a caller |
| 488 | /// must look at both `TabletToolAxisEvent` and `TabletToolTipEvent` events to know |
| 489 | /// the current state of the axes. |
| 490 | /// |
| 491 | /// If a button state change occurs at the same time as a tip state change, the order |
| 492 | /// of events is device-dependent. |
| 493 | struct TabletToolTipEvent, ffi::libinput_event_tablet_tool, ffi::libinput_event_tablet_tool_get_base_event |
| 494 | } |
| 495 | |
| 496 | impl TabletToolTipEvent { |
| 497 | /// Returns the new tip state of a tool from a tip event. |
| 498 | /// |
| 499 | /// Used to check whether or not a tool came in contact with the tablet surface or |
| 500 | /// left contact with the tablet surface during an `TabletToolTipEvent`. |
| 501 | pub fn tip_state(&self) -> TipState { |
| 502 | match unsafe { ffi::libinput_event_tablet_tool_get_tip_state(self.as_raw_mut()) } { |
| 503 | ffi::libinput_tablet_tool_tip_state_LIBINPUT_TABLET_TOOL_TIP_UP => TipState::Up, |
| 504 | ffi::libinput_tablet_tool_tip_state_LIBINPUT_TABLET_TOOL_TIP_DOWN => TipState::Down, |
| 505 | _ => panic!("libinput returned invalid 'libinput_tablet_tool_top_state'" ), |
| 506 | } |
| 507 | } |
| 508 | } |
| 509 | |
| 510 | ffi_event_struct! { |
| 511 | /// Signals that a tool has changed a logical button state on a device with the |
| 512 | /// `DeviceCapability::TabletTool` capability. |
| 513 | /// |
| 514 | /// Button state changes occur on their own and do not include axis state changes. If |
| 515 | /// button and axis state changes occur within the same logical hardware event, the |
| 516 | /// order of the `TabletToolButtonEvent` and `TabletToolAxisEvent` is device-specific. |
| 517 | /// |
| 518 | /// This event is not to be confused with the button events emitted by the tablet |
| 519 | /// pad. See `TabletPadButtonEvent`. |
| 520 | struct TabletToolButtonEvent, ffi::libinput_event_tablet_tool, ffi::libinput_event_tablet_tool_get_base_event |
| 521 | } |
| 522 | |
| 523 | impl TabletToolButtonEvent { |
| 524 | ffi_func!( |
| 525 | /// Return the button that triggered this event. |
| 526 | pub fn button, ffi::libinput_event_tablet_tool_get_button, u32); |
| 527 | ffi_func!( |
| 528 | /// For the button of a `TabletToolButtonEvent`, return the total number of buttons |
| 529 | /// pressed on all devices on the associated seat after the the event was triggered. |
| 530 | pub fn seat_button_count, ffi::libinput_event_tablet_tool_get_seat_button_count, u32); |
| 531 | |
| 532 | /// Return the button state of the event. |
| 533 | pub fn button_state(&self) -> ButtonState { |
| 534 | match unsafe { ffi::libinput_event_tablet_tool_get_button_state(self.as_raw_mut()) } { |
| 535 | ffi::libinput_button_state_LIBINPUT_BUTTON_STATE_PRESSED => ButtonState::Pressed, |
| 536 | ffi::libinput_button_state_LIBINPUT_BUTTON_STATE_RELEASED => ButtonState::Released, |
| 537 | _ => panic!("libinput returned invalid 'libinput_button_state'" ), |
| 538 | } |
| 539 | } |
| 540 | } |
| 541 | |