• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
18 #include "i_input_windows_manager.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 {
34     current_ = [this]() {
35         DrawTouchGraphicIdle();
36     };
37 }
38 
OnEvent(struct libinput_event * event)39 std::shared_ptr<PointerEvent> TabletToolTransformProcessor::OnEvent(struct libinput_event* event)
40 {
41     CHKPP(event);
42     if (pointerEvent_ == nullptr) {
43         pointerEvent_ = PointerEvent::Create();
44         CHKPP(pointerEvent_);
45     }
46     enum libinput_event_type type = libinput_event_get_type(event);
47     switch (type) {
48         case LIBINPUT_EVENT_TABLET_TOOL_AXIS: {
49             if (!OnTipMotion(event)) {
50                 MMI_HILOGE("OnTipMotion failed");
51                 return nullptr;
52             }
53             break;
54         }
55         case LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY: {
56             if (!OnTipProximity(event)) {
57                 MMI_HILOGE("OnTipProximity failed");
58                 return nullptr;
59             }
60             break;
61         }
62         case LIBINPUT_EVENT_TABLET_TOOL_TIP: {
63             if (!OnTip(event)) {
64                 MMI_HILOGE("OnTip failed");
65                 return nullptr;
66             }
67             break;
68         }
69         default: {
70             MMI_HILOGE("Unexpected event type");
71             return nullptr;
72         }
73     }
74     pointerEvent_->SetSourceType(PointerEvent::SOURCE_TYPE_TOUCHSCREEN);
75     pointerEvent_->UpdateId();
76     StartLogTraceId(pointerEvent_->GetId(), pointerEvent_->GetEventType(), pointerEvent_->GetPointerAction());
77     WIN_MGR->UpdateTargetPointer(pointerEvent_);
78     DrawTouchGraphic();
79     return pointerEvent_;
80 }
81 
GetToolType(struct libinput_event_tablet_tool * tabletEvent)82 int32_t TabletToolTransformProcessor::GetToolType(struct libinput_event_tablet_tool* tabletEvent)
83 {
84     int32_t toolType = libinput_event_tablet_tool_get_tool_type(tabletEvent);
85     if (toolType != 0) {
86         return PointerEvent::TOOL_TYPE_PEN;
87     }
88     auto tool = libinput_event_tablet_tool_get_tool(tabletEvent);
89     CHKPR(tool, PointerEvent::TOOL_TYPE_PEN);
90     int32_t type = libinput_tablet_tool_get_type(tool);
91     switch (type) {
92         case LIBINPUT_TABLET_TOOL_TYPE_PEN: {
93             return PointerEvent::TOOL_TYPE_PEN;
94         }
95         case LIBINPUT_TABLET_TOOL_TYPE_ERASER: {
96             return PointerEvent::TOOL_TYPE_RUBBER;
97         }
98         case LIBINPUT_TABLET_TOOL_TYPE_BRUSH: {
99             return PointerEvent::TOOL_TYPE_BRUSH;
100         }
101         case LIBINPUT_TABLET_TOOL_TYPE_PENCIL: {
102             return PointerEvent::TOOL_TYPE_PENCIL;
103         }
104         case LIBINPUT_TABLET_TOOL_TYPE_AIRBRUSH: {
105             return PointerEvent::TOOL_TYPE_AIRBRUSH;
106         }
107         case LIBINPUT_TABLET_TOOL_TYPE_MOUSE: {
108             return PointerEvent::TOOL_TYPE_MOUSE;
109         }
110         case LIBINPUT_TABLET_TOOL_TYPE_LENS: {
111             return PointerEvent::TOOL_TYPE_LENS;
112         }
113         default: {
114             MMI_HILOGW("Invalid type");
115             return PointerEvent::TOOL_TYPE_PEN;
116         }
117     }
118 }
119 
OnTip(struct libinput_event * event)120 bool TabletToolTransformProcessor::OnTip(struct libinput_event* event)
121 {
122     CHKPF(event);
123     auto tabletEvent = libinput_event_get_tablet_tool_event(event);
124     CHKPF(tabletEvent);
125     auto tipState = libinput_event_tablet_tool_get_tip_state(tabletEvent);
126     bool ret = false;
127     switch (tipState) {
128         case LIBINPUT_TABLET_TOOL_TIP_DOWN: {
129             ret = OnTipDown(tabletEvent);
130             if (!ret) {
131                 MMI_HILOGE("OnTipDown failed");
132             }
133             break;
134         }
135         case LIBINPUT_TABLET_TOOL_TIP_UP: {
136             ret = OnTipUp(tabletEvent);
137             if (!ret) {
138                 MMI_HILOGE("OnTipUp failed");
139             }
140             break;
141         }
142         default: {
143             MMI_HILOGE("Invalid tip state");
144             break;
145         }
146     }
147     return ret;
148 }
149 
OnTipDown(struct libinput_event_tablet_tool * event)150 bool TabletToolTransformProcessor::OnTipDown(struct libinput_event_tablet_tool* event)
151 {
152     CALL_DEBUG_ENTER;
153     CHKPF(event);
154     int32_t targetDisplayId = -1;
155     PhysicalCoordinate tCoord;
156     if (!WIN_MGR->CalculateTipPoint(event, targetDisplayId, tCoord)) {
157         MMI_HILOGE("CalculateTipPoint failed");
158         return false;
159     }
160     double tiltX = libinput_event_tablet_tool_get_tilt_x(event);
161     double tiltY = libinput_event_tablet_tool_get_tilt_y(event);
162     double pressure = libinput_event_tablet_tool_get_pressure(event);
163     int32_t toolType = GetToolType(event);
164     int32_t twist = libinput_event_tablet_tool_get_twist(event);
165 
166     uint64_t time = libinput_event_tablet_tool_get_time_usec(event);
167     pointerEvent_->SetActionStartTime(time);
168     pointerEvent_->SetTargetDisplayId(targetDisplayId);
169     pointerEvent_->SetActionTime(time);
170     pointerEvent_->SetPointerAction(PointerEvent::POINTER_ACTION_DOWN);
171 
172     PointerEvent::PointerItem item;
173     if (pointerEvent_->GetPointerItem(DEFAULT_POINTER_ID, item)) {
174         pointerEvent_->RemovePointerItem(DEFAULT_POINTER_ID);
175     }
176     item.SetPointerId(DEFAULT_POINTER_ID);
177     item.SetDeviceId(deviceId_);
178     item.SetDownTime(time);
179     item.SetPressed(true);
180     item.SetDisplayX(static_cast<int32_t>(tCoord.x));
181     item.SetDisplayY(static_cast<int32_t>(tCoord.y));
182     item.SetDisplayXPos(tCoord.x);
183     item.SetDisplayYPos(tCoord.y);
184     item.SetRawDisplayX(static_cast<int32_t>(tCoord.x));
185     item.SetRawDisplayY(static_cast<int32_t>(tCoord.y));
186     item.SetTiltX(tiltX);
187     item.SetTiltY(tiltY);
188     item.SetToolType(toolType);
189     item.SetPressure(pressure);
190     item.SetTargetWindowId(-1);
191     item.SetTwist(twist);
192 
193     pointerEvent_->SetDeviceId(deviceId_);
194     pointerEvent_->AddPointerItem(item);
195     pointerEvent_->SetPointerId(DEFAULT_POINTER_ID);
196     return true;
197 }
198 
OnTipMotion(struct libinput_event * event)199 bool TabletToolTransformProcessor::OnTipMotion(struct libinput_event* event)
200 {
201     CALL_DEBUG_ENTER;
202     CHKPF(event);
203     auto tabletEvent = libinput_event_get_tablet_tool_event(event);
204     CHKPF(tabletEvent);
205     uint64_t time = libinput_event_tablet_tool_get_time_usec(tabletEvent);
206     pointerEvent_->SetActionTime(time);
207     pointerEvent_->SetPointerAction(PointerEvent::POINTER_ACTION_MOVE);
208 
209     int32_t targetDisplayId = pointerEvent_->GetTargetDisplayId();
210     PhysicalCoordinate tCoord;
211     if (!WIN_MGR->CalculateTipPoint(tabletEvent, targetDisplayId, tCoord)) {
212         MMI_HILOGE("CalculateTipPoint failed");
213         return false;
214     }
215     double tiltX = libinput_event_tablet_tool_get_tilt_x(tabletEvent);
216     double tiltY = libinput_event_tablet_tool_get_tilt_y(tabletEvent);
217     double pressure = libinput_event_tablet_tool_get_pressure(tabletEvent);
218     int32_t toolType = GetToolType(tabletEvent);
219     int32_t twist = libinput_event_tablet_tool_get_twist(tabletEvent);
220 
221     PointerEvent::PointerItem item;
222     if (!pointerEvent_->GetPointerItem(DEFAULT_POINTER_ID, item)) {
223         MMI_HILOGW("The pointer is expected, but not found");
224         pointerEvent_->SetActionStartTime(time);
225         pointerEvent_->SetTargetDisplayId(targetDisplayId);
226         pointerEvent_->SetDeviceId(deviceId_);
227         pointerEvent_->SetPointerId(DEFAULT_POINTER_ID);
228 
229         item.SetPointerId(DEFAULT_POINTER_ID);
230         item.SetDeviceId(deviceId_);
231         item.SetDownTime(time);
232     }
233     item.SetPressed(true);
234     item.SetToolType(toolType);
235     item.SetDisplayX(static_cast<int32_t>(tCoord.x));
236     item.SetDisplayY(static_cast<int32_t>(tCoord.y));
237     item.SetDisplayXPos(tCoord.x);
238     item.SetDisplayYPos(tCoord.y);
239     item.SetRawDisplayX(static_cast<int32_t>(tCoord.x));
240     item.SetRawDisplayY(static_cast<int32_t>(tCoord.y));
241     item.SetTiltX(tiltX);
242     item.SetTiltY(tiltY);
243     item.SetPressure(pressure);
244     item.SetTwist(twist);
245     pointerEvent_->UpdatePointerItem(DEFAULT_POINTER_ID, item);
246     return true;
247 }
248 
OnTipUp(struct libinput_event_tablet_tool * event)249 bool TabletToolTransformProcessor::OnTipUp(struct libinput_event_tablet_tool* event)
250 {
251     CALL_DEBUG_ENTER;
252     CHKPF(event);
253     uint64_t time = libinput_event_tablet_tool_get_time_usec(event);
254     pointerEvent_->SetActionTime(time);
255     pointerEvent_->SetPointerAction(PointerEvent::POINTER_ACTION_UP);
256 
257     PointerEvent::PointerItem item;
258     if (!pointerEvent_->GetPointerItem(DEFAULT_POINTER_ID, item)) {
259         MMI_HILOGE("GetPointerItem failed");
260         return false;
261     }
262     item.SetPressed(false);
263     pointerEvent_->UpdatePointerItem(DEFAULT_POINTER_ID, item);
264     return true;
265 }
266 
OnTipProximity(struct libinput_event * event)267 bool TabletToolTransformProcessor::OnTipProximity(struct libinput_event* event)
268 {
269     CALL_DEBUG_ENTER;
270     CHKPF(event);
271     auto tabletEvent = libinput_event_get_tablet_tool_event(event);
272     CHKPF(tabletEvent);
273     uint64_t time = libinput_event_tablet_tool_get_time_usec(tabletEvent);
274     pointerEvent_->SetActionTime(time);
275 
276     bool tabletProximityState = libinput_event_tablet_tool_get_proximity_state(tabletEvent);
277     if (tabletProximityState) {
278         MMI_HILOGD("The pen is getting close and report proximity in event");
279         pointerEvent_->SetPointerAction(PointerEvent::POINTER_ACTION_PROXIMITY_IN);
280     } else {
281         MMI_HILOGD("The pen is getting away and report proximity out event");
282         pointerEvent_->SetPointerAction(PointerEvent::POINTER_ACTION_PROXIMITY_OUT);
283     }
284 
285     int32_t targetDisplayId = pointerEvent_->GetTargetDisplayId();
286     PhysicalCoordinate coord;
287     if (!WIN_MGR->CalculateTipPoint(tabletEvent, targetDisplayId, coord)) {
288         MMI_HILOGE("CalculateTipPoint failed");
289         return false;
290     }
291     double tiltX = libinput_event_tablet_tool_get_tilt_x(tabletEvent);
292     double tiltY = libinput_event_tablet_tool_get_tilt_y(tabletEvent);
293     double pressure = libinput_event_tablet_tool_get_pressure(tabletEvent);
294     int32_t toolType = GetToolType(tabletEvent);
295 
296     PointerEvent::PointerItem item;
297     if (!pointerEvent_->GetPointerItem(DEFAULT_POINTER_ID, item)) {
298         MMI_HILOGW("The pointer is expected, but not found");
299     }
300 
301     pointerEvent_->SetActionStartTime(time);
302     pointerEvent_->SetTargetDisplayId(targetDisplayId);
303     pointerEvent_->SetDeviceId(deviceId_);
304     pointerEvent_->SetPointerId(DEFAULT_POINTER_ID);
305 
306     item.SetPointerId(DEFAULT_POINTER_ID);
307     item.SetDeviceId(deviceId_);
308     item.SetDownTime(time);
309     item.SetPressed(false);
310     item.SetToolType(toolType);
311     item.SetDisplayX(static_cast<int32_t>(coord.x));
312     item.SetDisplayY(static_cast<int32_t>(coord.y));
313     item.SetDisplayXPos(coord.x);
314     item.SetDisplayYPos(coord.y);
315     item.SetRawDisplayX(static_cast<int32_t>(coord.x));
316     item.SetRawDisplayY(static_cast<int32_t>(coord.y));
317     item.SetTiltX(tiltX);
318     item.SetTiltY(tiltY);
319     item.SetPressure(pressure);
320     pointerEvent_->UpdatePointerItem(DEFAULT_POINTER_ID, item);
321     return true;
322 }
323 
DrawTouchGraphic()324 void TabletToolTransformProcessor::DrawTouchGraphic()
325 {
326     CHKPV(current_);
327     current_();
328 }
329 
DrawTouchGraphicIdle()330 void TabletToolTransformProcessor::DrawTouchGraphicIdle()
331 {
332     CHKPV(pointerEvent_);
333     auto pointerAction = pointerEvent_->GetPointerAction();
334     switch (pointerAction) {
335         case PointerEvent::POINTER_ACTION_PROXIMITY_IN:
336         case PointerEvent::POINTER_ACTION_DOWN:
337         case PointerEvent::POINTER_ACTION_MOVE: {
338             pointerEvent_->SetPointerAction(PointerEvent::POINTER_ACTION_DOWN);
339             current_ = [this]() {
340                 DrawTouchGraphicDrawing();
341             };
342             break;
343         }
344         default: {
345             return;
346         }
347     }
348     WIN_MGR->DrawTouchGraphic(pointerEvent_);
349     pointerEvent_->SetPointerAction(pointerAction);
350 }
351 
DrawTouchGraphicDrawing()352 void TabletToolTransformProcessor::DrawTouchGraphicDrawing()
353 {
354     CHKPV(pointerEvent_);
355     auto pointerAction = pointerEvent_->GetPointerAction();
356     switch (pointerAction) {
357         case PointerEvent::POINTER_ACTION_MOVE:
358         case PointerEvent::POINTER_ACTION_UP: {
359             pointerEvent_->SetPointerAction(PointerEvent::POINTER_ACTION_MOVE);
360             break;
361         }
362         case PointerEvent::POINTER_ACTION_PROXIMITY_OUT: {
363             auto pointerEvent = std::make_shared<PointerEvent>(*pointerEvent_);
364             PointerEvent::PointerItem item {};
365             if (pointerEvent->GetPointerItem(pointerEvent->GetPointerId(), item)) {
366                 item.SetPressed(true);
367                 pointerEvent->UpdatePointerItem(pointerEvent->GetPointerId(), item);
368                 pointerEvent->SetPointerAction(PointerEvent::POINTER_ACTION_MOVE);
369                 WIN_MGR->DrawTouchGraphic(pointerEvent);
370             }
371             pointerEvent_->SetPointerAction(PointerEvent::POINTER_ACTION_UP);
372             current_ = [this]() {
373                 DrawTouchGraphicIdle();
374             };
375             break;
376         }
377         default: {
378             return;
379         }
380     }
381     WIN_MGR->DrawTouchGraphic(pointerEvent_);
382     pointerEvent_->SetPointerAction(pointerAction);
383 }
384 } // namespace MMI
385 } // namespace OHOS
386