1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
//! Gesture event types

use super::EventTrait;
use {AsRaw, FromRaw};
use ffi;

/// Common functions all Gesture-Events implement.
pub trait GestureEventTrait: AsRaw<ffi::libinput_event_gesture> {
    ffi_func!(
    /// The event time for this event
    fn time, ffi::libinput_event_gesture_get_time, u32);
    ffi_func!(
    /// The event time for this event in microseconds
    fn time_usec, ffi::libinput_event_gesture_get_time_usec, u64);
    ffi_func!(
    /// Return the number of fingers used for a gesture.
    ///
    /// This can be used e.g. to differentiate between 3 or 4 finger swipes.
    ///
    /// This function can be called on all gesture events and the returned finger
    /// count value will not change during a sequence.
    fn finger_count, ffi::libinput_event_gesture_get_finger_count, i32);

    /// Convert into a general `GestureEvent` again
    fn into_gesture_event(self) -> GestureEvent
        where Self: Sized
    {
        unsafe { GestureEvent::from_raw(self.as_raw_mut()) }
    }
}

impl<T: AsRaw<ffi::libinput_event_gesture>> GestureEventTrait for T {}

/// A gesture related `Event`
#[derive(Debug, PartialEq, Eq, Hash)]
pub enum GestureEvent {
    /// A swipe gesture `Event`
    Swipe(GestureSwipeEvent),
    /// A pinch gesture `Event`
    Pinch(GesturePinchEvent),
}

impl EventTrait for GestureEvent {
    #[doc(hidden)]
    fn as_raw_event(&self) -> *mut ffi::libinput_event {
        match *self {
            GestureEvent::Swipe(ref event) => event.as_raw_event(),
            GestureEvent::Pinch(ref event) => event.as_raw_event(),
        }
    }
}

impl FromRaw<ffi::libinput_event_gesture> for GestureEvent {
    unsafe fn from_raw(event: *mut ffi::libinput_event_gesture) -> Self {
        let base = ffi::libinput_event_gesture_get_base_event(event);
        match ffi::libinput_event_get_type(base) {
            ffi::libinput_event_type::LIBINPUT_EVENT_GESTURE_SWIPE_BEGIN |
            ffi::libinput_event_type::LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE |
            ffi::libinput_event_type::LIBINPUT_EVENT_GESTURE_SWIPE_END => {
                GestureEvent::Swipe(GestureSwipeEvent::from_raw(event))
            }
            ffi::libinput_event_type::LIBINPUT_EVENT_GESTURE_PINCH_BEGIN |
            ffi::libinput_event_type::LIBINPUT_EVENT_GESTURE_PINCH_UPDATE |
            ffi::libinput_event_type::LIBINPUT_EVENT_GESTURE_PINCH_END => {
                GestureEvent::Pinch(GesturePinchEvent::from_raw(event))
            }
            _ => unreachable!(),
        }
    }
}

impl AsRaw<ffi::libinput_event_gesture> for GestureEvent {
    fn as_raw(&self) -> *const ffi::libinput_event_gesture {
        match *self {
            GestureEvent::Swipe(ref event) => event.as_raw(),
            GestureEvent::Pinch(ref event) => event.as_raw(),
        }
    }
}

/// Common functions for Gesture-Events having coordinates.
pub trait GestureEventCoordinates: AsRaw<ffi::libinput_event_gesture> {
    ffi_func!(
    /// Return the delta between the last event and the current event.
    ///
    /// If a device employs pointer acceleration, the delta returned by this
    /// function is the accelerated delta.
    ///
    /// Relative motion deltas are normalized to represent those of a device with
    /// 1000dpi resolution. See [Normalization of relative motion](https://wayland.freedesktop.org/libinput/doc/latest/motion_normalization.html)
    /// for more details.
    fn dx, ffi::libinput_event_gesture_get_dx, f64);
    ffi_func!(
    /// Return the relative delta of the unaccelerated motion vector of the
    /// current event.
    ///
    /// Relative unaccelerated motion deltas are normalized to represent those of
    /// a device with 1000dpi resolution. See [Normalization of relative motion](https://wayland.freedesktop.org/libinput/doc/latest/motion_normalization.html)
    /// for more details. Note that unaccelerated events are not equivalent to
    /// 'raw' events as read from the device.
    ///
    /// Any rotation applied to the device also applies to gesture motion (see
    /// `rotation_set_angle`).
    fn dx_unaccelerated, ffi::libinput_event_gesture_get_dx_unaccelerated, f64);
    ffi_func!(
    /// Return the delta between the last event and the current event.
    ///
    /// If a device employs pointer acceleration, the delta returned by this
    /// function is the accelerated delta.
    ///
    /// Relative motion deltas are normalized to represent those of a device with
    /// 1000dpi resolution. See [Normalization of relative motion](https://wayland.freedesktop.org/libinput/doc/latest/motion_normalization.html)
    /// for more details.
    fn dy, ffi::libinput_event_gesture_get_dy, f64);
    ffi_func!(
    /// Return the relative delta of the unaccelerated motion vector of the
    /// current event.
    ///
    /// Relative unaccelerated motion deltas are normalized to represent those of
    /// a device with 1000dpi resolution. See [Normalization of relative motion](https://wayland.freedesktop.org/libinput/doc/latest/motion_normalization.html)
    /// for more details. Note that unaccelerated events are not equivalent to
    /// 'raw' events as read from the device.
    ///
    /// Any rotation applied to the device also applies to gesture motion (see
    /// `rotation_set_angle`).
    fn dy_unaccelerated, ffi::libinput_event_gesture_get_dy_unaccelerated, f64);
}

