• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 //!
17 use hilog_rust::{error, hilog, info, HiLogLabel, LogType};
18 use std::ffi::{c_char, CString};
19 use std::sync::Once;
20 
21 const LOG_LABEL: HiLogLabel = HiLogLabel {
22     log_type: LogType::LogCore,
23     domain: 0xd002800,
24     tag: "MMIRustLib",
25 };
26 
27 static DOUBLE_ZERO: f64 = 1e-6;
28 static RET_OK: i32 = 0;
29 static RET_ERR: i32 = -1;
30 
31 struct CurveItem {
32     pub speeds: Vec<i32>,
33     pub slopes: Vec<f64>,
34     pub diff_nums: Vec<f64>,
35 }
36 struct AccelerateCurves {
37     data: Vec<CurveItem>,
38 }
39 impl AccelerateCurves {
get_curve_by_speed(&self, speed: usize) -> &CurveItem40     fn get_curve_by_speed(&self, speed: usize) -> &CurveItem {
41         &self.data[speed - 1]
42     }
43 }
44 impl AccelerateCurves {
get_instance() -> &'static AccelerateCurves45     fn get_instance() -> &'static AccelerateCurves {
46         static mut GLOBAL_CURVES: Option<AccelerateCurves> = None;
47         static ONCE: Once = Once::new();
48 
49         ONCE.call_once(|| unsafe {
50             GLOBAL_CURVES = Some(AccelerateCurves {
51                 data: vec![
52                     CurveItem {
53                         speeds: vec![8, 32, 128],
54                         slopes: vec![0.16, 0.30, 0.56],
55                         diff_nums: vec![0.0, -1.12, -9.44],
56                     },
57                     CurveItem {
58                         speeds: vec![8, 32, 128],
59                         slopes: vec![0.32, 0.60, 1.12],
60                         diff_nums: vec![0.0, -2.24, -18.88],
61                     },
62                     CurveItem {
63                         speeds: vec![8, 32, 128],
64                         slopes: vec![0.48, 0.90, 1.68],
65                         diff_nums: vec![0.0, -3.36, -28.32],
66                     },
67                     CurveItem {
68                         speeds: vec![8, 32, 128],
69                         slopes: vec![0.64, 1.20, 2.24],
70                         diff_nums: vec![0.0, -4.48, -37.76],
71                     },
72                     CurveItem {
73                         speeds: vec![8, 32, 128],
74                         slopes: vec![0.80, 1.50, 2.80],
75                         diff_nums: vec![0.0, -5.60, -47.20],
76                     },
77                     CurveItem {
78                         speeds: vec![8, 32, 128],
79                         slopes: vec![0.86, 1.95, 3.64],
80                         diff_nums: vec![0.0, -8.72, -62.80],
81                     },
82                     CurveItem {
83                         speeds: vec![8, 32, 128],
84                         slopes: vec![0.92, 2.40, 4.48],
85                         diff_nums: vec![0.0, -11.84, -78.40],
86                     },
87                     CurveItem {
88                         speeds: vec![8, 32, 128],
89                         slopes: vec![0.98, 2.85, 5.32],
90                         diff_nums: vec![0.0, -14.96, -94.00],
91                     },
92                     CurveItem {
93                         speeds: vec![8, 32, 128],
94                         slopes: vec![1.04, 3.30, 6.16],
95                         diff_nums: vec![0.0, -18.08, -109.60],
96                     },
97                     CurveItem {
98                         speeds: vec![8, 32, 128],
99                         slopes: vec![1.10, 3.75, 7.00],
100                         diff_nums: vec![0.0, -21.20, -125.20],
101                     },
102                     CurveItem {
103                         speeds: vec![8, 32, 128],
104                         slopes: vec![1.16, 4.20, 7.84],
105                         diff_nums: vec![0.0, -24.32, -140.80],
106                     },
107                 ],
108             });
109         });
110         unsafe { GLOBAL_CURVES.as_ref().unwrap() }
111     }
112 }
113 
114 // 这个 extern 代码块链接到 libm 库
115 #[link(name = "m")]
116 extern {
fabs(z: f64) -> f64117     fn fabs(z: f64) -> f64;
ceil(z: f64) -> f64118     fn ceil(z: f64) -> f64;
fmax(a: f64, b: f64) -> f64119     fn fmax(a: f64, b: f64) -> f64;
fmin(a: f64, b: f64) -> f64120     fn fmin(a: f64, b: f64) -> f64;
121 }
122 
get_speed_gain(vin: f64, gain: *mut f64, speed: i32) -> bool123 fn get_speed_gain(vin: f64, gain: *mut f64, speed: i32) -> bool {
124     info!(LOG_LABEL, "get_speed_gain enter vin is set to {} speed {} ", @public(vin), @public(speed));
125     unsafe {
126         if fabs(vin) < DOUBLE_ZERO {
127             error!(LOG_LABEL, "{} less that the limit", DOUBLE_ZERO);
128             return false;
129         }
130     }
131     if speed < 1 {
132         error!(LOG_LABEL, "{} The speed value can't be less than 1", @public(speed));
133         return false;
134     }
135     let item = AccelerateCurves::get_instance().get_curve_by_speed(speed as usize);
136     unsafe {
137         let num: i32 = ceil(fabs(vin)) as i32;
138         for i in 0..3 {
139             if num <= item.speeds[i] {
140                 *gain = (item.slopes[i] * vin + item.diff_nums[i]) / vin;
141                 info!(LOG_LABEL, "gain is set to {}", @public(*gain));
142                 return true;
143             }
144         }
145         *gain = (item.slopes[2] * vin + item.diff_nums[2]) / vin;
146         info!(LOG_LABEL, "gain is set to {}", @public(*gain));
147     }
148     info!(LOG_LABEL, "get_speed_gain leave");
149     true
150 }
151 
152 /// Offset struct is defined in C++, which give the vlaue
153 /// dx = libinput_event_pointer_get_dx
154 /// dy = libinput_event_pointer_get_dy
155 #[repr(C)]
156 pub struct Offset {
157     dx: f64,
158     dy: f64,
159 }
160 
161 /// # Safety
162 /// HandleMotionAccelerate is the origin C++ function name
163 /// C++ will call for rust realization using this name
164 #[no_mangle]
HandleMotionAccelerate( offset: *const Offset, mode: bool, abs_x: *mut f64, abs_y: *mut f64, speed: i32, ) -> i32165 pub unsafe extern "C" fn HandleMotionAccelerate (
166     offset: *const Offset,
167     mode: bool,
168     abs_x: *mut f64,
169     abs_y: *mut f64,
170     speed: i32,
171 ) -> i32 {
172     let mut gain = 0.0;
173     let vin: f64;
174     let dx: f64;
175     let dy: f64;
176     unsafe {
177         dx = (*offset).dx;
178         dy = (*offset).dy;
179         vin = (fmax(fabs(dx), fabs(dy)) + fmin(fabs(dx), fabs(dy))) / 2.0;
180         info!(
181             LOG_LABEL,
182             "output the abs_x {} and abs_y {} captureMode {} dx {} dy {} gain {}",
183             @public(*abs_x),
184             @public(*abs_y),
185             @public(mode),
186             @public(dx),
187             @public(dy),
188             @public(gain)
189         );
190         if !get_speed_gain(vin, &mut gain as *mut f64, speed) {
191             error!(LOG_LABEL, "{} getSpeedGgain failed!", @public(speed));
192             return RET_ERR;
193         }
194         if !mode {
195             *abs_x += dx * gain;
196             *abs_y += dy * gain;
197         }
198         info!(
199             LOG_LABEL,
200             "output the abs_x {} and abs_y {}", @public(*abs_x), @public(*abs_y)
201         );
202     }
203     RET_OK
204 }
205 
206 #[test]
test_handle_motion_accelerate_normal()207 fn test_handle_motion_accelerate_normal()
208 {
209     let offset: Offset = Offset{ dx: 0.00002, dy: 1.00004 };
210     let mut abs_x: f64 = 0.0;
211     let mut abs_y: f64 = 0.0;
212     let ret: i32;
213     unsafe {
214         ret = HandleMotionAccelerate(&offset, false, &mut abs_x as *mut f64, &mut abs_y as *mut f64, 2);
215     }
216     assert_eq!(ret, RET_OK);
217 }
218 
219 #[test]
test_handle_motion_accelerate_mini_limit()220 fn test_handle_motion_accelerate_mini_limit()
221 {
222     let offset: Offset = Offset{ dx: 0.00000001, dy: 0.00000002 };
223     let mut abs_x: f64 = 0.0;
224     let mut abs_y: f64 = 0.0;
225     let ret: i32;
226     unsafe {
227         ret = HandleMotionAccelerate(&offset, false, &mut abs_x as *mut f64, &mut abs_y as *mut f64, 2);
228     }
229     assert_eq!(ret, RET_ERR);
230 }
231 
232 #[test]
test_handle_motion_accelerate_capture_mode_false()233 fn test_handle_motion_accelerate_capture_mode_false()
234 {
235     let offset: Offset = Offset{ dx: 0.00002, dy: 1.00004 };
236     let mut abs_x: f64 = 0.0;
237     let mut abs_y: f64 = 0.0;
238     let ret: i32;
239     unsafe {
240         ret = HandleMotionAccelerate(&offset, true, &mut abs_x as *mut f64, &mut abs_y as *mut f64, 2);
241     }
242     assert_eq!(ret, RET_OK);
243     assert_eq!(abs_x, 0.0);
244     assert_eq!(abs_y, 0.0);
245 }
246