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 "input_windows_manager.h"
18 #include "mmi_log.h"
19
20 namespace OHOS {
21 namespace MMI {
22 namespace {
23 constexpr OHOS::HiviewDFX::HiLogLabel LABEL { LOG_CORE, MMI_LOG_DOMAIN, "TabletToolTransformProcessor" };
24 constexpr int32_t DEFAULT_POINTER_ID { 0 };
25 } // namespace
26
TabletToolTransformProcessor(int32_t deviceId)27 TabletToolTransformProcessor::TabletToolTransformProcessor(int32_t deviceId)
28 : deviceId_(deviceId) {}
29
OnEvent(struct libinput_event * event)30 std::shared_ptr<PointerEvent> TabletToolTransformProcessor::OnEvent(struct libinput_event* event)
31 {
32 CHKPP(event);
33 if (pointerEvent_ == nullptr) {
34 pointerEvent_ = PointerEvent::Create();
35 CHKPP(pointerEvent_);
36 }
37 enum libinput_event_type type = libinput_event_get_type(event);
38 switch (type) {
39 case LIBINPUT_EVENT_TABLET_TOOL_AXIS: {
40 if (!OnTipMotion(event)) {
41 MMI_HILOGE("OnTipMotion failed");
42 return nullptr;
43 }
44 break;
45 }
46 case LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY: {
47 MMI_HILOGE("Proximity event");
48 return nullptr;
49 }
50 case LIBINPUT_EVENT_TABLET_TOOL_TIP: {
51 if (!OnTip(event)) {
52 MMI_HILOGE("OnTip failed");
53 return nullptr;
54 }
55 break;
56 }
57 default: {
58 MMI_HILOGE("Unexpected event type");
59 return nullptr;
60 }
61 }
62 pointerEvent_->SetSourceType(PointerEvent::SOURCE_TYPE_TOUCHSCREEN);
63 pointerEvent_->UpdateId();
64 WinMgr->UpdateTargetPointer(pointerEvent_);
65 return pointerEvent_;
66 }
67
GetToolType(struct libinput_event_tablet_tool * tabletEvent)68 int32_t TabletToolTransformProcessor::GetToolType(struct libinput_event_tablet_tool* tabletEvent)
69 {
70 int32_t toolType = libinput_event_tablet_tool_get_tool_type(tabletEvent);
71 if (toolType != 0) {
72 return PointerEvent::TOOL_TYPE_PEN;
73 }
74 auto tool = libinput_event_tablet_tool_get_tool(tabletEvent);
75 CHKPR(tool, PointerEvent::TOOL_TYPE_PEN);
76 int32_t type = libinput_tablet_tool_get_type(tool);
77 switch (type) {
78 case LIBINPUT_TABLET_TOOL_TYPE_PEN: {
79 return PointerEvent::TOOL_TYPE_PEN;
80 }
81 case LIBINPUT_TABLET_TOOL_TYPE_ERASER: {
82 return PointerEvent::TOOL_TYPE_RUBBER;
83 }
84 case LIBINPUT_TABLET_TOOL_TYPE_BRUSH: {
85 return PointerEvent::TOOL_TYPE_BRUSH;
86 }
87 case LIBINPUT_TABLET_TOOL_TYPE_PENCIL: {
88 return PointerEvent::TOOL_TYPE_PENCIL;
89 }
90 case LIBINPUT_TABLET_TOOL_TYPE_AIRBRUSH: {
91 return PointerEvent::TOOL_TYPE_AIRBRUSH;
92 }
93 case LIBINPUT_TABLET_TOOL_TYPE_MOUSE: {
94 return PointerEvent::TOOL_TYPE_MOUSE;
95 }
96 case LIBINPUT_TABLET_TOOL_TYPE_LENS: {
97 return PointerEvent::TOOL_TYPE_LENS;
98 }
99 default: {
100 MMI_HILOGW("Invalid type");
101 return PointerEvent::TOOL_TYPE_PEN;
102 }
103 }
104 }
105
OnTip(struct libinput_event * event)106 bool TabletToolTransformProcessor::OnTip(struct libinput_event* event)
107 {
108 CHKPF(event);
109 auto tabletEvent = libinput_event_get_tablet_tool_event(event);
110 CHKPF(tabletEvent);
111 auto tipState = libinput_event_tablet_tool_get_tip_state(tabletEvent);
112 bool ret = false;
113 switch (tipState) {
114 case LIBINPUT_TABLET_TOOL_TIP_DOWN: {
115 ret = OnTipDown(tabletEvent);
116 if (!ret) {
117 MMI_HILOGE("OnTipDown failed");
118 }
119 break;
120 }
121 case LIBINPUT_TABLET_TOOL_TIP_UP: {
122 ret = OnTipUp(tabletEvent);
123 if (!ret) {
124 MMI_HILOGE("OnTipUp failed");
125 }
126 break;
127 }
128 default: {
129 MMI_HILOGE("Invalid tip state");
130 break;
131 }
132 }
133 return ret;
134 }
135
OnTipDown(struct libinput_event_tablet_tool * event)136 bool TabletToolTransformProcessor::OnTipDown(struct libinput_event_tablet_tool* event)
137 {
138 CALL_DEBUG_ENTER;
139 CHKPF(event);
140 int32_t targetDisplayId = -1;
141 LogicalCoordinate tCoord;
142 if (!WinMgr->CalculateTipPoint(event, targetDisplayId, tCoord)) {
143 MMI_HILOGE("CalculateTipPoint failed");
144 return false;
145 }
146 double tiltX = libinput_event_tablet_tool_get_tilt_x(event);
147 double tiltY = libinput_event_tablet_tool_get_tilt_y(event);
148 double pressure = libinput_event_tablet_tool_get_pressure(event);
149 int32_t toolType = GetToolType(event);
150
151 int64_t time = GetSysClockTime();
152 pointerEvent_->SetActionStartTime(time);
153 pointerEvent_->SetTargetDisplayId(targetDisplayId);
154 pointerEvent_->SetActionTime(time);
155 pointerEvent_->SetPointerAction(PointerEvent::POINTER_ACTION_DOWN);
156
157 PointerEvent::PointerItem item;
158 if (pointerEvent_->GetPointerItem(DEFAULT_POINTER_ID, item)) {
159 pointerEvent_->RemovePointerItem(DEFAULT_POINTER_ID);
160 }
161 item.SetPointerId(DEFAULT_POINTER_ID);
162 item.SetDeviceId(deviceId_);
163 item.SetDownTime(time);
164 item.SetPressed(true);
165 item.SetDisplayX(tCoord.x);
166 item.SetDisplayY(tCoord.y);
167 item.SetTiltX(tiltX);
168 item.SetTiltY(tiltY);
169 item.SetPressure(pressure);
170 item.SetToolType(toolType);
171 item.SetTargetWindowId(-1);
172
173 pointerEvent_->SetDeviceId(deviceId_);
174 pointerEvent_->AddPointerItem(item);
175 pointerEvent_->SetPointerId(DEFAULT_POINTER_ID);
176 return true;
177 }
178
OnTipMotion(struct libinput_event * event)179 bool TabletToolTransformProcessor::OnTipMotion(struct libinput_event* event)
180 {
181 CALL_DEBUG_ENTER;
182 CHKPF(event);
183 auto tabletEvent = libinput_event_get_tablet_tool_event(event);
184 CHKPF(tabletEvent);
185 int64_t time = GetSysClockTime();
186 pointerEvent_->SetActionTime(time);
187 pointerEvent_->SetPointerAction(PointerEvent::POINTER_ACTION_MOVE);
188
189 int32_t targetDisplayId = pointerEvent_->GetTargetDisplayId();
190 LogicalCoordinate tCoord;
191 if (!WinMgr->CalculateTipPoint(tabletEvent, targetDisplayId, tCoord)) {
192 MMI_HILOGE("CalculateTipPoint failed");
193 return false;
194 }
195 double tiltX = libinput_event_tablet_tool_get_tilt_x(tabletEvent);
196 double tiltY = libinput_event_tablet_tool_get_tilt_y(tabletEvent);
197 double pressure = libinput_event_tablet_tool_get_pressure(tabletEvent);
198 int32_t toolType = GetToolType(tabletEvent);
199
200 PointerEvent::PointerItem item;
201 if (!pointerEvent_->GetPointerItem(DEFAULT_POINTER_ID, item)) {
202 MMI_HILOGW("The pointer is expected, but not found");
203 pointerEvent_->SetActionStartTime(time);
204 pointerEvent_->SetTargetDisplayId(targetDisplayId);
205 pointerEvent_->SetDeviceId(deviceId_);
206 pointerEvent_->SetPointerId(DEFAULT_POINTER_ID);
207
208 item.SetPointerId(DEFAULT_POINTER_ID);
209 item.SetDeviceId(deviceId_);
210 item.SetDownTime(time);
211 item.SetPressed(true);
212 item.SetToolType(toolType);
213 }
214 item.SetDisplayX(tCoord.x);
215 item.SetDisplayY(tCoord.y);
216 item.SetTiltX(tiltX);
217 item.SetTiltY(tiltY);
218 item.SetPressure(pressure);
219 pointerEvent_->UpdatePointerItem(DEFAULT_POINTER_ID, item);
220 return true;
221 }
222
OnTipUp(struct libinput_event_tablet_tool * event)223 bool TabletToolTransformProcessor::OnTipUp(struct libinput_event_tablet_tool* event)
224 {
225 CALL_DEBUG_ENTER;
226 CHKPF(event);
227 int64_t time = GetSysClockTime();
228 pointerEvent_->SetActionTime(time);
229 pointerEvent_->SetPointerAction(PointerEvent::POINTER_ACTION_UP);
230
231 PointerEvent::PointerItem item;
232 if (!pointerEvent_->GetPointerItem(DEFAULT_POINTER_ID, item)) {
233 MMI_HILOGE("GetPointerItem failed");
234 return false;
235 }
236 item.SetPressed(false);
237 pointerEvent_->UpdatePointerItem(DEFAULT_POINTER_ID, item);
238 return true;
239 }
240 } // namespace MMI
241 } // namespace OHOS
242