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