1 /*
2  * Copyright (C) 2019 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "CursorScrollAccumulator.h"
18 
19 #include <android_companion_virtualdevice_flags.h>
20 #include "EventHub.h"
21 #include "InputDevice.h"
22 
23 namespace android {
24 
25 namespace vd_flags = android::companion::virtualdevice::flags;
26 
CursorScrollAccumulator()27 CursorScrollAccumulator::CursorScrollAccumulator()
28       : mHaveRelWheel(false),
29         mHaveRelHWheel(false),
30         mHaveRelWheelHighRes(false),
31         mHaveRelHWheelHighRes(false) {
32     clearRelativeAxes();
33 }
34 
configure(InputDeviceContext & deviceContext)35 void CursorScrollAccumulator::configure(InputDeviceContext& deviceContext) {
36     mHaveRelWheel = deviceContext.hasRelativeAxis(REL_WHEEL);
37     mHaveRelHWheel = deviceContext.hasRelativeAxis(REL_HWHEEL);
38     if (vd_flags::high_resolution_scroll()) {
39         mHaveRelWheelHighRes = deviceContext.hasRelativeAxis(REL_WHEEL_HI_RES);
40         mHaveRelHWheelHighRes = deviceContext.hasRelativeAxis(REL_HWHEEL_HI_RES);
41     }
42 }
43 
reset(InputDeviceContext & deviceContext)44 void CursorScrollAccumulator::reset(InputDeviceContext& deviceContext) {
45     clearRelativeAxes();
46 }
47 
clearRelativeAxes()48 void CursorScrollAccumulator::clearRelativeAxes() {
49     mRelWheel = 0;
50     mRelHWheel = 0;
51 }
52 
process(const RawEvent & rawEvent)53 void CursorScrollAccumulator::process(const RawEvent& rawEvent) {
54     if (rawEvent.type == EV_REL) {
55         switch (rawEvent.code) {
56             case REL_WHEEL_HI_RES:
57                 if (mHaveRelWheelHighRes) {
58                     mRelWheel =
59                             rawEvent.value / static_cast<float>(kEvdevHighResScrollUnitsPerDetent);
60                 }
61                 break;
62             case REL_HWHEEL_HI_RES:
63                 if (mHaveRelHWheelHighRes) {
64                     mRelHWheel =
65                             rawEvent.value / static_cast<float>(kEvdevHighResScrollUnitsPerDetent);
66                 }
67                 break;
68             case REL_WHEEL:
69                 // We should ignore regular scroll events, if we have already have high-res scroll
70                 // enabled.
71                 if (!mHaveRelWheelHighRes) {
72                     mRelWheel = rawEvent.value;
73                 }
74                 break;
75             case REL_HWHEEL:
76                 // We should ignore regular scroll events, if we have already have high-res scroll
77                 // enabled.
78                 if (!mHaveRelHWheelHighRes) {
79                     mRelHWheel = rawEvent.value;
80                 }
81                 break;
82         }
83     }
84 }
85 
finishSync()86 void CursorScrollAccumulator::finishSync() {
87     clearRelativeAxes();
88 }
89 
90 } // namespace android
91