• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 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 #include "input_event.h"
16 #include <cstdio>
17 #include <cstdlib>
18 #include "log/log.h"
19 #include "updater_ui_const.h"
20 
21 namespace updater {
22 constexpr int TOUCH_LOW_TH = 50;
23 constexpr int TOUCH_HIGH_TH = 90;
24 constexpr int INIT_DEFAULT_VALUE = 255;
25 constexpr int LABEL_HEIGHT = 64;
26 constexpr int LABEL_OFFSET_2 = 2;
27 constexpr int LABEL_OFFSET_3 = 3;
28 constexpr int DIALOG_START_Y = 550;
29 IInputInterface *g_inputInterface;
30 InputEventCb g_callback;
31 
32 bool g_touchSwiping = false;
33 bool g_touchFingerDown = false;
34 
35 int g_touchX;
36 int g_touchY;
37 int g_touchStartX;
38 int g_touchStartY;
39 extern Frame *g_menuFrame;
40 
41 enum SwipeDirection {
42     UP,
43     DOWN,
44     RIGHT,
45     LEFT
46 };
47 
TouchToClickEvent(const int dx,const int dy,int event)48 void TouchToClickEvent(const int dx, const int dy, int event)
49 {
50     if (!g_menuFrame->IsVisiable()) {
51         LOG(INFO) << "menu page is not top";
52         return;
53     }
54     if (abs(dy) >= 0 && abs(dy) <= LABEL_HEIGHT) {
55         g_menuFrame->DispatchKeyEvent(LABEL_ID_0, event);
56     } else if (abs(dy) > LABEL_HEIGHT && abs(dy) <= LABEL_HEIGHT * LABEL_OFFSET_2) {
57         g_menuFrame->DispatchKeyEvent(LABEL_ID_1, event);
58     } else if (abs(dy) > LABEL_HEIGHT * LABEL_OFFSET_2 && abs(dy) <= LABEL_HEIGHT * LABEL_OFFSET_3) {
59         g_menuFrame->DispatchKeyEvent(LABEL_ID_2, event);
60     } else if (abs(dy) > WIDTH1 && abs(dy) <= DIALOG_START_Y) {
61         if (abs(dx) > 0 && abs(dx) <= DIALOG_OK_WIDTH) {
62             g_menuFrame->DispatchKeyEvent(DIALOG_OK_ID, event);
63         } else if (abs(dx) > DIALOG_CANCEL_X && abs(dx) <= WIDTH1) {
64             g_menuFrame->DispatchKeyEvent(DIALOG_CANCEL_ID, event);
65         }
66     }
67     return;
68 }
69 
TouchToKey(const int dx,const int dy)70 void TouchToKey(const int dx, const int dy)
71 {
72     enum SwipeDirection direction;
73     if (abs(dy) < TOUCH_LOW_TH && abs(dx) > TOUCH_HIGH_TH) {
74         direction = (dx < 0) ? SwipeDirection::LEFT : SwipeDirection::RIGHT;
75     } else if (abs(dx) < TOUCH_LOW_TH && abs(dy) > TOUCH_HIGH_TH) {
76         direction = (dy < 0) ? SwipeDirection::UP : SwipeDirection::DOWN;
77     } else {
78         return;
79     }
80     switch (direction) {
81         case SwipeDirection::UP:
82             g_menuFrame->DispatchKeyEvent(KEY_UP);
83             break;
84         case SwipeDirection::DOWN:
85             g_menuFrame->DispatchKeyEvent(KEY_DOWN);
86             break;
87         case SwipeDirection::LEFT:
88         case SwipeDirection::RIGHT:
89             g_menuFrame->DispatchKeyEvent(KEY_POWER);
90             break;
91         default:
92             break;
93     }
94     return;
95 }
96 
SwipEvent()97 void SwipEvent()
98 {
99     if (g_touchFingerDown && !g_touchSwiping) {
100         g_touchStartX = g_touchX;
101         g_touchStartY = g_touchY;
102         g_touchSwiping = true;
103     } else if (!g_touchFingerDown && g_touchSwiping) {
104         g_touchSwiping = false;
105         TouchToKey(g_touchX - g_touchStartX, g_touchY - g_touchStartY);
106     }
107 }
108 
ClickEvent()109 void ClickEvent()
110 {
111     if (!g_menuFrame->IsVisiable()) {
112         LOG(INFO) << "click event";
113         TouchToClickEvent(g_touchX, g_touchY, -1);
114         return;
115     }
116     if (g_touchFingerDown) {
117         TouchToClickEvent(g_touchX, g_touchY, PRESS_EVENT);
118     } else if (!g_touchFingerDown) {
119         TouchToClickEvent(g_touchX, g_touchY, RELEASE_EVENT);
120     }
121 }
122 
HandleInputEvent(const struct input_event * iev)123 int HandleInputEvent(const struct input_event *iev)
124 {
125     struct input_event ev {};
126     ev.type = iev->type;
127     ev.code = iev->code;
128     ev.value = iev->value;
129     if (ev.type == EV_SYN) {
130         if (ev.code == SYN_REPORT) {
131             // There might be multiple SYN_REPORT events. We should only detect
132             // a swipe after lifting the contact.
133 #ifdef CONVERT_RL_SLIDE_TO_CLICK
134             SwipEvent();
135 #else
136             ClickEvent();
137 #endif
138         }
139         return 0;
140     }
141     if (ev.type == EV_ABS) {
142         switch (ev.code) {
143             case ABS_MT_POSITION_X:
144                 g_touchX = ev.value;
145                 g_touchFingerDown = true;
146                 break;
147             case ABS_MT_POSITION_Y:
148                 g_touchY = ev.value;
149                 g_touchFingerDown = true;
150                 break;
151             case ABS_MT_TRACKING_ID:
152                 // Protocol B: -1 marks lifting the contact.
153                 if (ev.value < 0) {
154                     g_touchFingerDown = false;
155                 }
156                 break;
157             default:
158                 break;
159         }
160         return 0;
161     }
162     if (ev.type == EV_KEY && ev.code <= KEY_MAX) {
163         if (ev.code == BTN_TOUCH) {
164             g_touchFingerDown = (ev.value == 1);
165         }
166         if (ev.code == BTN_TOUCH || ev.code == BTN_TOOL_FINGER) {
167             return 0;
168         }
169     }
170     return 0;
171 }
172 
ReportEventPkgCallback(const EventPackage ** pkgs,const uint32_t count,uint32_t devIndex)173 void ReportEventPkgCallback(const EventPackage **pkgs, const uint32_t count, uint32_t devIndex)
174 {
175     if (pkgs == nullptr || *pkgs == nullptr || !g_menuFrame->IsVisiable()) {
176         return;
177     }
178     for (uint32_t i = 0; i < count; i++) {
179         struct input_event ev = {
180             .type = static_cast<__u16>(pkgs[i]->type),
181             .code = static_cast<__u16>(pkgs[i]->code),
182             .value = pkgs[i]->value,
183         };
184         HandleInputEvent(&ev);
185     }
186     return;
187 }
HdfInit()188 int HdfInit()
189 {
190     int ret = GetInputInterface(&g_inputInterface);
191     if (ret != INPUT_SUCCESS) {
192         LOG(ERROR) << "get input driver interface failed";
193         return ret;
194     }
195     ret = g_inputInterface->iInputManager->OpenInputDevice(1);
196     if (ret) {
197         LOG(ERROR) << "open device1 failed";
198         return ret;
199     }
200     uint32_t devType = 0;
201     ret = g_inputInterface->iInputController->GetDeviceType(1, &devType);
202     if (ret) {
203         LOG(ERROR) << "get device1's type failed";
204         return ret;
205     }
206     g_callback.EventPkgCallback = ReportEventPkgCallback;
207     ret  = g_inputInterface->iInputReporter->RegisterReportCallback(1, &g_callback);
208     if (ret) {
209         LOG(ERROR) << "register callback failed for device 1";
210         return ret;
211     }
212     devType = INIT_DEFAULT_VALUE;
213     ret = g_inputInterface->iInputController->GetDeviceType(1, &devType);
214     return 0;
215 }
216 } // namespace updater
217