• 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 "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