1 /*
2 * Copyright (c) 2021-2022 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 "touch_transform_processor.h"
17
18 #include <linux/input.h>
19
20 #include "event_log_helper.h"
21 #include "input_windows_manager.h"
22 #include "mmi_log.h"
23
24 namespace OHOS {
25 namespace MMI {
26 namespace {
27 constexpr OHOS::HiviewDFX::HiLogLabel LABEL { LOG_CORE, MMI_LOG_DOMAIN, "TouchTransformProcessor" };
28 constexpr int32_t MT_TOOL_NONE { -1 };
29 constexpr int32_t BTN_DOWN { 1 };
30 } // namespace
31
TouchTransformProcessor(int32_t deviceId)32 TouchTransformProcessor::TouchTransformProcessor(int32_t deviceId)
33 : deviceId_(deviceId)
34 {
35 InitToolTypes();
36 }
37
OnEventTouchDown(struct libinput_event * event)38 bool TouchTransformProcessor::OnEventTouchDown(struct libinput_event *event)
39 {
40 CALL_DEBUG_ENTER;
41 CHKPF(event);
42 auto touch = libinput_event_get_touch_event(event);
43 CHKPF(touch);
44 auto device = libinput_event_get_device(event);
45 CHKPF(device);
46 EventTouch touchInfo;
47 int32_t logicalDisplayId = -1;
48 if (!WinMgr->TouchPointToDisplayPoint(deviceId_, touch, touchInfo, logicalDisplayId)) {
49 MMI_HILOGE("TouchDownPointToDisplayPoint failed");
50 return false;
51 }
52 auto pointIds = pointerEvent_->GetPointerIds();
53 int64_t time = GetSysClockTime();
54 if (pointIds.empty()) {
55 pointerEvent_->SetActionStartTime(time);
56 pointerEvent_->SetTargetDisplayId(logicalDisplayId);
57 }
58 pointerEvent_->SetActionTime(time);
59 pointerEvent_->SetPointerAction(PointerEvent::POINTER_ACTION_DOWN);
60
61 PointerEvent::PointerItem item;
62 double pressure = libinput_event_touch_get_pressure(touch);
63 int32_t seatSlot = libinput_event_touch_get_seat_slot(touch);
64 int32_t longAxis = libinput_event_get_touch_contact_long_axis(touch);
65 int32_t shortAxis = libinput_event_get_touch_contact_short_axis(touch);
66 item.SetPressure(pressure);
67 item.SetLongAxis(longAxis);
68 item.SetShortAxis(shortAxis);
69 int32_t toolType = GetTouchToolType(touch, device);
70 item.SetToolType(toolType);
71 item.SetPointerId(seatSlot);
72 item.SetDownTime(time);
73 item.SetPressed(true);
74 item.SetDisplayX(touchInfo.point.x);
75 item.SetDisplayY(touchInfo.point.y);
76 item.SetToolDisplayX(touchInfo.toolRect.point.x);
77 item.SetToolDisplayY(touchInfo.toolRect.point.y);
78 item.SetToolWidth(touchInfo.toolRect.width);
79 item.SetToolHeight(touchInfo.toolRect.height);
80 item.SetDeviceId(deviceId_);
81 pointerEvent_->SetDeviceId(deviceId_);
82 pointerEvent_->AddPointerItem(item);
83 pointerEvent_->SetPointerId(seatSlot);
84 EventLogHelper::PrintEventData(pointerEvent_, pointerEvent_->GetPointerAction(),
85 pointerEvent_->GetPointerIds().size());
86 return true;
87 }
88
OnEventTouchMotion(struct libinput_event * event)89 bool TouchTransformProcessor::OnEventTouchMotion(struct libinput_event *event)
90 {
91 CALL_DEBUG_ENTER;
92 CHKPF(event);
93 auto touch = libinput_event_get_touch_event(event);
94 CHKPF(touch);
95 int64_t time = GetSysClockTime();
96 pointerEvent_->SetActionTime(time);
97 pointerEvent_->SetPointerAction(PointerEvent::POINTER_ACTION_MOVE);
98 EventTouch touchInfo;
99 int32_t logicalDisplayId = pointerEvent_->GetTargetDisplayId();
100 if (!WinMgr->TouchPointToDisplayPoint(deviceId_, touch, touchInfo, logicalDisplayId)) {
101 MMI_HILOGE("Get TouchMotionPointToDisplayPoint failed");
102 return false;
103 }
104 PointerEvent::PointerItem item;
105 int32_t seatSlot = libinput_event_touch_get_seat_slot(touch);
106 if (!(pointerEvent_->GetPointerItem(seatSlot, item))) {
107 MMI_HILOGE("Get pointer parameter failed");
108 return false;
109 }
110 double pressure = libinput_event_touch_get_pressure(touch);
111 int32_t longAxis = libinput_event_get_touch_contact_long_axis(touch);
112 int32_t shortAxis = libinput_event_get_touch_contact_short_axis(touch);
113 item.SetPressure(pressure);
114 item.SetLongAxis(longAxis);
115 item.SetShortAxis(shortAxis);
116 item.SetDisplayX(touchInfo.point.x);
117 item.SetDisplayY(touchInfo.point.y);
118 item.SetToolDisplayX(touchInfo.toolRect.point.x);
119 item.SetToolDisplayY(touchInfo.toolRect.point.y);
120 item.SetToolWidth(touchInfo.toolRect.width);
121 item.SetToolHeight(touchInfo.toolRect.height);
122 pointerEvent_->UpdatePointerItem(seatSlot, item);
123 pointerEvent_->SetPointerId(seatSlot);
124 EventLogHelper::PrintEventData(pointerEvent_, pointerEvent_->GetPointerAction(),
125 pointerEvent_->GetPointerIds().size());
126 return true;
127 }
128
OnEventTouchUp(struct libinput_event * event)129 bool TouchTransformProcessor::OnEventTouchUp(struct libinput_event *event)
130 {
131 CALL_DEBUG_ENTER;
132 CHKPF(event);
133 auto touch = libinput_event_get_touch_event(event);
134 CHKPF(touch);
135 int64_t time = GetSysClockTime();
136 pointerEvent_->SetActionTime(time);
137 pointerEvent_->SetPointerAction(PointerEvent::POINTER_ACTION_UP);
138
139 PointerEvent::PointerItem item;
140 int32_t seatSlot = libinput_event_touch_get_seat_slot(touch);
141 if (!(pointerEvent_->GetPointerItem(seatSlot, item))) {
142 MMI_HILOGE("Get pointer parameter failed");
143 return false;
144 }
145 item.SetPressed(false);
146 pointerEvent_->UpdatePointerItem(seatSlot, item);
147 pointerEvent_->SetPointerId(seatSlot);
148 return true;
149 }
150
OnEvent(struct libinput_event * event)151 std::shared_ptr<PointerEvent> TouchTransformProcessor::OnEvent(struct libinput_event *event)
152 {
153 CALL_DEBUG_ENTER;
154 CHKPP(event);
155 if (pointerEvent_ == nullptr) {
156 pointerEvent_ = PointerEvent::Create();
157 CHKPP(pointerEvent_);
158 }
159 auto type = libinput_event_get_type(event);
160 switch (type) {
161 case LIBINPUT_EVENT_TOUCH_DOWN: {
162 if (!OnEventTouchDown(event)) {
163 MMI_HILOGE("Get OnEventTouchDown failed");
164 return nullptr;
165 }
166 break;
167 }
168 case LIBINPUT_EVENT_TOUCH_UP: {
169 if (!OnEventTouchUp(event)) {
170 MMI_HILOGE("Get OnEventTouchUp failed");
171 return nullptr;
172 }
173 break;
174 }
175 case LIBINPUT_EVENT_TOUCH_MOTION: {
176 if (!OnEventTouchMotion(event)) {
177 MMI_HILOGE("Get OnEventTouchMotion failed");
178 return nullptr;
179 }
180 break;
181 }
182 default: {
183 MMI_HILOGE("Unknown event type, touchType:%{public}d", type);
184 return nullptr;
185 }
186 }
187 pointerEvent_->SetSourceType(PointerEvent::SOURCE_TYPE_TOUCHSCREEN);
188 pointerEvent_->UpdateId();
189 WinMgr->UpdateTargetPointer(pointerEvent_);
190 return pointerEvent_;
191 }
192
GetTouchToolType(struct libinput_event_touch * data,struct libinput_device * device)193 int32_t TouchTransformProcessor::GetTouchToolType(struct libinput_event_touch *data,
194 struct libinput_device *device)
195 {
196 int32_t toolType = libinput_event_touch_get_tool_type(data);
197 switch (toolType) {
198 case MT_TOOL_NONE: {
199 return GetTouchToolType(device);
200 }
201 case MT_TOOL_FINGER: {
202 return PointerEvent::TOOL_TYPE_FINGER;
203 }
204 case MT_TOOL_PEN: {
205 return PointerEvent::TOOL_TYPE_PEN;
206 }
207 default : {
208 MMI_HILOGW("Unknown tool type, identified as finger, toolType:%{public}d", toolType);
209 return PointerEvent::TOOL_TYPE_FINGER;
210 }
211 }
212 }
213
GetTouchToolType(struct libinput_device * device)214 int32_t TouchTransformProcessor::GetTouchToolType(struct libinput_device *device)
215 {
216 for (const auto &item : vecToolType_) {
217 if (libinput_device_touch_btn_tool_type_down(device, item.first) == BTN_DOWN) {
218 return item.second;
219 }
220 }
221 MMI_HILOGW("Unknown Btn tool type, identified as finger");
222 return PointerEvent::TOOL_TYPE_FINGER;
223 }
224
InitToolTypes()225 void TouchTransformProcessor::InitToolTypes()
226 {
227 vecToolType_.emplace_back(std::make_pair(BTN_TOOL_PEN, PointerEvent::TOOL_TYPE_PEN));
228 vecToolType_.emplace_back(std::make_pair(BTN_TOOL_RUBBER, PointerEvent::TOOL_TYPE_RUBBER));
229 vecToolType_.emplace_back(std::make_pair(BTN_TOOL_BRUSH, PointerEvent::TOOL_TYPE_BRUSH));
230 vecToolType_.emplace_back(std::make_pair(BTN_TOOL_PENCIL, PointerEvent::TOOL_TYPE_PENCIL));
231 vecToolType_.emplace_back(std::make_pair(BTN_TOOL_AIRBRUSH, PointerEvent::TOOL_TYPE_AIRBRUSH));
232 vecToolType_.emplace_back(std::make_pair(BTN_TOOL_FINGER, PointerEvent::TOOL_TYPE_FINGER));
233 vecToolType_.emplace_back(std::make_pair(BTN_TOOL_MOUSE, PointerEvent::TOOL_TYPE_MOUSE));
234 vecToolType_.emplace_back(std::make_pair(BTN_TOOL_LENS, PointerEvent::TOOL_TYPE_LENS));
235 }
236 } // namespace MMI
237 } // namespace OHOS
238