/// Common functions for events noting the end of a gesture
pub trait GestureEndEvent: AsRaw<ffi::libinput_event_gesture> {
    ffi_func!(
    /// Return if the gesture ended normally, or if it was cancelled.
    fn cancelled, ffi::libinput_event_gesture_get_cancelled, bool);
}

/// Events for swipe gestures
#[derive(Debug, PartialEq, Eq, Hash)]
pub enum GestureSwipeEvent {
    /// Swipe gesture began
    Begin(GestureSwipeBeginEvent),
    /// In-progress swipe gesture updated
    Update(GestureSwipeUpdateEvent),
    /// Swipe gesture ended
    End(GestureSwipeEndEvent),
}

/// Common functions for swipe gesture events
pub trait GestureSwipeEventTrait: AsRaw<ffi::libinput_event_gesture> {
    /// Convert into a general `GestureSwipeEvent`
    fn into_gesture_swipe_event(self) -> GestureSwipeEvent
        where Self: Sized
    {
        unsafe { GestureSwipeEvent::from_raw(self.as_raw_mut()) }
    }
}

impl GestureSwipeEventTrait for GestureSwipeEvent {}

impl EventTrait for GestureSwipeEvent {
    #[doc(hidden)]
    fn as_raw_event(&self) -> *mut ffi::libinput_event {
        match *self {
            GestureSwipeEvent::Begin(ref event) => event.as_raw_event(),
            GestureSwipeEvent::Update(ref event) => event.as_raw_event(),
            GestureSwipeEvent::End(ref event) => event.as_raw_event(),
        }
    }
}

impl FromRaw<ffi::libinput_event_gesture> for GestureSwipeEvent {
    unsafe fn from_raw(event: *mut ffi::libinput_event_gesture) -> Self {
        let base = ffi::libinput_event_gesture_get_base_event(event);
        match ffi::libinput_event_get_type(base) {
            ffi::libinput_event_type::LIBINPUT_EVENT_GESTURE_SWIPE_BEGIN => {
                GestureSwipeEvent::Begin(GestureSwipeBeginEvent::from_raw(event))
            }
            ffi::libinput_event_type::LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE => {
                GestureSwipeEvent::Update(GestureSwipeUpdateEvent::from_raw(event))
            }
            ffi::libinput_event_type::LIBINPUT_EVENT_GESTURE_SWIPE_END => {
                GestureSwipeEvent::End(GestureSwipeEndEvent::from_raw(event))
            }
            ffi::libinput_event_type::LIBINPUT_EVENT_GESTURE_PINCH_BEGIN |
            ffi::libinput_event_type::LIBINPUT_EVENT_GESTURE_PINCH_UPDATE |
            ffi::libinput_event_type::LIBINPUT_EVENT_GESTURE_PINCH_END => {
                panic!("Tried to make GestureSwipeEvent from Pinch event")
            }
            _ => unreachable!(),
        }
    }
}

impl AsRaw<ffi::libinput_event_gesture> for GestureSwipeEvent {
    fn as_raw(&self) -> *const ffi::libinput_event_gesture {
        match *self {
            GestureSwipeEvent::Begin(ref event) => event.as_raw(),
            GestureSwipeEvent::Update(ref event) => event.as_raw(),
            GestureSwipeEvent::End(ref event) => event.as_raw(),
        }
    }
}

/// Events for pinch gestures
#[derive(Debug, PartialEq, Eq, Hash)]
pub enum GesturePinchEvent {
    /// Pinch gesture began
    Begin(GesturePinchBeginEvent),
    /// In-progress pinch gesture updated
    Update(GesturePinchUpdateEvent),
    /// Pinch gesture ended
    End(GesturePinchEndEvent),
}

impl EventTrait for GesturePinchEvent {
    #[doc(hidden)]
    fn as_raw_event(&self) -> *mut ffi::libinput_event {
        match *self {
            GesturePinchEvent::Begin(ref event) => event.as_raw_event(),
            GesturePinchEvent::Update(ref event) => event.as_raw_event(),
            GesturePinchEvent::End(ref event) => event.as_raw_event(),
        }
    }
}

/// Common functions for pinch gesture events
pub trait GesturePinchEventTrait: AsRaw<ffi::libinput_event_gesture> {
    ffi_func!(
    /// Return the absolute scale of a pinch gesture, the scale is the division of
    /// the current distance between the fingers and the distance at the start of
    /// the gesture.
    ///
    /// The scale begins at 1.0, and if e.g. the fingers moved together by 50%
    /// then the scale will become 0.5, if they move twice as far apart as
    /// initially the scale becomes 2.0, etc.
    ///
    /// For gesture events that are of type `GesturePinchBeginEvent`, this function
    /// returns 1.0.
    /// For gesture events that are of type `GesturePinchEndEvent`, this function
    /// returns the scale value of the most recent `GesturePinchUpdateEvent` event
    /// (if any) or 1.0 otherwise.
    fn scale, ffi::libinput_event_gesture_get_scale, f64);

