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 "mouse_transform_processor.h"
17
18 #include <cinttypes>
19 #include <functional>
20
21 #include "input-event-codes.h"
22
23 #include "define_multimodal.h"
24 #include "event_log_helper.h"
25 #include "i_pointer_drawing_manager.h"
26 #include "input_device_manager.h"
27 #include "input_event_handler.h"
28 #include "input_windows_manager.h"
29 #include "mouse_device_state.h"
30 #include "preferences.h"
31 #include "preferences_impl.h"
32 #include "preferences_errno.h"
33 #include "preferences_helper.h"
34 #include "preferences_xml_utils.h"
35 #include "timer_manager.h"
36 #include "dfx_hisysevent.h"
37 #include "util_ex.h"
38 #include "util.h"
39 #include "multimodal_input_preferences_manager.h"
40
41 namespace OHOS {
42 namespace MMI {
43 namespace {
44 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { LOG_CORE, MMI_LOG_DOMAIN, "MouseTransformProcessor" };
45 constexpr int32_t MIN_SPEED = 1;
46 constexpr int32_t MAX_SPEED = 11;
47 constexpr int32_t DEFAULT_SPEED = 5;
48 constexpr int32_t DEFAULT_TOUCHPAD_SPEED = 9;
49 constexpr int32_t DEFAULT_ROWS = 3;
50 constexpr int32_t MIN_ROWS = 1;
51 constexpr int32_t MAX_ROWS = 100;
52 constexpr int32_t CALCULATE_MIDDLE = 2;
53 constexpr int32_t BTN_RIGHT_MENUE_CODE = 0x118;
54 constexpr int32_t RIGHT_CLICK_TYPE_MIN = 1;
55 constexpr int32_t RIGHT_CLICK_TYPE_MAX = 3;
56 constexpr int32_t TP_RIGHT_CLICK_FINGER_CNT = 2;
57 const std::string mouseFileName = "mouse_settings.xml";
58 } // namespace
59
60 double MouseTransformProcessor::absolutionX_ = -1.0;
61 double MouseTransformProcessor::absolutionY_ = -1.0;
62 int32_t MouseTransformProcessor::currentDisplayId_ = -1;
63 int32_t MouseTransformProcessor::globalPointerSpeed_ = DEFAULT_SPEED;
64
MouseTransformProcessor(int32_t deviceId)65 MouseTransformProcessor::MouseTransformProcessor(int32_t deviceId)
66 : pointerEvent_(PointerEvent::Create()), deviceId_(deviceId)
67 {
68 globalPointerSpeed_ = GetPointerSpeed();
69 }
70
GetPointerEvent() const71 std::shared_ptr<PointerEvent> MouseTransformProcessor::GetPointerEvent() const
72 {
73 return pointerEvent_;
74 }
75
HandleMotionInner(struct libinput_event_pointer * data,struct libinput_event * event)76 int32_t MouseTransformProcessor::HandleMotionInner(struct libinput_event_pointer* data, struct libinput_event* event)
77 {
78 CALL_DEBUG_ENTER;
79 CHKPR(data, ERROR_NULL_POINTER);
80 CHKPR(pointerEvent_, ERROR_NULL_POINTER);
81 pointerEvent_->SetPointerAction(PointerEvent::POINTER_ACTION_MOVE);
82 pointerEvent_->SetButtonId(buttonId_);
83
84 InitAbsolution();
85 if (currentDisplayId_ == -1) {
86 absolutionX_ = -1;
87 absolutionY_ = -1;
88 MMI_HILOGI("The currentDisplayId_ is -1");
89 return RET_ERR;
90 }
91
92 Offset offset = {libinput_event_pointer_get_dx_unaccelerated(data),
93 libinput_event_pointer_get_dy_unaccelerated(data)};
94 auto displayInfo = WinMgr->GetPhysicalDisplay(currentDisplayId_);
95 CHKPR(displayInfo, ERROR_NULL_POINTER);
96 if (displayInfo->displayDirection == DIRECTION0) {
97 CalculateOffset(displayInfo->direction, offset);
98 }
99 const int32_t type = libinput_event_get_type(event);
100 int32_t ret = RET_ERR;
101 if (type == LIBINPUT_EVENT_POINTER_MOTION_TOUCHPAD) {
102 ret = HandleMotionAccelerate(&offset, WinMgr->GetMouseIsCaptureMode(), &absolutionX_,
103 &absolutionY_, GetTouchpadSpeed());
104 } else {
105 ret = HandleMotionAccelerate(&offset, WinMgr->GetMouseIsCaptureMode(), &absolutionX_,
106 &absolutionY_, globalPointerSpeed_);
107 }
108 if (ret != RET_OK) {
109 MMI_HILOGE("Failed to handle motion correction");
110 return ret;
111 }
112 #ifdef OHOS_BUILD_EMULATOR
113 absolutionX_ = offset.dx;
114 absolutionY_ = offset.dy;
115 #endif // OHOS_BUILD_EMULATOR
116 WinMgr->UpdateAndAdjustMouseLocation(currentDisplayId_, absolutionX_, absolutionY_);
117 pointerEvent_->SetTargetDisplayId(currentDisplayId_);
118 MMI_HILOGD("Change coordinate: x:%{public}lf, y:%{public}lf, currentDisplayId_:%{public}d",
119 absolutionX_, absolutionY_, currentDisplayId_);
120 return RET_OK;
121 }
122
CalculateOffset(Direction direction,Offset & offset)123 void MouseTransformProcessor::CalculateOffset(Direction direction, Offset &offset)
124 {
125 std::negate<double> neg;
126 if (direction == DIRECTION90) {
127 double tmp = offset.dx;
128 offset.dx = offset.dy;
129 offset.dy = neg(tmp);
130 } else if (direction == DIRECTION180) {
131 offset.dx = neg(offset.dx);
132 offset.dy = neg(offset.dy);
133 } else if (direction == DIRECTION270) {
134 double tmp = offset.dx;
135 offset.dx = neg(offset.dy);
136 offset.dy = tmp;
137 }
138 }
139
InitAbsolution()140 void MouseTransformProcessor::InitAbsolution()
141 {
142 CALL_DEBUG_ENTER;
143 if (absolutionX_ != -1 || absolutionY_ != -1 || currentDisplayId_ != -1) {
144 MMI_HILOGW("Unable to initialize coordinate information");
145 return;
146 }
147 auto displayGroupInfo = WinMgr->GetDisplayGroupInfo();
148 if (displayGroupInfo.displaysInfo.empty()) {
149 MMI_HILOGI("The displayInfo is empty");
150 return;
151 }
152 currentDisplayId_ = displayGroupInfo.displaysInfo[0].id;
153 absolutionX_ = displayGroupInfo.displaysInfo[0].width * 1.0 / CALCULATE_MIDDLE;
154 absolutionY_ = displayGroupInfo.displaysInfo[0].height * 1.0 / CALCULATE_MIDDLE;
155 }
156
HandleButtonInner(struct libinput_event_pointer * data,struct libinput_event * event)157 int32_t MouseTransformProcessor::HandleButtonInner(struct libinput_event_pointer* data, struct libinput_event* event)
158 {
159 CALL_DEBUG_ENTER;
160 CHKPR(data, ERROR_NULL_POINTER);
161 CHKPR(pointerEvent_, ERROR_NULL_POINTER);
162 MMI_HILOGD("Current action:%{public}d", pointerEvent_->GetPointerAction());
163
164 uint32_t button = libinput_event_pointer_get_button(data);
165 const int32_t type = libinput_event_get_type(event);
166 bool tpTapSwitch = true;
167 if (GetTouchpadTapSwitch(tpTapSwitch) != RET_OK) {
168 MMI_HILOGD("Failed to get touch pad switch flag, default is true.");
169 }
170
171 // touch pad tap switch is disable
172 if (type == LIBINPUT_EVENT_POINTER_TAP && tpTapSwitch == false) {
173 MMI_HILOGD("Touch pad is disable.");
174 return RET_ERR;
175 }
176
177 TransTouchpadRightButton(data, type, button);
178
179 if (button == MouseDeviceState::LIBINPUT_BUTTON_CODE::LIBINPUT_MIDDLE_BUTTON_CODE &&
180 type == LIBINPUT_EVENT_POINTER_BUTTON_TOUCHPAD) {
181 button = MouseDeviceState::LIBINPUT_BUTTON_CODE::LIBINPUT_LEFT_BUTTON_CODE;
182 }
183
184 auto ret = HandleButtonValueInner(data, button, type);
185 if (ret != RET_OK) {
186 MMI_HILOGE("The button value does not exist");
187 return RET_ERR;
188 }
189
190 auto state = libinput_event_pointer_get_button_state(data);
191 if (state == LIBINPUT_BUTTON_STATE_RELEASED) {
192 MouseState->MouseBtnStateCounts(button, BUTTON_STATE_RELEASED);
193 pointerEvent_->SetPointerAction(PointerEvent::POINTER_ACTION_BUTTON_UP);
194 int32_t buttonId = MouseState->LibinputChangeToPointer(button);
195 pointerEvent_->DeleteReleaseButton(buttonId);
196 isPressed_ = false;
197 buttonId_ = PointerEvent::BUTTON_NONE;
198 } else if (state == LIBINPUT_BUTTON_STATE_PRESSED) {
199 MouseState->MouseBtnStateCounts(button, BUTTON_STATE_PRESSED);
200 pointerEvent_->SetPointerAction(PointerEvent::POINTER_ACTION_BUTTON_DOWN);
201 int32_t buttonId = MouseState->LibinputChangeToPointer(button);
202 pointerEvent_->SetButtonPressed(buttonId);
203 isPressed_ = true;
204 buttonId_ = pointerEvent_->GetButtonId();
205 } else {
206 MMI_HILOGE("Unknown state, state:%{public}u", state);
207 return RET_ERR;
208 }
209 return RET_OK;
210 }
211
HandleButtonValueInner(struct libinput_event_pointer * data,uint32_t button,int32_t type)212 int32_t MouseTransformProcessor::HandleButtonValueInner(struct libinput_event_pointer *data, uint32_t button,
213 int32_t type)
214 {
215 CALL_DEBUG_ENTER;
216 CHKPR(data, ERROR_NULL_POINTER);
217 CHKPR(pointerEvent_, ERROR_NULL_POINTER);
218 int32_t buttonId = MouseState->LibinputChangeToPointer(button);
219 if (buttonId == PointerEvent::BUTTON_NONE) {
220 MMI_HILOGE("Unknown btn, btn:%{public}u", button);
221 return RET_ERR;
222 }
223
224 std::string name = "primaryButton";
225 int32_t primaryButton = PreferencesMgr->GetIntValue(name, 0);
226 MMI_HILOGD("Set mouse primary button:%{public}d", primaryButton);
227 if (type == LIBINPUT_EVENT_POINTER_BUTTON && primaryButton == RIGHT_BUTTON) {
228 if (buttonId == PointerEvent::MOUSE_BUTTON_LEFT) {
229 buttonId = PointerEvent::MOUSE_BUTTON_RIGHT;
230 } else if (buttonId == PointerEvent::MOUSE_BUTTON_RIGHT) {
231 buttonId = PointerEvent::MOUSE_BUTTON_LEFT;
232 } else {
233 MMI_HILOGD("buttonId does not switch.");
234 }
235 }
236
237 pointerEvent_->SetButtonId(buttonId);
238 return RET_OK;
239 }
240
SetMouseScrollRows(int32_t rows)241 int32_t MouseTransformProcessor::SetMouseScrollRows(int32_t rows)
242 {
243 CALL_DEBUG_ENTER;
244 if (rows < MIN_ROWS) {
245 rows = MIN_ROWS;
246 } else if (rows > MAX_ROWS) {
247 rows = MAX_ROWS;
248 }
249 std::string name = "rows";
250 int32_t ret = PreferencesMgr->SetIntValue(name, mouseFileName, rows);
251 MMI_HILOGD("Set mouse scroll rows successfully, rows:%{public}d", rows);
252 return ret;
253 }
254
GetMouseScrollRows()255 int32_t MouseTransformProcessor::GetMouseScrollRows()
256 {
257 CALL_DEBUG_ENTER;
258 std::string name = "rows";
259 int32_t rows = PreferencesMgr->GetIntValue(name, DEFAULT_ROWS);
260 MMI_HILOGD("Get mouse scroll rows successfully, rows:%{public}d", rows);
261 return rows;
262 }
263
HandleTouchPadAxisState(libinput_pointer_axis_source source,int32_t & direction,bool & tpScrollSwitch)264 void MouseTransformProcessor::HandleTouchPadAxisState(libinput_pointer_axis_source source,
265 int32_t& direction, bool& tpScrollSwitch)
266 {
267 bool scrollDirectionState = true;
268
269 if (GetTouchpadScrollSwitch(tpScrollSwitch) != RET_OK) {
270 MMI_HILOGE("Failed to get scroll switch flag, default is true.");
271 }
272
273 if (GetTouchpadScrollDirection(scrollDirectionState) != RET_OK) {
274 MMI_HILOGE("Failed to get scroll direct switch flag, default is true.");
275 }
276
277 if (scrollDirectionState == true && source == LIBINPUT_POINTER_AXIS_SOURCE_FINGER) {
278 direction = -1;
279 }
280 }
281
HandleAxisInner(struct libinput_event_pointer * data)282 int32_t MouseTransformProcessor::HandleAxisInner(struct libinput_event_pointer* data)
283 {
284 CALL_DEBUG_ENTER;
285 CHKPR(data, ERROR_NULL_POINTER);
286 CHKPR(pointerEvent_, ERROR_NULL_POINTER);
287
288 bool tpScrollSwitch = true;
289 int32_t tpScrollDirection = 1;
290
291 libinput_pointer_axis_source source = libinput_event_pointer_get_axis_source(data);
292 HandleTouchPadAxisState(source, tpScrollDirection, tpScrollSwitch);
293 if (tpScrollSwitch == false && source == LIBINPUT_POINTER_AXIS_SOURCE_FINGER) {
294 MMI_HILOGD("TouchPad axis event is disable.");
295 return RET_ERR;
296 }
297
298 if (buttonId_ == PointerEvent::BUTTON_NONE && pointerEvent_->GetButtonId() != PointerEvent::BUTTON_NONE) {
299 pointerEvent_->SetButtonId(PointerEvent::BUTTON_NONE);
300 }
301 if (libinput_event_pointer_get_axis_source(data) == LIBINPUT_POINTER_AXIS_SOURCE_FINGER) {
302 pointerEvent_->SetPointerAction(PointerEvent::POINTER_ACTION_AXIS_UPDATE);
303 } else {
304 if (TimerMgr->IsExist(timerId_)) {
305 pointerEvent_->SetPointerAction(PointerEvent::POINTER_ACTION_AXIS_UPDATE);
306 TimerMgr->ResetTimer(timerId_);
307 MMI_HILOGD("Axis update");
308 } else {
309 static constexpr int32_t timeout = 100;
310 std::weak_ptr<MouseTransformProcessor> weakPtr = shared_from_this();
311 timerId_ = TimerMgr->AddTimer(timeout, 1, [weakPtr]() {
312 CALL_DEBUG_ENTER;
313 auto sharedPtr = weakPtr.lock();
314 CHKPV(sharedPtr);
315 MMI_HILOGD("timer:%{public}d", sharedPtr->timerId_);
316 sharedPtr->timerId_ = -1;
317 auto pointerEvent = sharedPtr->GetPointerEvent();
318 CHKPV(pointerEvent);
319 pointerEvent->SetPointerAction(PointerEvent::POINTER_ACTION_AXIS_END);
320 pointerEvent->UpdateId();
321 auto inputEventNormalizeHandler = InputHandler->GetEventNormalizeHandler();
322 CHKPV(inputEventNormalizeHandler);
323 inputEventNormalizeHandler->HandlePointerEvent(pointerEvent);
324 });
325
326 pointerEvent_->SetPointerAction(PointerEvent::POINTER_ACTION_AXIS_BEGIN);
327 MMI_HILOGD("Axis begin");
328 }
329 }
330
331 const int32_t initRows = 3;
332 if (libinput_event_pointer_has_axis(data, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL)) {
333 double axisValue = libinput_event_pointer_get_axis_value(data, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL);
334 axisValue = GetMouseScrollRows() * (axisValue / initRows) * tpScrollDirection;
335 pointerEvent_->SetAxisValue(PointerEvent::AXIS_TYPE_SCROLL_VERTICAL, axisValue);
336 }
337 if (libinput_event_pointer_has_axis(data, LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL)) {
338 double axisValue = libinput_event_pointer_get_axis_value(data, LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL);
339 axisValue = GetMouseScrollRows() * (axisValue / initRows) * tpScrollDirection;
340 pointerEvent_->SetAxisValue(PointerEvent::AXIS_TYPE_SCROLL_HORIZONTAL, axisValue);
341 }
342 return RET_OK;
343 }
344
HandleAxisBeginEndInner(struct libinput_event * event)345 int32_t MouseTransformProcessor::HandleAxisBeginEndInner(struct libinput_event *event)
346 {
347 CALL_DEBUG_ENTER;
348 CHKPR(event, ERROR_NULL_POINTER);
349 CHKPR(pointerEvent_, ERROR_NULL_POINTER);
350 if (buttonId_ == PointerEvent::BUTTON_NONE && pointerEvent_->GetButtonId() != PointerEvent::BUTTON_NONE) {
351 pointerEvent_->SetButtonId(PointerEvent::BUTTON_NONE);
352 }
353 if (!isAxisBegin_ && isPressed_) {
354 MMI_HILOGE("Axis is invalid");
355 return RET_ERR;
356 }
357 if (isAxisBegin_ && isPressed_) {
358 pointerEvent_->SetPointerAction(PointerEvent::POINTER_ACTION_AXIS_END);
359 isAxisBegin_ = false;
360 MMI_HILOGD("Axis end due to a pressed event");
361 return RET_OK;
362 }
363 if (libinput_event_get_type(event) == LIBINPUT_EVENT_TOUCHPAD_DOWN && !isPressed_) {
364 pointerEvent_->SetPointerAction(PointerEvent::POINTER_ACTION_AXIS_BEGIN);
365 isAxisBegin_ = true;
366 MMI_HILOGD("Axis begin");
367 return RET_OK;
368 }
369 if (libinput_event_get_type(event) == LIBINPUT_EVENT_TOUCHPAD_UP && !isPressed_) {
370 pointerEvent_->SetPointerAction(PointerEvent::POINTER_ACTION_AXIS_END);
371 isAxisBegin_ = false;
372 MMI_HILOGD("Axis end");
373 return RET_OK;
374 }
375 MMI_HILOGE("Axis is invalid");
376 return RET_ERR;
377 }
378
HandleAxisPostInner(PointerEvent::PointerItem & pointerItem)379 void MouseTransformProcessor::HandleAxisPostInner(PointerEvent::PointerItem &pointerItem)
380 {
381 CALL_DEBUG_ENTER;
382 CHKPV(pointerEvent_);
383 auto mouseInfo = WinMgr->GetMouseInfo();
384 MouseState->SetMouseCoords(mouseInfo.physicalX, mouseInfo.physicalY);
385 pointerItem.SetDisplayX(mouseInfo.physicalX);
386 pointerItem.SetDisplayY(mouseInfo.physicalY);
387 pointerItem.SetWindowX(0);
388 pointerItem.SetWindowY(0);
389 pointerItem.SetPointerId(0);
390 pointerItem.SetPressed(isPressed_);
391 int64_t time = GetSysClockTime();
392 pointerItem.SetDownTime(time);
393 pointerItem.SetWidth(0);
394 pointerItem.SetHeight(0);
395 pointerItem.SetPressure(0);
396 pointerItem.SetToolType(PointerEvent::TOOL_TYPE_TOUCHPAD);
397 pointerItem.SetDeviceId(deviceId_);
398 pointerItem.SetRawDx(0);
399 pointerItem.SetRawDy(0);
400 pointerEvent_->UpdateId();
401 pointerEvent_->UpdatePointerItem(pointerEvent_->GetPointerId(), pointerItem);
402 pointerEvent_->SetSourceType(PointerEvent::SOURCE_TYPE_MOUSE);
403 pointerEvent_->SetActionTime(time);
404 pointerEvent_->SetActionStartTime(time);
405 pointerEvent_->SetPointerId(0);
406 pointerEvent_->SetDeviceId(deviceId_);
407 pointerEvent_->SetTargetDisplayId(currentDisplayId_);
408 pointerEvent_->SetTargetWindowId(-1);
409 pointerEvent_->SetAgentWindowId(-1);
410 }
411
HandlePostInner(struct libinput_event_pointer * data,PointerEvent::PointerItem & pointerItem)412 void MouseTransformProcessor::HandlePostInner(struct libinput_event_pointer* data,
413 PointerEvent::PointerItem &pointerItem)
414 {
415 CALL_DEBUG_ENTER;
416 CHKPV(data);
417 CHKPV(pointerEvent_);
418 auto mouseInfo = WinMgr->GetMouseInfo();
419 MouseState->SetMouseCoords(mouseInfo.physicalX, mouseInfo.physicalY);
420 pointerItem.SetDisplayX(mouseInfo.physicalX);
421 pointerItem.SetDisplayY(mouseInfo.physicalY);
422 pointerItem.SetWindowX(0);
423 pointerItem.SetWindowY(0);
424 pointerItem.SetPointerId(0);
425 pointerItem.SetPressed(isPressed_);
426
427 int64_t time = GetSysClockTime();
428 pointerItem.SetDownTime(time);
429 pointerItem.SetWidth(0);
430 pointerItem.SetHeight(0);
431 pointerItem.SetPressure(0);
432 if (libinput_event_pointer_get_axis_source(data) == LIBINPUT_POINTER_AXIS_SOURCE_FINGER) {
433 pointerItem.SetToolType(PointerEvent::TOOL_TYPE_TOUCHPAD);
434 MMI_HILOGD("ToolType is touchpad");
435 } else {
436 pointerItem.SetToolType(PointerEvent::TOOL_TYPE_MOUSE);
437 }
438 pointerItem.SetDeviceId(deviceId_);
439 SetDxDyForDInput(pointerItem, data);
440 pointerEvent_->UpdateId();
441 pointerEvent_->UpdatePointerItem(pointerEvent_->GetPointerId(), pointerItem);
442 pointerEvent_->SetSourceType(PointerEvent::SOURCE_TYPE_MOUSE);
443 pointerEvent_->SetActionTime(time);
444 pointerEvent_->SetActionStartTime(time);
445 pointerEvent_->SetDeviceId(deviceId_);
446 pointerEvent_->SetPointerId(0);
447 pointerEvent_->SetTargetDisplayId(currentDisplayId_);
448 pointerEvent_->SetTargetWindowId(-1);
449 pointerEvent_->SetAgentWindowId(-1);
450 }
451
Normalize(struct libinput_event * event)452 int32_t MouseTransformProcessor::Normalize(struct libinput_event *event)
453 {
454 CALL_DEBUG_ENTER;
455 CHKPR(event, ERROR_NULL_POINTER);
456 CHKPR(pointerEvent_, ERROR_NULL_POINTER);
457 const int32_t type = libinput_event_get_type(event);
458 auto data = libinput_event_get_pointer_event(event);
459 if (type != LIBINPUT_EVENT_TOUCHPAD_DOWN && type != LIBINPUT_EVENT_TOUCHPAD_UP) {
460 CHKPR(data, ERROR_NULL_POINTER);
461 }
462 pointerEvent_->ClearAxisValue();
463 int32_t result;
464 switch (type) {
465 case LIBINPUT_EVENT_POINTER_MOTION:
466 case LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE:
467 case LIBINPUT_EVENT_POINTER_MOTION_TOUCHPAD:
468 result = HandleMotionInner(data, event);
469 break;
470 case LIBINPUT_EVENT_POINTER_TAP:
471 case LIBINPUT_EVENT_POINTER_BUTTON:
472 case LIBINPUT_EVENT_POINTER_BUTTON_TOUCHPAD:
473 result = HandleButtonInner(data, event);
474 break;
475 case LIBINPUT_EVENT_POINTER_AXIS:
476 result = HandleAxisInner(data);
477 break;
478 case LIBINPUT_EVENT_TOUCHPAD_DOWN:
479 case LIBINPUT_EVENT_TOUCHPAD_UP:
480 result = HandleAxisBeginEndInner(event);
481 break;
482 default:
483 MMI_HILOGE("Unknown type:%{public}d", type);
484 return RET_ERR;
485 }
486 if (result == RET_ERR) {
487 return result;
488 }
489 PointerEvent::PointerItem pointerItem;
490 if (type == LIBINPUT_EVENT_TOUCHPAD_DOWN || type == LIBINPUT_EVENT_TOUCHPAD_UP) {
491 HandleAxisPostInner(pointerItem);
492 } else {
493 HandlePostInner(data, pointerItem);
494 }
495 WinMgr->UpdateTargetPointer(pointerEvent_);
496 DumpInner();
497 return result;
498 }
499
NormalizeRotateEvent(struct libinput_event * event,int32_t type,double angle)500 int32_t MouseTransformProcessor::NormalizeRotateEvent(struct libinput_event *event, int32_t type, double angle)
501 {
502 CALL_DEBUG_ENTER;
503 CHKPR(event, ERROR_NULL_POINTER);
504 CHKPR(pointerEvent_, ERROR_NULL_POINTER);
505 auto data = libinput_event_get_pointer_event(event);
506 pointerEvent_->SetPointerAction(type);
507 pointerEvent_->ClearAxisValue();
508 pointerEvent_->SetAxisValue(PointerEvent::AXIS_TYPE_ROTATE, angle);
509 PointerEvent::PointerItem pointerItem;
510 HandlePostInner(data, pointerItem);
511 WinMgr->UpdateTargetPointer(pointerEvent_);
512 DumpInner();
513 return RET_OK;
514 }
515
516 #ifdef OHOS_BUILD_ENABLE_POINTER_DRAWING
HandleMotionMoveMouse(int32_t offsetX,int32_t offsetY)517 void MouseTransformProcessor::HandleMotionMoveMouse(int32_t offsetX, int32_t offsetY)
518 {
519 CALL_DEBUG_ENTER;
520 CHKPV(pointerEvent_);
521 pointerEvent_->SetPointerAction(PointerEvent::POINTER_ACTION_MOVE);
522 InitAbsolution();
523 absolutionX_ += offsetX;
524 absolutionY_ += offsetY;
525 WinMgr->UpdateAndAdjustMouseLocation(currentDisplayId_, absolutionX_, absolutionY_);
526 }
527
OnDisplayLost(int32_t displayId)528 void MouseTransformProcessor::OnDisplayLost(int32_t displayId)
529 {
530 if (currentDisplayId_ != displayId) {
531 currentDisplayId_ = -1;
532 absolutionX_ = -1;
533 absolutionY_ = -1;
534 InitAbsolution();
535 WinMgr->UpdateAndAdjustMouseLocation(currentDisplayId_, absolutionX_, absolutionY_);
536 }
537 }
538
GetDisplayId()539 int32_t MouseTransformProcessor::GetDisplayId()
540 {
541 return currentDisplayId_;
542 }
543
HandlePostMoveMouse(PointerEvent::PointerItem & pointerItem)544 void MouseTransformProcessor::HandlePostMoveMouse(PointerEvent::PointerItem& pointerItem)
545 {
546 CALL_DEBUG_ENTER;
547 auto mouseInfo = WinMgr->GetMouseInfo();
548 CHKPV(pointerEvent_);
549 MouseState->SetMouseCoords(mouseInfo.physicalX, mouseInfo.physicalY);
550 pointerItem.SetDisplayX(mouseInfo.physicalX);
551 pointerItem.SetDisplayY(mouseInfo.physicalY);
552 pointerItem.SetWindowX(0);
553 pointerItem.SetWindowY(0);
554 pointerItem.SetPointerId(0);
555 pointerItem.SetPressed(isPressed_);
556
557 int64_t time = GetSysClockTime();
558 pointerItem.SetDownTime(time);
559 pointerItem.SetWidth(0);
560 pointerItem.SetHeight(0);
561 pointerItem.SetPressure(0);
562
563 pointerEvent_->UpdateId();
564 pointerEvent_->UpdatePointerItem(pointerEvent_->GetPointerId(), pointerItem);
565 pointerEvent_->SetSourceType(PointerEvent::SOURCE_TYPE_MOUSE);
566 pointerEvent_->SetActionTime(time);
567 pointerEvent_->SetActionStartTime(time);
568
569 pointerEvent_->SetPointerId(0);
570 pointerEvent_->SetTargetDisplayId(-1);
571 pointerEvent_->SetTargetWindowId(-1);
572 pointerEvent_->SetAgentWindowId(-1);
573 }
574
NormalizeMoveMouse(int32_t offsetX,int32_t offsetY)575 bool MouseTransformProcessor::NormalizeMoveMouse(int32_t offsetX, int32_t offsetY)
576 {
577 CALL_DEBUG_ENTER;
578 CHKPF(pointerEvent_);
579 bool bHasPointerDevice = InputDevMgr->HasPointerDevice();
580 if (!bHasPointerDevice) {
581 MMI_HILOGE("There hasn't any pointer device");
582 return false;
583 }
584
585 PointerEvent::PointerItem pointerItem;
586 HandleMotionMoveMouse(offsetX, offsetY);
587 HandlePostMoveMouse(pointerItem);
588 DumpInner();
589 return bHasPointerDevice;
590 }
591 #endif // OHOS_BUILD_ENABLE_POINTER_DRAWING
592
DumpInner()593 void MouseTransformProcessor::DumpInner()
594 {
595 EventLogHelper::PrintEventData(pointerEvent_);
596 auto device = InputDevMgr->GetInputDevice(pointerEvent_->GetDeviceId());
597 CHKPV(device);
598 MMI_HILOGI("The id:%{public}d event created by:%{public}s", pointerEvent_->GetId(), device->GetName().c_str());
599 }
600
Dump(int32_t fd,const std::vector<std::string> & args)601 void MouseTransformProcessor::Dump(int32_t fd, const std::vector<std::string> &args)
602 {
603 CALL_DEBUG_ENTER;
604 PointerEvent::PointerItem item;
605 CHKPV(pointerEvent_);
606 pointerEvent_->GetPointerItem(pointerEvent_->GetPointerId(), item);
607 mprintf(fd, "Mouse device state information:\t");
608 mprintf(fd,
609 "PointerId:%d | SourceType:%s | PointerAction:%s | WindowX:%d | WindowY:%d | ButtonId:%d "
610 "| AgentWindowId:%d | TargetWindowId:%d | DownTime:%" PRId64 " | IsPressed:%s \t",
611 pointerEvent_->GetPointerId(), pointerEvent_->DumpSourceType(), pointerEvent_->DumpPointerAction(),
612 item.GetWindowX(), item.GetWindowY(), pointerEvent_->GetButtonId(), pointerEvent_->GetAgentWindowId(),
613 pointerEvent_->GetTargetWindowId(), item.GetDownTime(), item.IsPressed() ? "true" : "false");
614 }
615
SetMousePrimaryButton(int32_t primaryButton)616 int32_t MouseTransformProcessor::SetMousePrimaryButton(int32_t primaryButton)
617 {
618 CALL_DEBUG_ENTER;
619 MMI_HILOGD("Set mouse primary button:%{public}d", primaryButton);
620 std::string name = "primaryButton";
621 PreferencesMgr->SetIntValue(name, mouseFileName, primaryButton);
622 return RET_OK;
623 }
624
GetMousePrimaryButton()625 int32_t MouseTransformProcessor::GetMousePrimaryButton()
626 {
627 CALL_DEBUG_ENTER;
628 std::string name = "primaryButton";
629 int32_t primaryButton = PreferencesMgr->GetIntValue(name, 0);
630 MMI_HILOGD("Set mouse primary button:%{public}d", primaryButton);
631 return primaryButton;
632 }
633
SetPointerSpeed(int32_t speed)634 int32_t MouseTransformProcessor::SetPointerSpeed(int32_t speed)
635 {
636 CALL_DEBUG_ENTER;
637 if (speed < MIN_SPEED) {
638 speed = MIN_SPEED;
639 } else if (speed > MAX_SPEED) {
640 speed = MAX_SPEED;
641 }
642 globalPointerSpeed_ = speed;
643 std::string name = "speed";
644 int32_t ret = PreferencesMgr->SetIntValue(name, mouseFileName, speed);
645 MMI_HILOGD("Set pointer speed successfully, speed:%{public}d", speed);
646 return ret;
647 }
648
GetPointerSpeed()649 int32_t MouseTransformProcessor::GetPointerSpeed()
650 {
651 CALL_DEBUG_ENTER;
652 std::string name = "speed";
653 int32_t speed = PreferencesMgr->GetIntValue(name, DEFAULT_SPEED);
654 MMI_HILOGD("Get pointer speed successfully, speed:%{public}d", speed);
655 return speed;
656 }
657
GetTouchpadSpeed(void)658 int32_t MouseTransformProcessor::GetTouchpadSpeed(void)
659 {
660 int32_t speed = DEFAULT_TOUCHPAD_SPEED;
661 if (GetTouchpadPointerSpeed(speed) != RET_OK) {
662 // if failed to get touchpad from database, return DEFAULT_TOUCHPAD_SPEED
663 return DEFAULT_TOUCHPAD_SPEED;
664 }
665
666 return speed;
667 }
668
SetDxDyForDInput(PointerEvent::PointerItem & pointerItem,struct libinput_event_pointer * data)669 void MouseTransformProcessor::SetDxDyForDInput(PointerEvent::PointerItem& pointerItem,
670 struct libinput_event_pointer* data)
671 {
672 double dx = libinput_event_pointer_get_dx(data);
673 double dy = libinput_event_pointer_get_dy(data);
674 int32_t rawDx = static_cast<int32_t>(dx);
675 int32_t rawDy = static_cast<int32_t>(dy);
676 pointerItem.SetRawDx(rawDx);
677 pointerItem.SetRawDy(rawDy);
678 MMI_HILOGD("MouseTransformProcessor SetDxDyForDInput, dx:%{public}d, dy:%{public}d", rawDx, rawDy);
679 }
680
SetPointerLocation(int32_t x,int32_t y)681 int32_t MouseTransformProcessor::SetPointerLocation(int32_t x, int32_t y)
682 {
683 MMI_HILOGI("Location, x:%{public}d, y:%{public}d", x, y);
684 auto displayGroupInfo = WinMgr->GetDisplayGroupInfo();
685 if (currentDisplayId_ == -1) {
686 if (displayGroupInfo.displaysInfo.empty()) {
687 MMI_HILOGI("The displayInfo is empty");
688 return RET_ERR;
689 }
690 currentDisplayId_ = displayGroupInfo.displaysInfo[0].id;
691 }
692 absolutionX_ = static_cast<double>(x);
693 absolutionY_ = static_cast<double>(y);
694 WinMgr->UpdateAndAdjustMouseLocation(currentDisplayId_, absolutionX_, absolutionY_);
695 int32_t physicalX = WinMgr->GetMouseInfo().physicalX;
696 int32_t physicalY = WinMgr->GetMouseInfo().physicalY;
697 IPointerDrawingManager::GetInstance()->SetPointerLocation(physicalX, physicalY);
698 return RET_OK;
699 }
700
HandleTouchpadRightButton(struct libinput_event_pointer * data,const int32_t evenType,uint32_t & button)701 void MouseTransformProcessor::HandleTouchpadRightButton(struct libinput_event_pointer *data, const int32_t evenType,
702 uint32_t &button)
703 {
704 // touchpad left click 280 -> 272
705 if (button == BTN_RIGHT_MENUE_CODE) {
706 button = MouseDeviceState::LIBINPUT_BUTTON_CODE::LIBINPUT_LEFT_BUTTON_CODE;
707 return;
708 }
709
710 // touchpad two finger tap 273 -> 0
711 if (button == MouseDeviceState::LIBINPUT_BUTTON_CODE::LIBINPUT_RIGHT_BUTTON_CODE &&
712 evenType == LIBINPUT_EVENT_POINTER_TAP) {
713 button = 0;
714 return;
715 }
716
717 // touchpad two finger button 272 -> 0
718 if (button == MouseDeviceState::LIBINPUT_BUTTON_CODE::LIBINPUT_LEFT_BUTTON_CODE &&
719 evenType == LIBINPUT_EVENT_POINTER_BUTTON_TOUCHPAD) {
720 return;
721 }
722 }
723
HandleTouchpadLeftButton(struct libinput_event_pointer * data,const int32_t evenType,uint32_t & button)724 void MouseTransformProcessor::HandleTouchpadLeftButton(struct libinput_event_pointer *data, const int32_t evenType,
725 uint32_t &button)
726 {
727 // touchpad left click 280 -> 273
728 if (button == BTN_RIGHT_MENUE_CODE) {
729 button = MouseDeviceState::LIBINPUT_BUTTON_CODE::LIBINPUT_RIGHT_BUTTON_CODE;
730 return;
731 }
732
733 // touchpad right click 273 -> 272
734 if (button == MouseDeviceState::LIBINPUT_BUTTON_CODE::LIBINPUT_RIGHT_BUTTON_CODE &&
735 evenType != LIBINPUT_EVENT_POINTER_TAP) {
736 button = MouseDeviceState::LIBINPUT_BUTTON_CODE::LIBINPUT_LEFT_BUTTON_CODE;
737 return;
738 }
739
740 // touchpad two finger tap 273 -> 0
741 if (button == MouseDeviceState::LIBINPUT_BUTTON_CODE::LIBINPUT_RIGHT_BUTTON_CODE &&
742 evenType == LIBINPUT_EVENT_POINTER_TAP) {
743 button = 0;
744 return;
745 }
746
747 // touchpad two finger button 272 -> 0
748 if (button == MouseDeviceState::LIBINPUT_BUTTON_CODE::LIBINPUT_LEFT_BUTTON_CODE &&
749 evenType == LIBINPUT_EVENT_POINTER_BUTTON_TOUCHPAD) {
750 return;
751 }
752 }
753
HandleTouchpadTwoFingerButton(struct libinput_event_pointer * data,const int32_t evenType,uint32_t & button)754 void MouseTransformProcessor::HandleTouchpadTwoFingerButton(struct libinput_event_pointer *data, const int32_t evenType,
755 uint32_t &button)
756 {
757 // touchpad right click 273 -> 272
758 if (button == MouseDeviceState::LIBINPUT_BUTTON_CODE::LIBINPUT_RIGHT_BUTTON_CODE &&
759 evenType == LIBINPUT_EVENT_POINTER_BUTTON_TOUCHPAD) {
760 button = MouseDeviceState::LIBINPUT_BUTTON_CODE::LIBINPUT_LEFT_BUTTON_CODE;
761 return;
762 }
763
764 // touchpad left click 280 -> 272
765 if (button == BTN_RIGHT_MENUE_CODE) {
766 button = MouseDeviceState::LIBINPUT_BUTTON_CODE::LIBINPUT_LEFT_BUTTON_CODE;
767 return;
768 }
769
770 // touchpad two finger button 272 -> 273
771 if (button == MouseDeviceState::LIBINPUT_BUTTON_CODE::LIBINPUT_LEFT_BUTTON_CODE &&
772 evenType == LIBINPUT_EVENT_POINTER_BUTTON_TOUCHPAD) {
773 uint32_t fingerCount = libinput_event_pointer_get_finger_count(data);
774 if (fingerCount == TP_RIGHT_CLICK_FINGER_CNT) {
775 button = MouseDeviceState::LIBINPUT_BUTTON_CODE::LIBINPUT_RIGHT_BUTTON_CODE;
776 }
777 return;
778 }
779 }
780
TransTouchpadRightButton(struct libinput_event_pointer * data,const int32_t evenType,uint32_t & button)781 void MouseTransformProcessor::TransTouchpadRightButton(struct libinput_event_pointer *data, const int32_t evenType,
782 uint32_t &button)
783 {
784 int32_t switchTypeData = RIGHT_CLICK_TYPE_MIN;
785 if (GetTouchpadRightClickType(switchTypeData) != RET_OK) {
786 MMI_HILOGD("Failed to get right click switch, default is TP_RIGHT_BUTTON.");
787 }
788
789 RightClickType switchType = RightClickType(switchTypeData);
790 if (evenType != LIBINPUT_EVENT_POINTER_TAP && evenType != LIBINPUT_EVENT_POINTER_BUTTON_TOUCHPAD) {
791 MMI_HILOGD("Event not from touchpad.");
792 return;
793 }
794
795 switch (switchType) {
796 case RightClickType::TP_RIGHT_BUTTON:
797 HandleTouchpadRightButton(data, evenType, button);
798 break;
799
800 case RightClickType::TP_LEFT_BUTTON:
801 HandleTouchpadLeftButton(data, evenType, button);
802 break;
803
804 case RightClickType::TP_TWO_FINGER_TAP:
805 HandleTouchpadTwoFingerButton(data, evenType, button);
806 break;
807 default:
808 MMI_HILOGD("Invalid type.");
809 break;
810 }
811 }
812
SetTouchpadScrollSwitch(bool switchFlag)813 int32_t MouseTransformProcessor::SetTouchpadScrollSwitch(bool switchFlag)
814 {
815 std::string name = "scrollSwitch";
816 if (PutConfigDataToDatabase(name, switchFlag) != RET_OK) {
817 MMI_HILOGE("Failed to set scroll switch flag to mem.");
818 return RET_ERR;
819 }
820 DfxHisysevent::ReportTouchpadSettingState(DfxHisysevent::TOUCHPAD_SETTING_CODE::TOUCHPAD_SCROLL_SETTING,
821 switchFlag);
822
823 return RET_OK;
824 }
825
GetTouchpadScrollSwitch(bool & switchFlag)826 int32_t MouseTransformProcessor::GetTouchpadScrollSwitch(bool &switchFlag)
827 {
828 std::string name = "scrollSwitch";
829 if (GetConfigDataFromDatabase(name, switchFlag) != RET_OK) {
830 MMI_HILOGE("Failed to get scroll switch flag from mem.");
831 return RET_ERR;
832 }
833
834 return RET_OK;
835 }
836
SetTouchpadScrollDirection(bool state)837 int32_t MouseTransformProcessor::SetTouchpadScrollDirection(bool state)
838 {
839 std::string name = "scrollDirection";
840 if (PutConfigDataToDatabase(name, state) != RET_OK) {
841 MMI_HILOGE("Failed to set scroll direct switch flag to mem.");
842 return RET_ERR;
843 }
844
845 DfxHisysevent::ReportTouchpadSettingState(DfxHisysevent::TOUCHPAD_SETTING_CODE::TOUCHPAD_SCROLL_DIR_SETTING,
846 state);
847
848 return RET_OK;
849 }
850
GetTouchpadScrollDirection(bool & state)851 int32_t MouseTransformProcessor::GetTouchpadScrollDirection(bool &state)
852 {
853 std::string name = "scrollDirection";
854 if (GetConfigDataFromDatabase(name, state) != RET_OK) {
855 MMI_HILOGE("Failed to get scroll direct switch flag from mem.");
856 return RET_ERR;
857 }
858
859 return RET_OK;
860 }
861
SetTouchpadTapSwitch(bool switchFlag)862 int32_t MouseTransformProcessor::SetTouchpadTapSwitch(bool switchFlag)
863 {
864 std::string name = "touchpadTap";
865 if (PutConfigDataToDatabase(name, switchFlag) != RET_OK) {
866 MMI_HILOGE("Failed to set scroll direct switch flag to mem.");
867 return RET_ERR;
868 }
869
870 DfxHisysevent::ReportTouchpadSettingState(DfxHisysevent::TOUCHPAD_SETTING_CODE::TOUCHPAD_TAP_SETTING,
871 switchFlag);
872
873 return RET_OK;
874 }
875
GetTouchpadTapSwitch(bool & switchFlag)876 int32_t MouseTransformProcessor::GetTouchpadTapSwitch(bool &switchFlag)
877 {
878 std::string name = "touchpadTap";
879 if (GetConfigDataFromDatabase(name, switchFlag) != RET_OK) {
880 MMI_HILOGE("Failed to get scroll direct switch flag from mem.");
881 return RET_ERR;
882 }
883
884 return RET_OK;
885 }
886
SetTouchpadPointerSpeed(int32_t speed)887 int32_t MouseTransformProcessor::SetTouchpadPointerSpeed(int32_t speed)
888 {
889 std::string name = "touchPadPointerSpeed";
890 if (PutConfigDataToDatabase(name, speed) != RET_OK) {
891 MMI_HILOGE("Failed to set touch pad pointer speed to mem.");
892 return RET_ERR;
893 }
894
895 DfxHisysevent::ReportTouchpadSettingState(DfxHisysevent::TOUCHPAD_SETTING_CODE::TOUCHPAD_POINTER_SPEED_SETTING,
896 speed);
897
898 return RET_OK;
899 }
900
GetTouchpadPointerSpeed(int32_t & speed)901 int32_t MouseTransformProcessor::GetTouchpadPointerSpeed(int32_t &speed)
902 {
903 std::string name = "touchPadPointerSpeed";
904 if (GetConfigDataFromDatabase(name, speed) != RET_OK) {
905 MMI_HILOGE("Failed to get touch pad pointer speed from mem.");
906 return RET_ERR;
907 }
908
909 if (speed == 0) {
910 speed = DEFAULT_TOUCHPAD_SPEED;
911 }
912
913 // if speed < MIN_SPEED | speed > MAX_SPEED, touchpad would be out of action
914 if (speed < MIN_SPEED) {
915 speed = MIN_SPEED;
916 }
917
918 if (speed > MAX_SPEED) {
919 speed = MAX_SPEED;
920 }
921
922 return RET_OK;
923 }
924
SetTouchpadRightClickType(int32_t type)925 int32_t MouseTransformProcessor::SetTouchpadRightClickType(int32_t type)
926 {
927 std::string name = "rightMenuSwitch";
928 if (PutConfigDataToDatabase(name, type) != RET_OK) {
929 MMI_HILOGE("Failed to set right click type to mem.");
930 return RET_ERR;
931 }
932 DfxHisysevent::ReportTouchpadSettingState(DfxHisysevent::TOUCHPAD_SETTING_CODE::TOUCHPAD_RIGHT_CLICK_SETTING,
933 type);
934 return RET_OK;
935 }
936
GetTouchpadRightClickType(int32_t & type)937 int32_t MouseTransformProcessor::GetTouchpadRightClickType(int32_t &type)
938 {
939 std::string name = "rightMenuSwitch";
940 if (GetConfigDataFromDatabase(name, type) != RET_OK) {
941 MMI_HILOGE("Failed to get right click type from mem.");
942 type = RIGHT_CLICK_TYPE_MIN;
943 return RET_ERR;
944 }
945
946 if (type < RIGHT_CLICK_TYPE_MIN || type > RIGHT_CLICK_TYPE_MAX) {
947 type = RIGHT_CLICK_TYPE_MIN;
948 }
949
950 return RET_OK;
951 }
952
PutConfigDataToDatabase(std::string & key,bool value)953 int32_t MouseTransformProcessor::PutConfigDataToDatabase(std::string &key, bool value)
954 {
955 return PreferencesMgr->SetBoolValue(key, mouseFileName, value);
956 }
957
GetConfigDataFromDatabase(std::string & key,bool & value)958 int32_t MouseTransformProcessor::GetConfigDataFromDatabase(std::string &key, bool &value)
959 {
960 value = PreferencesMgr->GetBoolValue(key, true);
961 return RET_OK;
962 }
963
PutConfigDataToDatabase(std::string & key,int32_t value)964 int32_t MouseTransformProcessor::PutConfigDataToDatabase(std::string &key, int32_t value)
965 {
966 return PreferencesMgr->SetIntValue(key, mouseFileName, value);
967 }
968
GetConfigDataFromDatabase(std::string & key,int32_t & value)969 int32_t MouseTransformProcessor::GetConfigDataFromDatabase(std::string &key, int32_t &value)
970 {
971 int32_t defaultValue = value;
972 value = PreferencesMgr->GetIntValue(key, defaultValue);
973 return RET_OK;
974 }
975 } // namespace MMI
976 } // namespace OHOS
977