1 /*
2 * Copyright (c) 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 "tablet_tool_tranform_processor.h"
17 #include "i_input_windows_manager.h"
18 #include "mmi_log.h"
19
20 #undef MMI_LOG_DOMAIN
21 #define MMI_LOG_DOMAIN MMI_LOG_DISPATCH
22 #undef MMI_LOG_TAG
23 #define MMI_LOG_TAG "TabletToolTransformProcessor"
24
25 namespace OHOS {
26 namespace MMI {
27 namespace {
28 constexpr int32_t DEFAULT_POINTER_ID { 0 };
29 } // namespace
30
TabletToolTransformProcessor(int32_t deviceId)31 TabletToolTransformProcessor::TabletToolTransformProcessor(int32_t deviceId)
32 : deviceId_(deviceId) {}
33
OnEvent(struct libinput_event * event)34 std::shared_ptr<PointerEvent> TabletToolTransformProcessor::OnEvent(struct libinput_event* event)
35 {
36 CHKPP(event);
37 if (pointerEvent_ == nullptr) {
38 pointerEvent_ = PointerEvent::Create();
39 CHKPP(pointerEvent_);
40 }
41 enum libinput_event_type type = libinput_event_get_type(event);
42 switch (type) {
43 case LIBINPUT_EVENT_TABLET_TOOL_AXIS: {
44 if (!OnTipMotion(event)) {
45 MMI_HILOGE("OnTipMotion failed");
46 return nullptr;
47 }
48 break;
49 }
50 case LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY: {
51 if (!OnTipProximity(event)) {
52 MMI_HILOGE("OnTipProximity failed");
53 return nullptr;
54 }
55 break;
56 }
57 case LIBINPUT_EVENT_TABLET_TOOL_TIP: {
58 if (!OnTip(event)) {
59 MMI_HILOGE("OnTip failed");
60 return nullptr;
61 }
62 break;
63 }
64 default: {
65 MMI_HILOGE("Unexpected event type");
66 return nullptr;
67 }
68 }
69 pointerEvent_->SetSourceType(PointerEvent::SOURCE_TYPE_TOUCHSCREEN);
70 pointerEvent_->UpdateId();
71 StartLogTraceId(pointerEvent_->GetId(), pointerEvent_->GetEventType(), pointerEvent_->GetPointerAction());
72 WIN_MGR->UpdateTargetPointer(pointerEvent_);
73 return pointerEvent_;
74 }
75
GetToolType(struct libinput_event_tablet_tool * tabletEvent)76 int32_t TabletToolTransformProcessor::GetToolType(struct libinput_event_tablet_tool* tabletEvent)
77 {
78 int32_t toolType = libinput_event_tablet_tool_get_tool_type(tabletEvent);
79 if (toolType != 0) {
80 return PointerEvent::TOOL_TYPE_PEN;
81 }
82 auto tool = libinput_event_tablet_tool_get_tool(tabletEvent);
83 CHKPR(tool, PointerEvent::TOOL_TYPE_PEN);
84 int32_t type = libinput_tablet_tool_get_type(tool);
85 switch (type) {
86 case LIBINPUT_TABLET_TOOL_TYPE_PEN: {
87 return PointerEvent::TOOL_TYPE_PEN;
88 }
89 case LIBINPUT_TABLET_TOOL_TYPE_ERASER: {
90 return PointerEvent::TOOL_TYPE_RUBBER;
91 }
92 case LIBINPUT_TABLET_TOOL_TYPE_BRUSH: {
93 return PointerEvent::TOOL_TYPE_BRUSH;
94 }
95 case LIBINPUT_TABLET_TOOL_TYPE_PENCIL: {
96 return PointerEvent::TOOL_TYPE_PENCIL;
97 }
98 case LIBINPUT_TABLET_TOOL_TYPE_AIRBRUSH: {
99 return PointerEvent::TOOL_TYPE_AIRBRUSH;
100 }
101 case LIBINPUT_TABLET_TOOL_TYPE_MOUSE: {
102 return PointerEvent::TOOL_TYPE_MOUSE;
103 }
104 case LIBINPUT_TABLET_TOOL_TYPE_LENS: {
105 return PointerEvent::TOOL_TYPE_LENS;
106 }
107 default: {
108 MMI_HILOGW("Invalid type");
109 return PointerEvent::TOOL_TYPE_PEN;
110 }
111 }
112 }
113
OnTip(struct libinput_event * event)114 bool TabletToolTransformProcessor::OnTip(struct libinput_event* event)
115 {
116 CHKPF(event);
117 auto tabletEvent = libinput_event_get_tablet_tool_event(event);
118 CHKPF(tabletEvent);
119 auto tipState = libinput_event_tablet_tool_get_tip_state(tabletEvent);
120 bool ret = false;
121 switch (tipState) {
122 case LIBINPUT_TABLET_TOOL_TIP_DOWN: {
123 ret = OnTipDown(tabletEvent);
124 if (!ret) {
125 MMI_HILOGE("OnTipDown failed");
126 }
127 break;
128 }
129 case LIBINPUT_TABLET_TOOL_TIP_UP: {
130 ret = OnTipUp(tabletEvent);
131 if (!ret) {
132 MMI_HILOGE("OnTipUp failed");
133 }
134 break;
135 }
136 default: {
137 MMI_HILOGE("Invalid tip state");
138 break;
139 }
140 }
141 return ret;
142 }
143
OnTipDown(struct libinput_event_tablet_tool * event)144 bool TabletToolTransformProcessor::OnTipDown(struct libinput_event_tablet_tool* event)
145 {
146 CALL_DEBUG_ENTER;
147 CHKPF(event);
148 int32_t targetDisplayId = -1;
149 PhysicalCoordinate tCoord;
150 if (!WIN_MGR->CalculateTipPoint(event, targetDisplayId, tCoord)) {
151 MMI_HILOGE("CalculateTipPoint failed");
152 return false;
153 }
154 double tiltX = libinput_event_tablet_tool_get_tilt_x(event);
155 double tiltY = libinput_event_tablet_tool_get_tilt_y(event);
156 double pressure = libinput_event_tablet_tool_get_pressure(event);
157 int32_t toolType = GetToolType(event);
158
159 uint64_t time = libinput_event_tablet_tool_get_time_usec(event);
160 pointerEvent_->SetActionStartTime(time);
161 pointerEvent_->SetTargetDisplayId(targetDisplayId);
162 pointerEvent_->SetActionTime(time);
163 pointerEvent_->SetPointerAction(PointerEvent::POINTER_ACTION_DOWN);
164
165 PointerEvent::PointerItem item;
166 if (pointerEvent_->GetPointerItem(DEFAULT_POINTER_ID, item)) {
167 pointerEvent_->RemovePointerItem(DEFAULT_POINTER_ID);
168 }
169 item.SetPointerId(DEFAULT_POINTER_ID);
170 item.SetDeviceId(deviceId_);
171 item.SetDownTime(time);
172 item.SetPressed(true);
173 item.SetDisplayX(static_cast<int32_t>(tCoord.x));
174 item.SetDisplayY(static_cast<int32_t>(tCoord.y));
175 item.SetDisplayXPos(tCoord.x);
176 item.SetDisplayYPos(tCoord.y);
177 item.SetTiltX(tiltX);
178 item.SetTiltY(tiltY);
179 item.SetToolType(toolType);
180 item.SetPressure(pressure);
181 item.SetTargetWindowId(-1);
182
183 pointerEvent_->SetDeviceId(deviceId_);
184 pointerEvent_->AddPointerItem(item);
185 pointerEvent_->SetPointerId(DEFAULT_POINTER_ID);
186 return true;
187 }
188
OnTipMotion(struct libinput_event * event)189 bool TabletToolTransformProcessor::OnTipMotion(struct libinput_event* event)
190 {
191 CALL_DEBUG_ENTER;
192 CHKPF(event);
193 auto tabletEvent = libinput_event_get_tablet_tool_event(event);
194 CHKPF(tabletEvent);
195 uint64_t time = libinput_event_tablet_tool_get_time_usec(tabletEvent);
196 pointerEvent_->SetActionTime(time);
197 pointerEvent_->SetPointerAction(PointerEvent::POINTER_ACTION_MOVE);
198
199 int32_t targetDisplayId = pointerEvent_->GetTargetDisplayId();
200 PhysicalCoordinate tCoord;
201 if (!WIN_MGR->CalculateTipPoint(tabletEvent, targetDisplayId, tCoord)) {
202 MMI_HILOGE("CalculateTipPoint failed");
203 return false;
204 }
205 double tiltX = libinput_event_tablet_tool_get_tilt_x(tabletEvent);
206 double tiltY = libinput_event_tablet_tool_get_tilt_y(tabletEvent);
207 double pressure = libinput_event_tablet_tool_get_pressure(tabletEvent);
208 int32_t toolType = GetToolType(tabletEvent);
209
210 PointerEvent::PointerItem item;
211 if (!pointerEvent_->GetPointerItem(DEFAULT_POINTER_ID, item)) {
212 MMI_HILOGW("The pointer is expected, but not found");
213 pointerEvent_->SetActionStartTime(time);
214 pointerEvent_->SetTargetDisplayId(targetDisplayId);
215 pointerEvent_->SetDeviceId(deviceId_);
216 pointerEvent_->SetPointerId(DEFAULT_POINTER_ID);
217
218 item.SetPointerId(DEFAULT_POINTER_ID);
219 item.SetDeviceId(deviceId_);
220 item.SetDownTime(time);
221 item.SetPressed(true);
222 item.SetToolType(toolType);
223 }
224 item.SetDisplayX(static_cast<int32_t>(tCoord.x));
225 item.SetDisplayY(static_cast<int32_t>(tCoord.y));
226 item.SetDisplayXPos(tCoord.x);
227 item.SetDisplayYPos(tCoord.y);
228 item.SetTiltX(tiltX);
229 item.SetTiltY(tiltY);
230 item.SetPressure(pressure);
231 pointerEvent_->UpdatePointerItem(DEFAULT_POINTER_ID, item);
232 return true;
233 }
234
OnTipUp(struct libinput_event_tablet_tool * event)235 bool TabletToolTransformProcessor::OnTipUp(struct libinput_event_tablet_tool* event)
236 {
237 CALL_DEBUG_ENTER;
238 CHKPF(event);
239 uint64_t time = libinput_event_tablet_tool_get_time_usec(event);
240 pointerEvent_->SetActionTime(time);
241 pointerEvent_->SetPointerAction(PointerEvent::POINTER_ACTION_UP);
242
243 PointerEvent::PointerItem item;
244 if (!pointerEvent_->GetPointerItem(DEFAULT_POINTER_ID, item)) {
245 MMI_HILOGE("GetPointerItem failed");
246 return false;
247 }
248 item.SetPressed(false);
249 pointerEvent_->UpdatePointerItem(DEFAULT_POINTER_ID, item);
250 return true;
251 }
252
OnTipProximity(struct libinput_event * event)253 bool TabletToolTransformProcessor::OnTipProximity(struct libinput_event* event)
254 {
255 CALL_DEBUG_ENTER;
256 CHKPF(event);
257 auto tabletEvent = libinput_event_get_tablet_tool_event(event);
258 CHKPF(tabletEvent);
259 uint64_t time = libinput_event_tablet_tool_get_time_usec(tabletEvent);
260 pointerEvent_->SetActionTime(time);
261
262 bool tabletProximityState = libinput_event_tablet_tool_get_proximity_state(tabletEvent);
263 if (tabletProximityState) {
264 MMI_HILOGD("The pen is getting close and report proximity in event");
265 pointerEvent_->SetPointerAction(PointerEvent::POINTER_ACTION_PROXIMITY_IN);
266 } else {
267 MMI_HILOGD("The pen is getting away and report proximity out event");
268 pointerEvent_->SetPointerAction(PointerEvent::POINTER_ACTION_PROXIMITY_OUT);
269 }
270
271 int32_t targetDisplayId = pointerEvent_->GetTargetDisplayId();
272 PhysicalCoordinate coord;
273 if (!WIN_MGR->CalculateTipPoint(tabletEvent, targetDisplayId, coord)) {
274 MMI_HILOGE("CalculateTipPoint failed");
275 return false;
276 }
277 double tiltX = libinput_event_tablet_tool_get_tilt_x(tabletEvent);
278 double tiltY = libinput_event_tablet_tool_get_tilt_y(tabletEvent);
279 double pressure = libinput_event_tablet_tool_get_pressure(tabletEvent);
280 int32_t toolType = GetToolType(tabletEvent);
281
282 PointerEvent::PointerItem item;
283 if (!pointerEvent_->GetPointerItem(DEFAULT_POINTER_ID, item)) {
284 MMI_HILOGW("The pointer is expected, but not found");
285 }
286
287 pointerEvent_->SetActionStartTime(time);
288 pointerEvent_->SetTargetDisplayId(targetDisplayId);
289 pointerEvent_->SetDeviceId(deviceId_);
290 pointerEvent_->SetPointerId(DEFAULT_POINTER_ID);
291
292 item.SetPointerId(DEFAULT_POINTER_ID);
293 item.SetDeviceId(deviceId_);
294 item.SetDownTime(time);
295 item.SetPressed(false);
296 item.SetToolType(toolType);
297 item.SetDisplayX(static_cast<int32_t>(coord.x));
298 item.SetDisplayY(static_cast<int32_t>(coord.y));
299 item.SetDisplayXPos(coord.x);
300 item.SetDisplayYPos(coord.y);
301 item.SetTiltX(tiltX);
302 item.SetTiltY(tiltY);
303 item.SetPressure(pressure);
304 pointerEvent_->UpdatePointerItem(DEFAULT_POINTER_ID, item);
305 return true;
306 }
307 } // namespace MMI
308 } // namespace OHOS
309