    /// Convert into a general `GesturePinchEvent`
    fn into_gesture_pinch_event(self) -> GesturePinchEvent
        where Self: Sized
    {
        unsafe { GesturePinchEvent::from_raw(self.as_raw_mut()) }
    }
}

impl GesturePinchEventTrait for GesturePinchEvent {}

impl FromRaw<ffi::libinput_event_gesture> for GesturePinchEvent {
    unsafe fn from_raw(event: *mut ffi::libinput_event_gesture) -> Self {
        let base = ffi::libinput_event_gesture_get_base_event(event);
        match ffi::libinput_event_get_type(base) {
            ffi::libinput_event_type::LIBINPUT_EVENT_GESTURE_SWIPE_BEGIN |
            ffi::libinput_event_type::LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE |
            ffi::libinput_event_type::LIBINPUT_EVENT_GESTURE_SWIPE_END => {
                panic!("Tried to make GesturePinchEvent from Swipe event")
            }
            ffi::libinput_event_type::LIBINPUT_EVENT_GESTURE_PINCH_BEGIN => {
                GesturePinchEvent::Begin(GesturePinchBeginEvent::from_raw(event))
            }
            ffi::libinput_event_type::LIBINPUT_EVENT_GESTURE_PINCH_UPDATE => {
                GesturePinchEvent::Update(GesturePinchUpdateEvent::from_raw(event))
            }
            ffi::libinput_event_type::LIBINPUT_EVENT_GESTURE_PINCH_END => {
                GesturePinchEvent::End(GesturePinchEndEvent::from_raw(event))
            }
            _ => unreachable!(),
        }
    }
}

impl AsRaw<ffi::libinput_event_gesture> for GesturePinchEvent {
    fn as_raw(&self) -> *const ffi::libinput_event_gesture {
        match *self {
            GesturePinchEvent::Begin(ref event) => event.as_raw(),
            GesturePinchEvent::Update(ref event) => event.as_raw(),
            GesturePinchEvent::End(ref event) => event.as_raw(),
        }
    }
}

ffi_event_struct!(
/// Swipe gesture began
struct GestureSwipeBeginEvent, ffi::libinput_event_gesture, ffi::libinput_event_gesture_get_base_event);

impl GestureSwipeEventTrait for GestureSwipeBeginEvent {}

ffi_event_struct!(
/// In-progress swipe gesture updated
struct GestureSwipeUpdateEvent, ffi::libinput_event_gesture, ffi::libinput_event_gesture_get_base_event);

impl GestureSwipeEventTrait for GestureSwipeUpdateEvent {}

impl GestureEventCoordinates for GestureSwipeUpdateEvent {}

ffi_event_struct!(
/// Swipe gesture ended
struct GestureSwipeEndEvent, ffi::libinput_event_gesture, ffi::libinput_event_gesture_get_base_event);

impl GestureEndEvent for GestureSwipeEndEvent {}

impl GestureSwipeEventTrait for GestureSwipeEndEvent {}

ffi_event_struct!(
/// Pinch gesture began
struct GesturePinchBeginEvent, ffi::libinput_event_gesture, ffi::libinput_event_gesture_get_base_event);

impl GesturePinchEventTrait for GesturePinchBeginEvent {}

ffi_event_struct!(
/// In-progress pinch gesture updated
struct GesturePinchUpdateEvent, ffi::libinput_event_gesture, ffi::libinput_event_gesture_get_base_event);

impl GesturePinchEventTrait for GesturePinchUpdateEvent {}

impl GestureEventCoordinates for GesturePinchUpdateEvent {}

impl GesturePinchUpdateEvent {
    ffi_func!(
    /// Return the angle delta in degrees between the last and the current
    /// `GesturePinchUpdateEvent`.
    ///
    /// The angle delta is defined as the change in angle of the line formed by
    /// the 2 fingers of a pinch gesture. Clockwise rotation is represented by a
    /// positive delta, counter-clockwise by a negative delta. If e.g. the fingers
    /// are on the 12 and 6 location of a clock face plate and they move to the 1
    /// resp. 7 location in a single event then the angle delta is 30 degrees.
    ///
    /// If more than two fingers are present, the angle represents the rotation
    /// around the center of gravity. The calculation of the center of gravity is
    /// implementation-dependent.
    pub fn angle_delta, ffi::libinput_event_gesture_get_angle_delta, f64);
}

ffi_event_struct!(
/// Pinch gesture ended
struct GesturePinchEndEvent, ffi::libinput_event_gesture, ffi::libinput_event_gesture_get_base_event);

impl GesturePinchEventTrait for GesturePinchEndEvent {}

impl GestureEndEvent for GesturePinchEndEvent {}