Skip to main content

input_pipeline/
utils.rs

1// Copyright 2020 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5// TODO(https://fxbug.dev/494333485): Delete this module in favor of using the autogenerated
6// fidl_next conversions, once available.
7
8use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Sub, SubAssign};
9use zx;
10
11// TODO: b/513635934 - remove this when we can move the value from wire type table.
12pub fn duplicate_wake_lease(
13    wake_lease: Option<&fidl_next::wire::fuchsia::EventPair>,
14) -> Option<zx::EventPair> {
15    wake_lease.map(|h| h.as_raw_handle()).map(|raw| {
16        // SAFETY: `raw` is a valid handle obtained from `wake_lease`, which is borrowed
17        // for the duration of this function. The `zx::Unowned` instance is created from
18        // this valid handle and does not outlive the borrow of `wake_lease`, ensuring
19        // that the handle remains valid while `Unowned` exists.
20        let unowned = unsafe { zx::Unowned::<'_, zx::EventPair>::from_raw_handle(raw) };
21        unowned.duplicate_handle(zx::Rights::SAME_RIGHTS).expect("failed to duplicate wake lease")
22    })
23}
24
25pub fn duplicate_view_ref_next(
26    view_ref: &fidl_next_fuchsia_ui_views::ViewRef,
27) -> Result<fidl_next_fuchsia_ui_views::ViewRef, fidl::Status> {
28    let handle = view_ref.reference.as_handle_ref().duplicate_handle(fidl::Rights::SAME_RIGHTS)?;
29    Ok(fidl_next_fuchsia_ui_views::ViewRef { reference: handle.into() })
30}
31
32pub fn axis_to_next(
33    axis: Option<&fidl_fuchsia_input_report::Axis>,
34) -> Option<fidl_next_fuchsia_input_report::Axis> {
35    axis.map(|a| fidl_next_fuchsia_input_report::Axis {
36        range: fidl_next_fuchsia_input_report::Range { min: a.range.min, max: a.range.max },
37        unit: fidl_next_fuchsia_input_report::Unit {
38            type_: a.unit.type_.into_primitive().into(),
39            exponent: a.unit.exponent,
40        },
41    })
42}
43
44pub fn axis_to_old(
45    axis: Option<&fidl_next_fuchsia_input_report::Axis>,
46) -> Option<fidl_fuchsia_input_report::Axis> {
47    axis.map(|a| fidl_fuchsia_input_report::Axis {
48        range: fidl_fuchsia_input_report::Range { min: a.range.min, max: a.range.max },
49        unit: unit_to_old(&a.unit),
50    })
51}
52
53pub fn viewport_to_next(
54    viewport: &fidl_fuchsia_ui_pointerinjector::Viewport,
55) -> fidl_next_fuchsia_ui_pointerinjector::Viewport {
56    fidl_next_fuchsia_ui_pointerinjector::Viewport {
57        extents: viewport.extents.clone(),
58        viewport_to_context_transform: viewport.viewport_to_context_transform.clone(),
59    }
60}
61
62pub fn range_to_old(
63    range: &fidl_next_fuchsia_input_report::Range,
64) -> fidl_fuchsia_input_report::Range {
65    fidl_fuchsia_input_report::Range { min: range.min, max: range.max }
66}
67
68pub fn unit_to_old(unit: &fidl_next_fuchsia_input_report::Unit) -> fidl_fuchsia_input_report::Unit {
69    // SAFETY: The `fidl_next` generated enum is representation-compatible with `u32`
70    // (typically `#[repr(u32)]`). Casting the pointer to `*const u32` and dereferencing
71    // it is safe because the memory is initialized, aligned correctly, and we only
72    // perform a read operation.
73    let discriminant: u32 =
74        unsafe { *(&unit.type_ as *const fidl_next_fuchsia_input_report::UnitType as *const u32) };
75    fidl_fuchsia_input_report::Unit {
76        type_: fidl_fuchsia_input_report::UnitType::from_primitive_allow_unknown(discriminant),
77        exponent: unit.exponent,
78    }
79}
80
81pub fn key_to_old(key: &fidl_next_fuchsia_input::Key) -> fidl_fuchsia_input::Key {
82    // SAFETY: The `fidl_next` generated enum is representation-compatible with `u32`
83    // (typically `#[repr(u32)]`). Casting the pointer to `*const u32` and dereferencing
84    // it is safe because the memory is initialized, aligned correctly, and we only
85    // perform a read operation.
86    let discriminant: u32 = unsafe { *(key as *const fidl_next_fuchsia_input::Key as *const u32) };
87    fidl_fuchsia_input::Key::from_primitive_allow_unknown(discriminant)
88}
89
90#[cfg(test)]
91pub fn key_to_next(key: &fidl_fuchsia_input::Key) -> fidl_next_fuchsia_input::Key {
92    let discriminant = key.into_primitive();
93    fidl_next_fuchsia_input::Key::from(discriminant)
94}
95
96#[cfg(test)]
97pub fn touch_button_to_next(
98    button: &fidl_fuchsia_input_report::TouchButton,
99) -> fidl_next_fuchsia_input_report::TouchButton {
100    let discriminant = button.into_primitive();
101    fidl_next_fuchsia_input_report::TouchButton::from(discriminant)
102}
103
104pub fn consumer_control_button_to_old(
105    button: &fidl_next_fuchsia_input_report::ConsumerControlButton,
106) -> fidl_fuchsia_input_report::ConsumerControlButton {
107    // SAFETY: The `fidl_next` generated enum is representation-compatible with `u32`
108    // (typically `#[repr(u32)]`). Casting the pointer to `*const u32` and dereferencing
109    // it is safe because the memory is initialized, aligned correctly, and we only
110    // perform a read operation.
111    let discriminant: u32 = unsafe {
112        *(button as *const fidl_next_fuchsia_input_report::ConsumerControlButton as *const u32)
113    };
114    fidl_fuchsia_input_report::ConsumerControlButton::from_primitive_allow_unknown(discriminant)
115}
116
117#[cfg(test)]
118pub fn consumer_control_button_to_next(
119    button: &fidl_fuchsia_input_report::ConsumerControlButton,
120) -> fidl_next_fuchsia_input_report::ConsumerControlButton {
121    let discriminant = button.into_primitive();
122    fidl_next_fuchsia_input_report::ConsumerControlButton::from(discriminant)
123}
124
125/// Cursor messages.
126#[derive(Debug, PartialEq)]
127pub enum CursorMessage {
128    /// Set the position of the cursor.
129    SetPosition(Position),
130    /// Set the visibility of the cursor.
131    SetVisibility(bool),
132}
133
134/// Represents a generic 2D position.
135#[derive(Clone, Copy, Debug, PartialEq)]
136pub struct Position {
137    /// The x component of the position, in pixels.
138    pub x: f32,
139
140    /// The y component of the position, in pixels.
141    pub y: f32,
142}
143
144impl Position {
145    pub fn clamp(target: &mut Position, min: Position, max: Position) {
146        if (*target).x < min.x {
147            (*target).x = min.x;
148        }
149        if (*target).x > max.x {
150            (*target).x = max.x;
151        }
152
153        if (*target).y < min.y {
154            (*target).y = min.y;
155        }
156        if (*target).y > max.y {
157            (*target).y = max.y;
158        }
159    }
160
161    pub fn clamp_size(target: &mut Position, min: Size, max: Size) {
162        if (*target).x < min.width {
163            (*target).x = min.width;
164        }
165        if (*target).x > max.width {
166            (*target).x = max.width;
167        }
168
169        if (*target).y < min.height {
170            (*target).y = min.height;
171        }
172        if (*target).y > max.height {
173            (*target).y = max.height;
174        }
175    }
176
177    pub fn zero() -> Position {
178        Position { x: 0.0, y: 0.0 }
179    }
180}
181
182impl Add for Position {
183    type Output = Self;
184
185    #[inline]
186    fn add(self, other: Self) -> Self {
187        Self { x: self.x + other.x, y: self.y + other.y }
188    }
189}
190
191impl AddAssign for Position {
192    #[inline]
193    fn add_assign(&mut self, other: Self) {
194        *self = Self { x: self.x + other.x, y: self.y + other.y };
195    }
196}
197
198impl Sub for Position {
199    type Output = Self;
200
201    #[inline]
202    fn sub(self, other: Self) -> Self {
203        Self { x: self.x - other.x, y: self.y - other.y }
204    }
205}
206
207impl SubAssign for Position {
208    #[inline]
209    fn sub_assign(&mut self, other: Self) {
210        *self = Self { x: self.x - other.x, y: self.y - other.y };
211    }
212}
213
214impl Div for Position {
215    type Output = Self;
216
217    #[inline]
218    fn div(self, other: Self) -> Self {
219        Self { x: self.x / other.x, y: self.y / other.y }
220    }
221}
222
223impl DivAssign for Position {
224    #[inline]
225    fn div_assign(&mut self, other: Self) {
226        *self = Self { x: self.x / other.x, y: self.y / other.y };
227    }
228}
229
230impl Mul for Position {
231    type Output = Self;
232
233    #[inline]
234    fn mul(self, other: Self) -> Self {
235        Self { x: self.x * other.x, y: self.y * other.y }
236    }
237}
238
239impl MulAssign for Position {
240    #[inline]
241    fn mul_assign(&mut self, other: Self) {
242        *self = Self { x: self.x * other.x, y: self.y * other.y };
243    }
244}
245
246impl Mul<Size> for Position {
247    type Output = Self;
248
249    #[inline]
250    fn mul(self, other: Size) -> Position {
251        Self { x: self.x * other.width, y: self.y * other.height }
252    }
253}
254
255macro_rules! scale_position_impl {
256    ($($t:ty)*) => ($(
257        impl Div<$t> for Position {
258            type Output = Position;
259
260            #[inline]
261            fn div(self, other: $t) -> Position {
262                Self { x: self.x / other as f32, y: self.y / other as f32 }
263            }
264        }
265
266        impl DivAssign<$t> for Position {
267            #[inline]
268            fn div_assign(&mut self, other: $t) {
269                *self = Self { x: self.x / other as f32, y: self.y / other as f32 };
270            }
271        }
272
273        impl Mul<$t> for Position {
274            type Output = Position;
275
276            #[inline]
277            fn mul(self, other: $t) -> Position {
278                Self { x: self.x * other as f32, y: self.y * other as f32 }
279            }
280        }
281
282        impl Mul<Position> for $t {
283            type Output = Position;
284
285            #[inline]
286            fn mul(self, other: Position) -> Position {
287                Position { x: self as f32 * other.x, y: self as f32 * other.y }
288            }
289        }
290
291        impl MulAssign<$t> for Position {
292            #[inline]
293            fn mul_assign(&mut self, other: $t) {
294                *self = Self { x: self.x * other as f32, y: self.y * other as f32 };
295            }
296        }
297    )*)
298}
299
300scale_position_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
301
302/// Represents a generic size.
303#[derive(Clone, Copy, Debug, PartialEq)]
304pub struct Size {
305    /// The width in pixels.
306    pub width: f32,
307
308    /// The height in pixels.
309    pub height: f32,
310}
311
312impl Size {
313    pub fn zero() -> Size {
314        Size { width: 0.0, height: 0.0 }
315    }
316}
317
318impl Add for Size {
319    type Output = Self;
320
321    #[inline]
322    fn add(self, other: Self) -> Self {
323        Self { width: self.width + other.width, height: self.height + other.height }
324    }
325}
326
327impl AddAssign for Size {
328    #[inline]
329    fn add_assign(&mut self, other: Self) {
330        *self = Self { width: self.width + other.width, height: self.height + other.height };
331    }
332}
333
334impl Sub for Size {
335    type Output = Self;
336
337    #[inline]
338    fn sub(self, other: Self) -> Self {
339        Self { width: self.width - other.width, height: self.height - other.height }
340    }
341}
342
343impl SubAssign for Size {
344    fn sub_assign(&mut self, other: Self) {
345        *self = Self { width: self.width - other.width, height: self.height - other.height };
346    }
347}
348
349impl Div for Size {
350    type Output = Self;
351
352    #[inline]
353    fn div(self, other: Self) -> Self {
354        Self { width: self.width / other.width, height: self.height / other.height }
355    }
356}
357
358impl DivAssign for Size {
359    #[inline]
360    fn div_assign(&mut self, other: Self) {
361        *self = Self { width: self.width / other.width, height: self.height / other.height };
362    }
363}
364
365impl Mul for Size {
366    type Output = Self;
367
368    #[inline]
369    fn mul(self, other: Self) -> Self {
370        Self { width: self.width * other.width, height: self.height * other.height }
371    }
372}
373
374impl MulAssign for Size {
375    #[inline]
376    fn mul_assign(&mut self, other: Self) {
377        *self = Self { width: self.width * other.width, height: self.height * other.height };
378    }
379}
380
381macro_rules! scale_size_impl {
382    ($($t:ty)*) => ($(
383        impl Div<$t> for Size {
384            type Output = Size;
385
386            #[inline]
387            fn div(self, other: $t) -> Size {
388                Self { width: self.width / other as f32, height: self.height / other as f32 }
389            }
390        }
391
392        impl DivAssign<$t> for Size {
393            #[inline]
394            fn div_assign(&mut self, other: $t) {
395                *self = Self { width: self.width / other as f32, height: self.height / other as f32 };
396            }
397        }
398
399        impl Mul<$t> for Size {
400            type Output = Size;
401
402            #[inline]
403            fn mul(self, other: $t) -> Size {
404                Self { width: self.width * other as f32, height: self.height * other as f32 }
405            }
406        }
407
408        impl MulAssign<$t> for Size {
409            #[inline]
410            fn mul_assign(&mut self, other: $t) {
411                *self = Self { width: self.width * other as f32, height: self.height * other as f32 };
412            }
413        }
414    )*)
415}
416
417scale_size_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }