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 #include "gesture_handler.h"
17
18 #include "mmi_log.h"
19
20 namespace OHOS {
21 namespace MMI {
22 namespace {
23 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { LOG_CORE, MMI_LOG_DOMAIN, "GestureHandler" };
24 constexpr int32_t FIRST_FINGER = 0;
25 constexpr int32_t SECOND_FINGER = 1;
26 constexpr int32_t TWO_FINGERS = 2;
27 constexpr double EFFECT_ANGLE = 5.0;
28 constexpr double FLAT_ANGLE = 180.0;
29 } // namespace
30
GestureHandler()31 GestureHandler::GestureHandler() {}
32
~GestureHandler()33 GestureHandler::~GestureHandler() {}
34
InitRotateGesture()35 void GestureHandler::InitRotateGesture()
36 {
37 isReady_ = false;
38 isStartRotate_ = false;
39 fingerDownPosition_.clear();
40 fingerCurrentPosition_.clear();
41 initialAngle_ = 0.0;
42 lastAngle_ = 0.0;
43 rotateAngle_ = 0.0;
44 }
45
GestureIdentify(int32_t originType,int32_t seatSlot,double logicalX,double logicalY)46 int32_t GestureHandler::GestureIdentify(int32_t originType, int32_t seatSlot, double logicalX, double logicalY)
47 {
48 int32_t gestureType = PointerEvent::POINTER_ACTION_UNKNOWN;
49 switch (originType) {
50 case LIBINPUT_EVENT_TOUCHPAD_DOWN: {
51 gestureType = HandleTouchPadDownEvent(seatSlot, logicalX, logicalY);
52 break;
53 }
54 case LIBINPUT_EVENT_TOUCHPAD_MOTION: {
55 gestureType = HandleTouchPadMoveEvent(seatSlot, logicalX, logicalY);
56 break;
57 }
58 case LIBINPUT_EVENT_TOUCHPAD_UP: {
59 gestureType = HandleTouchPadUpEvent(seatSlot);
60 break;
61 }
62 default: {
63 MMI_HILOGE("originType is invalid");
64 break;
65 }
66 }
67
68 return gestureType;
69 }
70
HandleTouchPadDownEvent(int32_t seatSlot,double logicalX,double logicalY)71 int32_t GestureHandler::HandleTouchPadDownEvent(int32_t seatSlot, double logicalX, double logicalY)
72 {
73 if (seatSlot < FIRST_FINGER || seatSlot > SECOND_FINGER) {
74 if (isStartRotate_) {
75 MMI_HILOGI("Exceed two fingers, rotate is end");
76 return PointerEvent::POINTER_ACTION_ROTATE_END;
77 }
78 if (isReady_) {
79 InitRotateGesture();
80 }
81 MMI_HILOGD("seatSlot is invalid");
82 return PointerEvent::POINTER_ACTION_UNKNOWN;
83 }
84
85 struct Position position;
86 position.x = logicalX;
87 position.y = logicalY;
88 fingerDownPosition_[seatSlot] = position;
89 if (fingerDownPosition_.size() == TWO_FINGERS) {
90 isReady_ = true;
91 initialAngle_ = CalculateAngle(fingerDownPosition_);
92 fingerCurrentPosition_ = fingerDownPosition_;
93 }
94 return PointerEvent::POINTER_ACTION_UNKNOWN;
95 }
96
HandleTouchPadMoveEvent(int32_t seatSlot,double logicalX,double logicalY)97 int32_t GestureHandler::HandleTouchPadMoveEvent(int32_t seatSlot, double logicalX, double logicalY)
98 {
99 if (!isReady_) {
100 MMI_HILOGD("Gesture event is not identified");
101 return PointerEvent::POINTER_ACTION_UNKNOWN;
102 }
103
104 struct Position position;
105 position.x = logicalX;
106 position.y = logicalY;
107 fingerCurrentPosition_[seatSlot] = position;
108 double currentAngle = CalculateAngle(fingerCurrentPosition_);
109 if (!isStartRotate_ && fabs(currentAngle - initialAngle_) >= EFFECT_ANGLE) {
110 initialAngle_ = currentAngle;
111 lastAngle_ = currentAngle;
112 isStartRotate_ = true;
113 MMI_HILOGI("Begin to rotate");
114 return PointerEvent::POINTER_ACTION_ROTATE_BEGIN;
115 }
116
117 if (isStartRotate_) {
118 rotateAngle_ += AdjustRotateAngle(currentAngle);
119 lastAngle_ = currentAngle;
120 return PointerEvent::POINTER_ACTION_ROTATE_UPDATE;
121 }
122 return PointerEvent::POINTER_ACTION_UNKNOWN;
123 }
124
HandleTouchPadUpEvent(int32_t seatSlot)125 int32_t GestureHandler::HandleTouchPadUpEvent(int32_t seatSlot)
126 {
127 if (isStartRotate_) {
128 isReady_ = false;
129 isStartRotate_ = false;
130 fingerDownPosition_.erase(seatSlot);
131 fingerCurrentPosition_.erase(seatSlot);
132 MMI_HILOGI("Rotate is end");
133 return PointerEvent::POINTER_ACTION_ROTATE_END;
134 }
135 InitRotateGesture();
136 return PointerEvent::POINTER_ACTION_UNKNOWN;
137 }
138
CalculateAngle(std::map<int32_t,struct Position> fingerPosition)139 double GestureHandler::CalculateAngle(std::map<int32_t, struct Position> fingerPosition)
140 {
141 double firstX = fingerPosition[FIRST_FINGER].x;
142 double firstY = fingerPosition[FIRST_FINGER].y;
143 double secondX = fingerPosition[SECOND_FINGER].x;
144 double secondY = fingerPosition[SECOND_FINGER].y;
145 double angle = atan2(firstY - secondY, firstX - secondX) * 180.0 / M_PI;
146 return angle;
147 }
148
AdjustRotateAngle(double currentAngle)149 double GestureHandler::AdjustRotateAngle(double currentAngle)
150 {
151 double angleIncrement = 0;
152 if (currentAngle - lastAngle_ >= FLAT_ANGLE) {
153 angleIncrement = (currentAngle - FLAT_ANGLE) - (lastAngle_ + FLAT_ANGLE);
154 } else if (lastAngle_ - currentAngle >= FLAT_ANGLE) {
155 angleIncrement = (currentAngle + FLAT_ANGLE) + (FLAT_ANGLE - lastAngle_);
156 } else {
157 angleIncrement = currentAngle - lastAngle_;
158 }
159 return angleIncrement;
160 }
161
GetRotateAngle()162 double GestureHandler::GetRotateAngle()
163 {
164 return rotateAngle_;
165 }
166 } // namespace MMI
167 } // namespace OHOS