• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-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 "input_windows_manager.h"
17 
18 #include <cstdlib>
19 #include <cstdio>
20 
21 #include "dfx_hisysevent.h"
22 #include "i_pointer_drawing_manager.h"
23 #include "input_device_manager.h"
24 #include "mouse_event_normalize.h"
25 #include "pointer_drawing_manager.h"
26 #include "util_ex.h"
27 #include "util_napi_error.h"
28 #include "util.h"
29 
30 namespace OHOS {
31 namespace MMI {
32 namespace {
33 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, MMI_LOG_DOMAIN, "InputWindowsManager"};
34 #ifdef OHOS_BUILD_ENABLE_POINTER
35 constexpr int32_t DEFAULT_POINTER_STYLE = 0;
36 constexpr size_t MAX_WINDOW_COUNT = 20;
37 #endif // OHOS_BUILD_ENABLE_POINTER
38 } // namespace
39 
InputWindowsManager()40 InputWindowsManager::InputWindowsManager() {}
~InputWindowsManager()41 InputWindowsManager::~InputWindowsManager() {}
42 
Init(UDSServer & udsServer)43 void InputWindowsManager::Init(UDSServer& udsServer)
44 {
45     udsServer_ = &udsServer;
46     CHKPV(udsServer_);
47 #ifdef OHOS_BUILD_ENABLE_POINTER
48     udsServer_->AddSessionDeletedCallback(std::bind(&InputWindowsManager::OnSessionLost, this, std::placeholders::_1));
49     InitMouseDownInfo();
50 #endif // OHOS_BUILD_ENABLE_POINTER
51 }
52 
53 #ifdef OHOS_BUILD_ENABLE_POINTER
InitMouseDownInfo()54 void InputWindowsManager::InitMouseDownInfo()
55 {
56     mouseDownInfo_.id = -1;
57     mouseDownInfo_.pid = -1;
58     mouseDownInfo_.defaultHotAreas.clear();
59     mouseDownInfo_.pointerHotAreas.clear();
60 }
61 #endif // OHOS_BUILD_ENABLE_POINTER
62 
GetClientFd(std::shared_ptr<PointerEvent> pointerEvent)63 int32_t InputWindowsManager::GetClientFd(std::shared_ptr<PointerEvent> pointerEvent)
64 {
65     CALL_DEBUG_ENTER;
66     CHKPR(pointerEvent, INVALID_FD);
67     const WindowInfo* windowInfo = nullptr;
68     for (const auto &item : displayGroupInfo_.windowsInfo) {
69         if (item.id == pointerEvent->GetTargetWindowId()) {
70             windowInfo = &item;
71             break;
72         }
73     }
74     CHKPR(udsServer_, INVALID_FD);
75     if (windowInfo != nullptr) {
76         return udsServer_->GetClientFd(windowInfo->pid);
77     }
78     if (pointerEvent->GetPointerAction() != PointerEvent::POINTER_ACTION_CANCEL) {
79         return udsServer_->GetClientFd(-1);
80     }
81     int32_t pid = -1;
82     if (pointerEvent->GetSourceType() == PointerEvent::SOURCE_TYPE_TOUCHSCREEN) {
83         auto iter = touchItemDownInfos_.find(pointerEvent->GetPointerId());
84         if (iter != touchItemDownInfos_.end()) {
85             pid = iter->second.pid;
86             touchItemDownInfos_.erase(iter);
87         }
88     }
89     if (pointerEvent->GetSourceType() == PointerEvent::SOURCE_TYPE_MOUSE) {
90         if (mouseDownInfo_.pid != -1) {
91             pid = mouseDownInfo_.pid;
92             InitMouseDownInfo();
93         }
94     }
95 
96     return udsServer_->GetClientFd(pid);
97 }
98 
99 #ifdef OHOS_BUILD_ENABLE_KEYBOARD
UpdateTarget(std::shared_ptr<InputEvent> inputEvent)100 int32_t InputWindowsManager::UpdateTarget(std::shared_ptr<InputEvent> inputEvent)
101 {
102     CHKPR(inputEvent, INVALID_FD);
103     CALL_DEBUG_ENTER;
104     int32_t pid = GetPidAndUpdateTarget(inputEvent);
105     if (pid <= 0) {
106         MMI_HILOGE("Invalid pid");
107         return INVALID_FD;
108     }
109     int32_t fd = udsServer_->GetClientFd(pid);
110     if (fd < 0) {
111         MMI_HILOGE("Invalid fd");
112         return INVALID_FD;
113     }
114     return fd;
115 }
116 #endif // OHOS_BUILD_ENABLE_KEYBOARD
117 
GetDisplayId(std::shared_ptr<InputEvent> inputEvent) const118 int32_t InputWindowsManager::GetDisplayId(std::shared_ptr<InputEvent> inputEvent) const
119 {
120     int32_t displayId = inputEvent->GetTargetDisplayId();
121     if (displayId < 0) {
122         MMI_HILOGD("Target display is -1");
123         if (displayGroupInfo_.displaysInfo.empty()) {
124             return displayId;
125         }
126         displayId = displayGroupInfo_.displaysInfo[0].id;
127         inputEvent->SetTargetDisplayId(displayId);
128     }
129     return displayId;
130 }
131 
132 #ifdef OHOS_BUILD_ENABLE_KEYBOARD
GetPidAndUpdateTarget(std::shared_ptr<InputEvent> inputEvent)133 int32_t InputWindowsManager::GetPidAndUpdateTarget(std::shared_ptr<InputEvent> inputEvent)
134 {
135     CALL_DEBUG_ENTER;
136     CHKPR(inputEvent, INVALID_PID);
137     const int32_t focusWindowId = displayGroupInfo_.focusWindowId;
138     WindowInfo* windowInfo = nullptr;
139     for (auto &item : displayGroupInfo_.windowsInfo) {
140         if (item.id == focusWindowId) {
141             windowInfo = &item;
142             break;
143         }
144     }
145     CHKPR(windowInfo, INVALID_PID);
146     inputEvent->SetTargetWindowId(windowInfo->id);
147     inputEvent->SetAgentWindowId(windowInfo->agentWindowId);
148     MMI_HILOGD("focusWindowId:%{public}d, pid:%{public}d", focusWindowId, windowInfo->pid);
149     return windowInfo->pid;
150 }
151 #endif // OHOS_BUILD_ENABLE_KEYBOARD
152 
GetWindowPid(int32_t windowId) const153 int32_t InputWindowsManager::GetWindowPid(int32_t windowId) const
154 {
155     int32_t windowPid = -1;
156     for (const auto &item : displayGroupInfo_.windowsInfo) {
157         if (item.id == windowId) {
158             windowPid = item.pid;
159             break;
160         }
161     }
162     return windowPid;
163 }
164 
GetWindowPid(int32_t windowId,const DisplayGroupInfo & displayGroupInfo) const165 int32_t InputWindowsManager::GetWindowPid(int32_t windowId, const DisplayGroupInfo& displayGroupInfo) const
166 {
167     int32_t windowPid = -1;
168     for (const auto &item : displayGroupInfo.windowsInfo) {
169         if (item.id == windowId) {
170             windowPid = item.pid;
171             break;
172         }
173     }
174     return windowPid;
175 }
176 
CheckFocusWindowChange(const DisplayGroupInfo & displayGroupInfo)177 void InputWindowsManager::CheckFocusWindowChange(const DisplayGroupInfo &displayGroupInfo)
178 {
179     const int32_t oldFocusWindowId = displayGroupInfo_.focusWindowId;
180     const int32_t newFocusWindowId = displayGroupInfo.focusWindowId;
181     if (oldFocusWindowId == newFocusWindowId) {
182         return;
183     }
184     const int32_t oldFocusWindowPid = GetWindowPid(oldFocusWindowId);
185     const int32_t newFocusWindowPid = GetWindowPid(newFocusWindowId, displayGroupInfo);
186     DfxHisysevent::OnFocusWindowChanged(oldFocusWindowId, newFocusWindowId, oldFocusWindowPid, newFocusWindowPid);
187 }
188 
CheckZorderWindowChange(const DisplayGroupInfo & displayGroupInfo)189 void InputWindowsManager::CheckZorderWindowChange(const DisplayGroupInfo &displayGroupInfo)
190 {
191     int32_t oldZorderFirstWindowId = -1;
192     int32_t newZorderFirstWindowId = -1;
193     if (!displayGroupInfo_.windowsInfo.empty()) {
194         oldZorderFirstWindowId = displayGroupInfo_.windowsInfo[0].id;
195     }
196     if (!displayGroupInfo.windowsInfo.empty()) {
197         newZorderFirstWindowId = displayGroupInfo.windowsInfo[0].id;
198     }
199     if (oldZorderFirstWindowId == newZorderFirstWindowId) {
200         return;
201     }
202     const int32_t oldZorderFirstWindowPid = GetWindowPid(oldZorderFirstWindowId);
203     const int32_t newZorderFirstWindowPid = GetWindowPid(newZorderFirstWindowId, displayGroupInfo);
204     DfxHisysevent::OnZorderWindowChanged(oldZorderFirstWindowId, newZorderFirstWindowId,
205         oldZorderFirstWindowPid, newZorderFirstWindowPid);
206 }
207 
UpdateDisplayInfo(const DisplayGroupInfo & displayGroupInfo)208 void InputWindowsManager::UpdateDisplayInfo(const DisplayGroupInfo &displayGroupInfo)
209 {
210     CALL_DEBUG_ENTER;
211     CheckFocusWindowChange(displayGroupInfo);
212     CheckZorderWindowChange(displayGroupInfo);
213     displayGroupInfo_ = displayGroupInfo;
214     PrintDisplayInfo();
215 #ifdef OHOS_BUILD_ENABLE_POINTER
216     UpdatePointerStyle();
217 #endif // OHOS_BUILD_ENABLE_POINTER
218 
219     if (!displayGroupInfo.displaysInfo.empty()) {
220 #if defined(OHOS_BUILD_ENABLE_POINTER) && defined(OHOS_BUILD_ENABLE_POINTER_DRAWING)
221         IPointerDrawingManager::GetInstance()->OnDisplayInfo(displayGroupInfo);
222         if (InputDevMgr->HasPointerDevice()) {
223             MouseLocation mouseLocation = GetMouseInfo();
224             int32_t displayId = MouseEventHdr->GetDisplayId();
225             if (displayId < 0) {
226                 displayId = displayGroupInfo_.displaysInfo[0].id;
227             }
228             auto displayInfo = GetPhysicalDisplay(displayId);
229             CHKPV(displayInfo);
230             int32_t logicX = mouseLocation.physicalX + displayInfo->x;
231             int32_t logicY = mouseLocation.physicalY + displayInfo->y;
232             std::optional<WindowInfo> windowInfo;
233             CHKPV(lastPointerEvent_);
234             if (lastPointerEvent_->GetPointerAction() == PointerEvent::POINTER_ACTION_MOVE &&
235                 lastPointerEvent_->GetPressedButtons().empty()) {
236                 windowInfo = GetWindowInfo(logicX, logicY);
237             } else {
238                 windowInfo = SelectWindowInfo(logicX, logicY, lastPointerEvent_);
239             }
240             if (!windowInfo) {
241                 MMI_HILOGE("The windowInfo is nullptr");
242                 return;
243             }
244             int32_t windowPid = GetWindowPid(windowInfo->id);
245             WinInfo info = { .windowPid = windowPid, .windowId = windowInfo->id };
246             IPointerDrawingManager::GetInstance()->OnWindowInfo(info);
247             IPointerDrawingManager::GetInstance()->DrawPointerStyle();
248         }
249 #endif // OHOS_BUILD_ENABLE_POINTER && OHOS_BUILD_ENABLE_POINTER_DRAWING
250     }
251 #ifdef OHOS_BUILD_ENABLE_POINTER_DRAWING
252     if (InputDevMgr->HasPointerDevice()) {
253 #ifdef OHOS_BUILD_ENABLE_POINTER
254         NotifyPointerToWindow();
255 #endif // OHOS_BUILD_ENABLE_POINTER
256     }
257 #endif // OHOS_BUILD_ENABLE_POINTER_DRAWING
258 }
259 
260 #ifdef OHOS_BUILD_ENABLE_POINTER
SendPointerEvent(int32_t pointerAction)261 void InputWindowsManager::SendPointerEvent(int32_t pointerAction)
262 {
263     CALL_INFO_TRACE;
264     CHKPV(udsServer_);
265     auto pointerEvent = PointerEvent::Create();
266     CHKPV(pointerEvent);
267     pointerEvent->UpdateId();
268     MouseLocation mouseLocation = GetMouseInfo();
269     lastLogicX_ = mouseLocation.physicalX;
270     lastLogicY_ = mouseLocation.physicalY;
271     if (pointerAction == PointerEvent::POINTER_ACTION_ENTER_WINDOW) {
272         auto touchWindow = GetWindowInfo(lastLogicX_, lastLogicY_);
273         if (!touchWindow) {
274             MMI_HILOGE("TouchWindow is nullptr");
275             return;
276         }
277         lastWindowInfo_ = *touchWindow;
278     }
279     PointerEvent::PointerItem pointerItem;
280     pointerItem.SetWindowX(lastLogicX_ - lastWindowInfo_.area.x);
281     pointerItem.SetWindowY(lastLogicY_ - lastWindowInfo_.area.y);
282     pointerItem.SetDisplayX(lastLogicX_);
283     pointerItem.SetDisplayY(lastLogicY_);
284     pointerItem.SetPointerId(0);
285 
286     pointerEvent->SetTargetDisplayId(-1);
287     auto displayId = pointerEvent->GetTargetDisplayId();
288     if (!UpdateDisplayId(displayId)) {
289         MMI_HILOGE("This display:%{public}d is not existent", displayId);
290         return;
291     }
292     pointerEvent->SetTargetDisplayId(displayId);
293     pointerEvent->SetTargetWindowId(lastWindowInfo_.id);
294     pointerEvent->SetAgentWindowId(lastWindowInfo_.agentWindowId);
295     pointerEvent->SetPointerId(0);
296     pointerEvent->AddPointerItem(pointerItem);
297     pointerEvent->SetPointerAction(pointerAction);
298     pointerEvent->SetSourceType(PointerEvent::SOURCE_TYPE_MOUSE);
299     int64_t time = GetSysClockTime();
300     pointerEvent->SetActionTime(time);
301     pointerEvent->SetActionStartTime(time);
302     pointerEvent->UpdateId();
303 
304     auto fd = udsServer_->GetClientFd(lastWindowInfo_.pid);
305     auto sess = udsServer_->GetSession(fd);
306     CHKPV(sess);
307 
308     NetPacket pkt(MmiMessageId::ON_POINTER_EVENT);
309     InputEventDataTransformation::Marshalling(pointerEvent, pkt);
310     if (!sess->SendMsg(pkt)) {
311         MMI_HILOGE("Send message failed, errCode:%{public}d", MSG_SEND_FAIL);
312         return;
313     }
314 }
315 
DispatchPointer(int32_t pointerAction)316 void InputWindowsManager::DispatchPointer(int32_t pointerAction)
317 {
318     CALL_INFO_TRACE;
319     CHKPV(udsServer_);
320     if (!IPointerDrawingManager::GetInstance()->GetMouseDisplayState()) {
321         MMI_HILOGD("The mouse is hide");
322         return;
323     }
324     if (lastPointerEvent_ == nullptr) {
325         SendPointerEvent(pointerAction);
326         return;
327     }
328     auto pointerEvent = PointerEvent::Create();
329     CHKPV(pointerEvent);
330     pointerEvent->UpdateId();
331 
332     PointerEvent::PointerItem lastPointerItem;
333     int32_t lastPointerId = lastPointerEvent_->GetPointerId();
334     if (!lastPointerEvent_->GetPointerItem(lastPointerId, lastPointerItem)) {
335         MMI_HILOGE("GetPointerItem:%{public}d fail", lastPointerId);
336         return;
337     }
338     if (pointerAction == PointerEvent::POINTER_ACTION_ENTER_WINDOW) {
339         std::optional<WindowInfo> windowInfo;
340         if (lastPointerEvent_->GetPointerAction() == PointerEvent::POINTER_ACTION_MOVE &&
341             lastPointerEvent_->GetPressedButtons().empty()) {
342             windowInfo = GetWindowInfo(lastLogicX_, lastLogicY_);
343         } else {
344             windowInfo = SelectWindowInfo(lastLogicX_, lastLogicY_, lastPointerEvent_);
345         }
346         if (!windowInfo) {
347             MMI_HILOGE("windowInfo is nullptr");
348             return;
349         }
350         if (windowInfo->id != lastWindowInfo_.id) {
351             lastWindowInfo_ = *windowInfo;
352         }
353     }
354     PointerEvent::PointerItem currentPointerItem;
355     currentPointerItem.SetWindowX(lastLogicX_ - lastWindowInfo_.area.x);
356     currentPointerItem.SetWindowY(lastLogicY_ - lastWindowInfo_.area.y);
357     currentPointerItem.SetDisplayX(lastPointerItem.GetDisplayX());
358     currentPointerItem.SetDisplayY(lastPointerItem.GetDisplayY());
359     currentPointerItem.SetPointerId(0);
360 
361     pointerEvent->SetTargetDisplayId(lastPointerEvent_->GetTargetDisplayId());
362     pointerEvent->SetTargetWindowId(lastWindowInfo_.id);
363     pointerEvent->SetAgentWindowId(lastWindowInfo_.agentWindowId);
364     pointerEvent->SetPointerId(0);
365     pointerEvent->AddPointerItem(currentPointerItem);
366     pointerEvent->SetPointerAction(pointerAction);
367     pointerEvent->SetSourceType(lastPointerEvent_->GetSourceType());
368     int64_t time = GetSysClockTime();
369     pointerEvent->SetActionTime(time);
370     pointerEvent->SetActionStartTime(time);
371     pointerEvent->SetDeviceId(lastPointerEvent_->GetDeviceId());
372 
373     auto fd = udsServer_->GetClientFd(lastWindowInfo_.pid);
374     if (fd == RET_ERR) {
375         auto windowInfo = GetWindowInfo(lastLogicX_, lastLogicY_);
376         if (!windowInfo) {
377             MMI_HILOGE("The windowInfo is nullptr");
378             return;
379         }
380         fd = udsServer_->GetClientFd(windowInfo->pid);
381     }
382     auto sess = udsServer_->GetSession(fd);
383     if (sess == nullptr) {
384         MMI_HILOGI("The last window has disappeared");
385         return;
386     }
387 
388     NetPacket pkt(MmiMessageId::ON_POINTER_EVENT);
389     InputEventDataTransformation::Marshalling(pointerEvent, pkt);
390     if (!sess->SendMsg(pkt)) {
391         MMI_HILOGE("Send message failed, errCode:%{public}d", MSG_SEND_FAIL);
392         return;
393     }
394 }
395 
NotifyPointerToWindow()396 void InputWindowsManager::NotifyPointerToWindow()
397 {
398     CALL_INFO_TRACE;
399     std::optional<WindowInfo> windowInfo;
400     CHKPV(lastPointerEvent_);
401     if (lastPointerEvent_->GetPointerAction() == PointerEvent::POINTER_ACTION_MOVE &&
402         lastPointerEvent_->GetPressedButtons().empty()) {
403         windowInfo = GetWindowInfo(lastLogicX_, lastLogicY_);
404     } else {
405         windowInfo = SelectWindowInfo(lastLogicX_, lastLogicY_, lastPointerEvent_);
406     }
407     if (!windowInfo) {
408         MMI_HILOGE("The windowInfo is nullptr");
409         return;
410     }
411     if (windowInfo->id == lastWindowInfo_.id) {
412         MMI_HILOGI("The mouse pointer does not leave the window:%{public}d", lastWindowInfo_.id);
413         lastWindowInfo_ = *windowInfo;
414         return;
415     }
416     bool isFindLastWindow = false;
417     for (const auto &item : displayGroupInfo_.windowsInfo) {
418         if (item.id == lastWindowInfo_.id) {
419             DispatchPointer(PointerEvent::POINTER_ACTION_LEAVE_WINDOW);
420             isFindLastWindow = true;
421             break;
422         }
423     }
424     if (!isFindLastWindow) {
425         if (udsServer_ != nullptr && udsServer_->GetClientFd(lastWindowInfo_.pid) != INVALID_FD) {
426             DispatchPointer(PointerEvent::POINTER_ACTION_LEAVE_WINDOW);
427         }
428     }
429     lastWindowInfo_ = *windowInfo;
430     DispatchPointer(PointerEvent::POINTER_ACTION_ENTER_WINDOW);
431 }
432 #endif // OHOS_BUILD_ENABLE_POINTER
433 
PrintDisplayInfo()434 void InputWindowsManager::PrintDisplayInfo()
435 {
436     MMI_HILOGI("logicalInfo,width:%{public}d,height:%{public}d,focusWindowId:%{public}d",
437         displayGroupInfo_.width, displayGroupInfo_.height, displayGroupInfo_.focusWindowId);
438     MMI_HILOGI("windowsInfos,num:%{public}zu", displayGroupInfo_.windowsInfo.size());
439     for (const auto &item : displayGroupInfo_.windowsInfo) {
440         MMI_HILOGI("windowsInfos,id:%{public}d,pid:%{public}d,uid:%{public}d,"
441             "area.x:%{public}d,area.y:%{public}d,area.width:%{public}d,area.height:%{public}d,"
442             "defaultHotAreas.size:%{public}zu,pointerHotAreas.size:%{public}zu,"
443             "agentWindowId:%{public}d,flags:%{public}d",
444             item.id, item.pid, item.uid, item.area.x, item.area.y, item.area.width,
445             item.area.height, item.defaultHotAreas.size(), item.pointerHotAreas.size(),
446             item.agentWindowId, item.flags);
447         for (const auto &win : item.defaultHotAreas) {
448             MMI_HILOGI("defaultHotAreas:x:%{public}d,y:%{public}d,width:%{public}d,height:%{public}d",
449                 win.x, win.y, win.width, win.height);
450         }
451         for (const auto &pointer : item.pointerHotAreas) {
452             MMI_HILOGI("pointerHotAreas:x:%{public}d,y:%{public}d,width:%{public}d,height:%{public}d",
453                 pointer.x, pointer.y, pointer.width, pointer.height);
454         }
455     }
456 
457     MMI_HILOGI("displayInfos,num:%{public}zu", displayGroupInfo_.displaysInfo.size());
458     for (const auto &item : displayGroupInfo_.displaysInfo) {
459         MMI_HILOGI("displayInfos,id:%{public}d,x:%{public}d,y:%{public}d,"
460             "width:%{public}d,height:%{public}d,name:%{public}s,"
461             "uniq:%{public}s,direction:%{public}d",
462             item.id, item.x, item.y, item.width, item.height, item.name.c_str(),
463             item.uniq.c_str(), item.direction);
464     }
465 }
466 
467 #if defined(OHOS_BUILD_ENABLE_POINTER) || defined(OHOS_BUILD_ENABLE_TOUCH)
GetPhysicalDisplay(int32_t id) const468 const DisplayInfo* InputWindowsManager::GetPhysicalDisplay(int32_t id) const
469 {
470     for (auto &it : displayGroupInfo_.displaysInfo) {
471         if (it.id == id) {
472             return &it;
473         }
474     }
475     MMI_HILOGW("Failed to obtain physical(%{public}d) display", id);
476     return nullptr;
477 }
478 #endif // OHOS_BUILD_ENABLE_POINTER || OHOS_BUILD_ENABLE_TOUCH
479 
480 #ifdef OHOS_BUILD_ENABLE_TOUCH
FindPhysicalDisplayInfo(const std::string & uniq) const481 const DisplayInfo* InputWindowsManager::FindPhysicalDisplayInfo(const std::string& uniq) const
482 {
483     for (auto &it : displayGroupInfo_.displaysInfo) {
484         if (it.uniq == uniq) {
485             return &it;
486         }
487     }
488     MMI_HILOGE("Failed to search for Physical,uniq:%{public}s", uniq.c_str());
489     return nullptr;
490 }
491 
RotateTouchScreen(DisplayInfo info,LogicalCoordinate & coord) const492 void InputWindowsManager::RotateTouchScreen(DisplayInfo info, LogicalCoordinate& coord) const
493 {
494     const Direction direction = info.direction;
495 
496     if (direction == Direction0) {
497         MMI_HILOGD("direction is Direction0");
498         return;
499     }
500     if (direction == Direction90) {
501         MMI_HILOGD("direction is Direction90");
502         int32_t temp = coord.x;
503         coord.x = info.height - coord.y;
504         coord.y = temp;
505         MMI_HILOGD("physicalX:%{public}d, physicalY:%{public}d", coord.x, coord.y);
506         return;
507     }
508     if (direction == Direction180) {
509         MMI_HILOGD("direction is Direction180");
510         coord.x = info.width - coord.x;
511         coord.y = info.height - coord.y;
512         MMI_HILOGD("physicalX:%{public}d, physicalY:%{public}d", coord.x, coord.y);
513         return;
514     }
515     if (direction == Direction270) {
516         MMI_HILOGD("direction is Direction270");
517         int32_t temp = coord.y;
518         coord.y = info.width - coord.x;
519         coord.x = temp;
520         MMI_HILOGD("physicalX:%{public}d, physicalY:%{public}d", coord.x, coord.y);
521     }
522 }
523 
GetPhysicalDisplayCoord(struct libinput_event_touch * touch,const DisplayInfo & info,EventTouch & touchInfo)524 void InputWindowsManager::GetPhysicalDisplayCoord(struct libinput_event_touch* touch,
525     const DisplayInfo& info, EventTouch& touchInfo)
526 {
527     LogicalCoordinate coord {
528         .x = static_cast<int32_t>(libinput_event_touch_get_x_transformed(touch, info.width)),
529         .y = static_cast<int32_t>(libinput_event_touch_get_y_transformed(touch, info.height)),
530     };
531     RotateTouchScreen(info, coord);
532     touchInfo.point.x = coord.x;
533     touchInfo.point.y = coord.y;
534     touchInfo.toolRect.point.x = static_cast<int32_t>(libinput_event_touch_get_tool_x_transformed(touch, info.width));
535     touchInfo.toolRect.point.y = static_cast<int32_t>(libinput_event_touch_get_tool_y_transformed(touch, info.height));
536     touchInfo.toolRect.width = static_cast<int32_t>(
537         libinput_event_touch_get_tool_width_transformed(touch, info.width));
538     touchInfo.toolRect.height = static_cast<int32_t>(
539         libinput_event_touch_get_tool_height_transformed(touch, info.height));
540 }
541 
TouchPointToDisplayPoint(int32_t deviceId,struct libinput_event_touch * touch,EventTouch & touchInfo,int32_t & physicalDisplayId)542 bool InputWindowsManager::TouchPointToDisplayPoint(int32_t deviceId, struct libinput_event_touch* touch,
543     EventTouch& touchInfo, int32_t& physicalDisplayId)
544 {
545     CHKPF(touch);
546     std::string screenId = InputDevMgr->GetScreenId(deviceId);
547     if (screenId.empty()) {
548         screenId = "default0";
549     }
550     auto info = FindPhysicalDisplayInfo(screenId);
551     CHKPF(info);
552     physicalDisplayId = info->id;
553     if ((info->width <= 0) || (info->height <= 0)) {
554         MMI_HILOGE("Get DisplayInfo is error");
555         return false;
556     }
557     GetPhysicalDisplayCoord(touch, *info, touchInfo);
558     return true;
559 }
560 
TransformTipPoint(struct libinput_event_tablet_tool * tip,LogicalCoordinate & coord,int32_t & displayId) const561 bool InputWindowsManager::TransformTipPoint(struct libinput_event_tablet_tool* tip,
562     LogicalCoordinate& coord, int32_t& displayId) const
563 {
564     CHKPF(tip);
565     auto displayInfo = FindPhysicalDisplayInfo("default0");
566     CHKPF(displayInfo);
567     MMI_HILOGD("PhysicalDisplay.width:%{public}d, PhysicalDisplay.height:%{public}d, "
568                "PhysicalDisplay.topLeftX:%{public}d, PhysicalDisplay.topLeftY:%{public}d",
569                displayInfo->width, displayInfo->height, displayInfo->x, displayInfo->y);
570     displayId = displayInfo->id;
571     PhysicalCoordinate phys {
572         .x = libinput_event_tablet_tool_get_x_transformed(tip, displayInfo->width),
573         .y = libinput_event_tablet_tool_get_y_transformed(tip, displayInfo->height)
574     };
575 
576     coord.x = static_cast<int32_t>(phys.x);
577     coord.y = static_cast<int32_t>(phys.y);
578     MMI_HILOGD("physicalX:%{public}f, physicalY:%{public}f, displayId:%{public}d", phys.x, phys.y, displayId);
579     return true;
580 }
581 
CalculateTipPoint(struct libinput_event_tablet_tool * tip,int32_t & targetDisplayId,LogicalCoordinate & coord) const582 bool InputWindowsManager::CalculateTipPoint(struct libinput_event_tablet_tool* tip,
583     int32_t& targetDisplayId, LogicalCoordinate& coord) const
584 {
585     CHKPF(tip);
586     if (!TransformTipPoint(tip, coord, targetDisplayId)) {
587         return false;
588     }
589     return true;
590 }
591 #endif // OHOS_BUILD_ENABLE_TOUCH
592 
593 #ifdef OHOS_BUILD_ENABLE_POINTER
GetDisplayGroupInfo()594 const DisplayGroupInfo& InputWindowsManager::GetDisplayGroupInfo()
595 {
596     return displayGroupInfo_;
597 }
598 
599 #ifdef OHOS_BUILD_ENABLE_POINTER_DRAWING
IsNeedRefreshLayer(int32_t windowId)600 bool InputWindowsManager::IsNeedRefreshLayer(int32_t windowId)
601 {
602     CALL_DEBUG_ENTER;
603     MouseLocation mouseLocation = GetMouseInfo();
604     int32_t displayId = MouseEventHdr->GetDisplayId();
605     if (displayId < 0) {
606         displayId = displayGroupInfo_.displaysInfo[0].id;
607     }
608     auto displayInfo = GetPhysicalDisplay(displayId);
609     CHKPR(displayInfo, false);
610     int32_t logicX = mouseLocation.physicalX + displayInfo->x;
611     int32_t logicY = mouseLocation.physicalY + displayInfo->y;
612     std::optional<WindowInfo> touchWindow = GetWindowInfo(logicX, logicY);
613     if (!touchWindow) {
614         MMI_HILOGE("TouchWindow is nullptr");
615         return false;
616     }
617     if (touchWindow->id == windowId) {
618         MMI_HILOGD("Need refresh pointer style, focusWindow type:%{public}d, window type:%{public}d",
619             touchWindow->id, windowId);
620         return true;
621     }
622 
623     MMI_HILOGD("Not need refresh pointer style, focusWindow type:%{public}d, window type:%{public}d",
624         touchWindow->id, windowId);
625     return false;
626 }
627 #endif
628 
OnSessionLost(SessionPtr session)629 void InputWindowsManager::OnSessionLost(SessionPtr session)
630 {
631     CALL_DEBUG_ENTER;
632     CHKPV(session);
633     int32_t pid = session->GetPid();
634 
635     auto it = pointerStyle_.find(pid);
636     if (it != pointerStyle_.end()) {
637         pointerStyle_.erase(it);
638         MMI_HILOGD("Clear the pointer style map, pd:%{public}d", pid);
639     }
640 }
641 
SetPointerStyle(int32_t pid,int32_t windowId,int32_t pointerStyle)642 int32_t InputWindowsManager::SetPointerStyle(int32_t pid, int32_t windowId, int32_t pointerStyle)
643 {
644     CALL_DEBUG_ENTER;
645     auto it = pointerStyle_.find(pid);
646     if (it == pointerStyle_.end()) {
647         MMI_HILOGE("The pointer style map is not include param pd:%{public}d", pid);
648         return COMMON_PARAMETER_ERROR ;
649     }
650 
651     auto iter = it->second.find(windowId);
652     if (iter == it->second.end()) {
653         MMI_HILOGE("The window id is invalid");
654         return COMMON_PARAMETER_ERROR ;
655     }
656 
657     iter->second = pointerStyle;
658     MMI_HILOGD("Window id:%{public}d set pointer style:%{public}d success", windowId, pointerStyle);
659     return RET_OK;
660 }
661 
GetPointerStyle(int32_t pid,int32_t windowId,int32_t & pointerStyle) const662 int32_t InputWindowsManager::GetPointerStyle(int32_t pid, int32_t windowId, int32_t &pointerStyle) const
663 {
664     CALL_DEBUG_ENTER;
665     auto it = pointerStyle_.find(pid);
666     if (it == pointerStyle_.end()) {
667         MMI_HILOGE("The pointer style map is not include param pd, %{public}d", pid);
668         return RET_ERR;
669     }
670 
671     auto iter = it->second.find(windowId);
672     if (iter == it->second.end()) {
673         MMI_HILOGW("The window id is invalid");
674         pointerStyle = DEFAULT_POINTER_STYLE;
675         return RET_OK;
676     }
677 
678     MMI_HILOGD("Window type:%{public}d get pointer style:%{public}d success", windowId, iter->second);
679     pointerStyle = iter->second;
680     return RET_OK;
681 }
682 
UpdatePointerStyle()683 void InputWindowsManager::UpdatePointerStyle()
684 {
685     CALL_DEBUG_ENTER;
686     for (const auto& windowItem : displayGroupInfo_.windowsInfo) {
687         int32_t pid = windowItem.pid;
688         auto it = pointerStyle_.find(pid);
689         if (it == pointerStyle_.end()) {
690             std::map<int32_t, int32_t> tmpPointerStyle = {{windowItem.id, DEFAULT_POINTER_STYLE}};
691             auto iter = pointerStyle_.insert(std::make_pair(pid, tmpPointerStyle));
692             if (!iter.second) {
693                 MMI_HILOGW("The pd is duplicated");
694             }
695             continue;
696         }
697 
698         auto subIter = it->second.find(windowItem.id);
699         if (subIter == it->second.end()) {
700             if (it->second.size() == MAX_WINDOW_COUNT) {
701                 MMI_HILOGD("The window count:%{public}zu exceeds limit in same pd", it->second.size());
702                 it->second.erase(it->second.begin());
703             }
704             auto iter = it->second.insert(std::make_pair(windowItem.id, DEFAULT_POINTER_STYLE));
705             if (!iter.second) {
706                 MMI_HILOGW("The window type is duplicated");
707             }
708         }
709     }
710 
711     MMI_HILOGD("Number of pointer style:%{public}zu", pointerStyle_.size());
712 }
713 
714 #endif // OHOS_BUILD_ENABLE_POINTER
715 
716 #if defined(OHOS_BUILD_ENABLE_POINTER) || defined(OHOS_BUILD_ENABLE_TOUCH)
IsInHotArea(int32_t x,int32_t y,const std::vector<Rect> & rects) const717 bool InputWindowsManager::IsInHotArea(int32_t x, int32_t y, const std::vector<Rect> &rects) const
718 {
719     for (const auto &item : rects) {
720         int32_t displayMaxX = 0;
721         int32_t displayMaxY = 0;
722         if (!AddInt32(item.x, item.width, displayMaxX)) {
723             MMI_HILOGE("The addition of displayMaxX overflows");
724             return false;
725         }
726         if (!AddInt32(item.y, item.height, displayMaxY)) {
727             MMI_HILOGE("The addition of displayMaxY overflows");
728             return false;
729         }
730         if (((x >= item.x) && (x < displayMaxX)) &&
731             (y >= item.y) && (y < displayMaxY)) {
732             return true;
733         }
734     }
735     return false;
736 }
737 #endif // OHOS_BUILD_ENABLE_POINTER || OHOS_BUILD_ENABLE_TOUCH
738 
739 #ifdef OHOS_BUILD_ENABLE_TOUCH
AdjustDisplayCoordinate(const DisplayInfo & displayInfo,int32_t & physicalX,int32_t & physicalY) const740 void InputWindowsManager::AdjustDisplayCoordinate(
741     const DisplayInfo& displayInfo, int32_t& physicalX, int32_t& physicalY) const
742 {
743     int32_t width = 0;
744     int32_t height = 0;
745     if (displayInfo.direction == Direction0 || displayInfo.direction == Direction180) {
746         width = displayInfo.width;
747         height = displayInfo.height;
748     } else {
749         height = displayInfo.width;
750         width = displayInfo.height;
751     }
752     if (physicalX <= 0) {
753         physicalX = 0;
754     }
755     if (physicalX >= width && width > 0) {
756         physicalX = width - 1;
757     }
758     if (physicalY <= 0) {
759         physicalY = 0;
760     }
761     if (physicalY >= height && height > 0) {
762         physicalY = height - 1;
763     }
764 }
765 #endif // OHOS_BUILD_ENABLE_TOUCH
766 
767 #if defined(OHOS_BUILD_ENABLE_POINTER) || defined(OHOS_BUILD_ENABLE_TOUCH)
UpdateDisplayId(int32_t & displayId)768 bool InputWindowsManager::UpdateDisplayId(int32_t& displayId)
769 {
770     if (displayGroupInfo_.displaysInfo.empty()) {
771         MMI_HILOGE("logicalDisplays_is empty");
772         return false;
773     }
774     if (displayId < 0) {
775         displayId = displayGroupInfo_.displaysInfo[0].id;
776         return true;
777     }
778     for (const auto &item : displayGroupInfo_.displaysInfo) {
779         if (item.id == displayId) {
780             return true;
781         }
782     }
783     return false;
784 }
785 #endif // OHOS_BUILD_ENABLE_POINTER || OHOS_BUILD_ENABLE_TOUCH
786 
787 #ifdef OHOS_BUILD_ENABLE_POINTER
SelectWindowInfo(int32_t logicalX,int32_t logicalY,const std::shared_ptr<PointerEvent> & pointerEvent)788 std::optional<WindowInfo> InputWindowsManager::SelectWindowInfo(int32_t logicalX, int32_t logicalY,
789     const std::shared_ptr<PointerEvent>& pointerEvent)
790 {
791     CALL_DEBUG_ENTER;
792     int32_t action = pointerEvent->GetPointerAction();
793     if ((firstBtnDownWindowId_ == -1) ||
794         ((action == PointerEvent::POINTER_ACTION_BUTTON_DOWN) && (pointerEvent->GetPressedButtons().size() == 1)) ||
795         ((action == PointerEvent::POINTER_ACTION_MOVE) && (pointerEvent->GetPressedButtons().empty()))) {
796         int32_t targetWindowId = pointerEvent->GetTargetWindowId();
797         for (const auto &item : displayGroupInfo_.windowsInfo) {
798             if ((item.flags & WindowInfo::FLAG_BIT_UNTOUCHABLE) == WindowInfo::FLAG_BIT_UNTOUCHABLE) {
799                 MMI_HILOGD("Skip the untouchable window to continue searching, "
800                            "window:%{public}d, flags:%{public}d", item.id, item.flags);
801                 continue;
802             } else if ((targetWindowId < 0) && (IsInHotArea(logicalX, logicalY, item.pointerHotAreas))) {
803                 firstBtnDownWindowId_ = item.id;
804                 MMI_HILOGW("Find out the dispatch window of this pointer event when the targetWindowId "
805                            "hasn't been setted up yet, window:%{public}d", firstBtnDownWindowId_);
806                 break;
807             } else if ((targetWindowId >= 0) && (targetWindowId == item.id)) {
808                 firstBtnDownWindowId_ = targetWindowId;
809                 MMI_HILOGW("Find out the dispatch window of this pointer event when the targetWindowId "
810                            "has been setted up already, window:%{public}d", firstBtnDownWindowId_);
811                 break;
812             } else {
813                 MMI_HILOGW("Continue searching for the dispatch window of this pointer event");
814             }
815         }
816     }
817     MMI_HILOGD("firstBtnDownWindowId_:%{public}d", firstBtnDownWindowId_);
818     for (const auto &item : displayGroupInfo_.windowsInfo) {
819         if (item.id == firstBtnDownWindowId_) {
820             return std::make_optional(item);
821         }
822     }
823     return std::nullopt;
824 }
825 
GetWindowInfo(int32_t logicalX,int32_t logicalY)826 std::optional<WindowInfo> InputWindowsManager::GetWindowInfo(int32_t logicalX, int32_t logicalY)
827 {
828     CALL_DEBUG_ENTER;
829     for (const auto& item : displayGroupInfo_.windowsInfo) {
830         if ((item.flags & WindowInfo::FLAG_BIT_UNTOUCHABLE) == WindowInfo::FLAG_BIT_UNTOUCHABLE) {
831             MMI_HILOGD("Skip the untouchable window to continue searching, "
832                        "window:%{public}d, flags:%{public}d", item.id, item.flags);
833             continue;
834         } else if (IsInHotArea(logicalX, logicalY, item.pointerHotAreas)) {
835             return std::make_optional(item);
836         } else {
837             MMI_HILOGW("Continue searching for the dispatch window");
838         }
839     }
840     return std::nullopt;
841 }
842 
UpdatePointerEvent(int32_t logicalX,int32_t logicalY,const std::shared_ptr<PointerEvent> & pointerEvent,const WindowInfo & touchWindow)843 void InputWindowsManager::UpdatePointerEvent(int32_t logicalX, int32_t logicalY,
844     const std::shared_ptr<PointerEvent>& pointerEvent, const WindowInfo& touchWindow)
845 {
846     CHKPV(pointerEvent);
847     MMI_HILOGD("LastWindowInfo:%{public}d, touchWindow:%{public}d", lastWindowInfo_.id, touchWindow.id);
848     if (lastWindowInfo_.id != touchWindow.id) {
849         DispatchPointer(PointerEvent::POINTER_ACTION_LEAVE_WINDOW);
850         lastLogicX_ = logicalX;
851         lastLogicY_ = logicalY;
852         lastPointerEvent_ = pointerEvent;
853         lastWindowInfo_ = touchWindow;
854         DispatchPointer(PointerEvent::POINTER_ACTION_ENTER_WINDOW);
855         return;
856     }
857     lastLogicX_ = logicalX;
858     lastLogicY_ = logicalY;
859     lastPointerEvent_ = pointerEvent;
860     lastWindowInfo_ = touchWindow;
861 }
862 
UpdateMouseTarget(std::shared_ptr<PointerEvent> pointerEvent)863 int32_t InputWindowsManager::UpdateMouseTarget(std::shared_ptr<PointerEvent> pointerEvent)
864 {
865     CALL_DEBUG_ENTER;
866     CHKPR(pointerEvent, ERROR_NULL_POINTER);
867     auto displayId = pointerEvent->GetTargetDisplayId();
868     if (!UpdateDisplayId(displayId)) {
869         MMI_HILOGE("This display:%{public}d is not existent", displayId);
870         return RET_ERR;
871     }
872     pointerEvent->SetTargetDisplayId(displayId);
873 
874     int32_t pointerId = pointerEvent->GetPointerId();
875     PointerEvent::PointerItem pointerItem;
876     if (!pointerEvent->GetPointerItem(pointerId, pointerItem)) {
877         MMI_HILOGE("Can't find pointer item, pointer:%{public}d", pointerId);
878         return RET_ERR;
879     }
880     auto physicalDisplayInfo = GetPhysicalDisplay(displayId);
881     CHKPR(physicalDisplayInfo, ERROR_NULL_POINTER);
882     int32_t logicalX = 0;
883     int32_t logicalY = 0;
884     if (!AddInt32(pointerItem.GetDisplayX(), physicalDisplayInfo->x, logicalX)) {
885         MMI_HILOGE("The addition of logicalX overflows");
886         return RET_ERR;
887     }
888     if (!AddInt32(pointerItem.GetDisplayY(), physicalDisplayInfo->y, logicalY)) {
889         MMI_HILOGE("The addition of logicalY overflows");
890         return RET_ERR;
891     }
892     auto touchWindow = SelectWindowInfo(logicalX, logicalY, pointerEvent);
893     if (!touchWindow) {
894         if (pointerEvent->GetPointerAction() == PointerEvent::POINTER_ACTION_BUTTON_DOWN || mouseDownInfo_.id == -1) {
895             MMI_HILOGE("touchWindow is nullptr, targetWindow:%{public}d", pointerEvent->GetTargetWindowId());
896             return RET_ERR;
897         }
898         touchWindow = std::make_optional(mouseDownInfo_);
899         pointerEvent->SetPointerAction(PointerEvent::POINTER_ACTION_CANCEL);
900         MMI_HILOGD("mouse event send cancel, window:%{public}d", touchWindow->id);
901     }
902     int32_t mouseStyle = -1;
903     int32_t ret = GetPointerStyle(touchWindow->pid, touchWindow->id, mouseStyle);
904     if (ret != RET_OK) {
905         MMI_HILOGE("Get pointer style failed, pointerStyleInfo is nullptr");
906         return ret;
907     }
908     if (!IPointerDrawingManager::GetInstance()->GetMouseDisplayState()) {
909         IPointerDrawingManager::GetInstance()->SetMouseDisplayState(true);
910         DispatchPointer(PointerEvent::POINTER_ACTION_ENTER_WINDOW);
911     }
912     IPointerDrawingManager::GetInstance()->UpdateDisplayInfo(*physicalDisplayInfo);
913     WinInfo info = { .windowPid = touchWindow->pid, .windowId = touchWindow->id };
914     IPointerDrawingManager::GetInstance()->OnWindowInfo(info);
915     IPointerDrawingManager::GetInstance()->DrawPointer(displayId, pointerItem.GetDisplayX(),
916         pointerItem.GetDisplayY(), MOUSE_ICON(mouseStyle));
917 
918     pointerEvent->SetTargetWindowId(touchWindow->id);
919     pointerEvent->SetAgentWindowId(touchWindow->agentWindowId);
920     int32_t windowX = logicalX - touchWindow->area.x;
921     int32_t windowY = logicalY - touchWindow->area.y;
922     pointerItem.SetWindowX(windowX);
923     pointerItem.SetWindowY(windowY);
924     pointerEvent->UpdatePointerItem(pointerId, pointerItem);
925     CHKPR(udsServer_, ERROR_NULL_POINTER);
926 #ifdef OHOS_BUILD_ENABLE_POINTER_DRAWING
927     UpdatePointerEvent(logicalX, logicalY, pointerEvent, *touchWindow);
928 #endif // OHOS_BUILD_ENABLE_POINTER_DRAWING
929     int32_t action = pointerEvent->GetPointerAction();
930     if (action == PointerEvent::POINTER_ACTION_BUTTON_DOWN) {
931         mouseDownInfo_ = *touchWindow;
932     }
933     if (action == PointerEvent::POINTER_ACTION_BUTTON_UP) {
934         InitMouseDownInfo();
935         MMI_HILOGD("Mouse up, clear mouse down info");
936     }
937     MMI_HILOGD("pid:%{public}d,id:%{public}d,agentWindowId:%{public}d,"
938                "logicalX:%{public}d,logicalY:%{public}d,"
939                "displayX:%{public}d,displayY:%{public}d,windowX:%{public}d,windowY:%{public}d",
940                touchWindow->pid, touchWindow->id, touchWindow->agentWindowId,
941                logicalX, logicalY, pointerItem.GetDisplayX(), pointerItem.GetDisplayY(), windowX, windowY);
942     return ERR_OK;
943 }
944 #endif // OHOS_BUILD_ENABLE_POINTER
945 
946 #ifdef OHOS_BUILD_ENABLE_TOUCH
UpdateTouchScreenTarget(std::shared_ptr<PointerEvent> pointerEvent)947 int32_t InputWindowsManager::UpdateTouchScreenTarget(std::shared_ptr<PointerEvent> pointerEvent)
948 {
949     CALL_DEBUG_ENTER;
950     CHKPR(pointerEvent, ERROR_NULL_POINTER);
951     auto displayId = pointerEvent->GetTargetDisplayId();
952     if (!UpdateDisplayId(displayId)) {
953         MMI_HILOGE("This display is not existent");
954         return RET_ERR;
955     }
956     pointerEvent->SetTargetDisplayId(displayId);
957 
958     int32_t pointerId = pointerEvent->GetPointerId();
959     PointerEvent::PointerItem pointerItem;
960     if (!pointerEvent->GetPointerItem(pointerId, pointerItem)) {
961         MMI_HILOGE("Can't find pointer item, pointer:%{public}d", pointerId);
962         return RET_ERR;
963     }
964     MMI_HILOGD("display:%{public}d", displayId);
965     auto physicDisplayInfo = GetPhysicalDisplay(displayId);
966     CHKPR(physicDisplayInfo, ERROR_NULL_POINTER);
967     int32_t physicalX = pointerItem.GetDisplayX();
968     int32_t physicalY = pointerItem.GetDisplayY();
969     AdjustDisplayCoordinate(*physicDisplayInfo, physicalX, physicalY);
970     int32_t logicalX = 0;
971     int32_t logicalY = 0;
972     if (!AddInt32(physicalX, physicDisplayInfo->x, logicalX)) {
973         MMI_HILOGE("The addition of logicalX overflows");
974         return RET_ERR;
975     }
976     if (!AddInt32(physicalY, physicDisplayInfo->y, logicalY)) {
977         MMI_HILOGE("The addition of logicalY overflows");
978         return RET_ERR;
979     }
980     WindowInfo *touchWindow = nullptr;
981     auto targetWindowId = pointerItem.GetTargetWindowId();
982     for (auto &item : displayGroupInfo_.windowsInfo) {
983         if ((item.flags & WindowInfo::FLAG_BIT_UNTOUCHABLE) == WindowInfo::FLAG_BIT_UNTOUCHABLE) {
984             MMI_HILOGD("Skip the untouchable window to continue searching, "
985                        "window:%{public}d, flags:%{public}d", item.id, item.flags);
986             continue;
987         }
988         if (targetWindowId >= 0) {
989             if (item.id == targetWindowId) {
990                 touchWindow = &item;
991                 break;
992             }
993         } else if (IsInHotArea(logicalX, logicalY, item.defaultHotAreas)) {
994             touchWindow = &item;
995             break;
996         }
997     }
998     if (touchWindow == nullptr) {
999         auto it = touchItemDownInfos_.find(pointerId);
1000         if (it == touchItemDownInfos_.end() ||
1001             pointerEvent->GetPointerAction() == PointerEvent::POINTER_ACTION_DOWN) {
1002             MMI_HILOGE("The touchWindow is nullptr, logicalX:%{public}d, logicalY:%{public}d",
1003                 logicalX, logicalY);
1004             return RET_ERR;
1005         }
1006         touchWindow = &it->second;
1007         pointerEvent->SetPointerAction(PointerEvent::POINTER_ACTION_CANCEL);
1008         MMI_HILOGD("touch event send cancel, window:%{public}d", touchWindow->id);
1009     }
1010     auto windowX = logicalX - touchWindow->area.x;
1011     auto windowY = logicalY - touchWindow->area.y;
1012     pointerEvent->SetTargetWindowId(touchWindow->id);
1013     pointerEvent->SetAgentWindowId(touchWindow->agentWindowId);
1014     pointerItem.SetDisplayX(physicalX);
1015     pointerItem.SetDisplayY(physicalY);
1016     pointerItem.SetWindowX(windowX);
1017     pointerItem.SetWindowY(windowY);
1018     pointerItem.SetToolWindowX(pointerItem.GetToolDisplayX() + physicDisplayInfo->x - touchWindow->area.x);
1019     pointerItem.SetToolWindowY(pointerItem.GetToolDisplayY() + physicDisplayInfo->y - touchWindow->area.y);
1020     pointerItem.SetTargetWindowId(touchWindow->id);
1021     pointerEvent->UpdatePointerItem(pointerId, pointerItem);
1022     MMI_HILOGD("pid:%{public}d,logicalX:%{public}d,logicalY:%{public}d,"
1023                "physicalX:%{public}d,physicalY:%{public}d,windowX:%{public}d,windowY:%{public}d,"
1024                "displayId:%{public}d,TargetWindowId:%{public}d,AgentWindowId:%{public}d",
1025                touchWindow->pid, logicalX, logicalY, physicalX, physicalY,
1026                windowX, windowY, displayId, pointerEvent->GetTargetWindowId(), pointerEvent->GetAgentWindowId());
1027 #ifdef OHOS_BUILD_ENABLE_POINTER
1028     if (IPointerDrawingManager::GetInstance()->GetMouseDisplayState()) {
1029         DispatchPointer(PointerEvent::POINTER_ACTION_LEAVE_WINDOW);
1030         IPointerDrawingManager::GetInstance()->SetMouseDisplayState(false);
1031     }
1032 #endif // OHOS_BUILD_ENABLE_POINTER
1033     int32_t pointerAction = pointerEvent->GetPointerAction();
1034     if (pointerAction == PointerEvent::POINTER_ACTION_DOWN) {
1035         touchItemDownInfos_.insert(std::make_pair(pointerId, *touchWindow));
1036     }
1037     if (pointerAction == PointerEvent::POINTER_ACTION_UP) {
1038         auto iter = touchItemDownInfos_.find(pointerId);
1039         if (iter != touchItemDownInfos_.end()) {
1040             touchItemDownInfos_.erase(iter);
1041             MMI_HILOGD("Clear the touch info, action is up, pointerid:%{public}d", pointerId);
1042         }
1043     }
1044     return ERR_OK;
1045 }
1046 #endif // OHOS_BUILD_ENABLE_TOUCH
1047 
1048 #ifdef OHOS_BUILD_ENABLE_POINTER
UpdateTouchPadTarget(std::shared_ptr<PointerEvent> pointerEvent)1049 int32_t InputWindowsManager::UpdateTouchPadTarget(std::shared_ptr<PointerEvent> pointerEvent)
1050 {
1051     CALL_DEBUG_ENTER;
1052     return RET_ERR;
1053 }
1054 #endif // OHOS_BUILD_ENABLE_POINTER
1055 
1056 #ifdef OHOS_BUILD_ENABLE_JOYSTICK
UpdateJoystickTarget(std::shared_ptr<PointerEvent> pointerEvent)1057 int32_t InputWindowsManager::UpdateJoystickTarget(std::shared_ptr<PointerEvent> pointerEvent)
1058 {
1059     CALL_DEBUG_ENTER;
1060     CHKPR(pointerEvent, ERROR_NULL_POINTER);
1061     int32_t focusWindowId = displayGroupInfo_.focusWindowId;
1062     const WindowInfo* windowInfo = nullptr;
1063     for (const auto &item : displayGroupInfo_.windowsInfo) {
1064         if (item.id == focusWindowId) {
1065             windowInfo = &item;
1066             break;
1067         }
1068     }
1069     CHKPR(windowInfo, ERROR_NULL_POINTER);
1070     pointerEvent->SetTargetWindowId(windowInfo->id);
1071     pointerEvent->SetAgentWindowId(windowInfo->agentWindowId);
1072     MMI_HILOGD("focusWindow:%{public}d, pid:%{public}d", focusWindowId, windowInfo->pid);
1073 
1074     return RET_OK;
1075 }
1076 #endif // OHOS_BUILD_ENABLE_JOYSTICK
1077 
1078 #if defined(OHOS_BUILD_ENABLE_POINTER) || defined(OHOS_BUILD_ENABLE_TOUCH)
UpdateTargetPointer(std::shared_ptr<PointerEvent> pointerEvent)1079 int32_t InputWindowsManager::UpdateTargetPointer(std::shared_ptr<PointerEvent> pointerEvent)
1080 {
1081     CALL_DEBUG_ENTER;
1082     CHKPR(pointerEvent, ERROR_NULL_POINTER);
1083     auto source = pointerEvent->GetSourceType();
1084     switch (source) {
1085 #ifdef OHOS_BUILD_ENABLE_TOUCH
1086         case PointerEvent::SOURCE_TYPE_TOUCHSCREEN: {
1087             return UpdateTouchScreenTarget(pointerEvent);
1088         }
1089 #endif // OHOS_BUILD_ENABLE_TOUCH
1090 #ifdef OHOS_BUILD_ENABLE_POINTER
1091         case PointerEvent::SOURCE_TYPE_MOUSE: {
1092             return UpdateMouseTarget(pointerEvent);
1093         }
1094         case PointerEvent::SOURCE_TYPE_TOUCHPAD: {
1095             return UpdateTouchPadTarget(pointerEvent);
1096         }
1097 #endif // OHOS_BUILD_ENABLE_POINTER
1098 #ifdef OHOS_BUILD_ENABLE_JOYSTICK
1099         case PointerEvent::SOURCE_TYPE_JOYSTICK: {
1100             return UpdateJoystickTarget(pointerEvent);
1101         }
1102 #endif // OHOS_BUILD_ENABLE_JOYSTICK
1103         default: {
1104             MMI_HILOGE("Source type is unknown, source:%{public}d", source);
1105             break;
1106         }
1107     }
1108     return RET_ERR;
1109 }
1110 #endif // OHOS_BUILD_ENABLE_POINTER || OHOS_BUILD_ENABLE_TOUCH
1111 
1112 #ifdef OHOS_BUILD_ENABLE_POINTER
IsInsideDisplay(const DisplayInfo & displayInfo,int32_t physicalX,int32_t physicalY)1113 bool InputWindowsManager::IsInsideDisplay(const DisplayInfo& displayInfo, int32_t physicalX, int32_t physicalY)
1114 {
1115     return (physicalX >= 0 && physicalX < displayInfo.width) && (physicalY >= 0 && physicalY < displayInfo.height);
1116 }
1117 
FindPhysicalDisplay(const DisplayInfo & displayInfo,int32_t & physicalX,int32_t & physicalY,int32_t & displayId)1118 void InputWindowsManager::FindPhysicalDisplay(const DisplayInfo& displayInfo, int32_t& physicalX,
1119     int32_t& physicalY, int32_t& displayId)
1120 {
1121     CALL_DEBUG_ENTER;
1122     int32_t logicalX = 0;
1123     int32_t logicalY = 0;
1124     if (!AddInt32(physicalX, displayInfo.x, logicalX)) {
1125         MMI_HILOGE("The addition of logicalX overflows");
1126         return;
1127     }
1128     if (!AddInt32(physicalY, displayInfo.y, logicalY)) {
1129         MMI_HILOGE("The addition of logicalY overflows");
1130         return;
1131     }
1132     for (const auto &item : displayGroupInfo_.displaysInfo) {
1133         int32_t displayMaxX = 0;
1134         int32_t displayMaxY = 0;
1135         if (!AddInt32(item.x, item.width, displayMaxX)) {
1136             MMI_HILOGE("The addition of displayMaxX overflows");
1137             return;
1138         }
1139         if (!AddInt32(item.y, item.height, displayMaxY)) {
1140             MMI_HILOGE("The addition of displayMaxY overflows");
1141             return;
1142         }
1143         if ((logicalX >= item.x && logicalX < displayMaxX) &&
1144             (logicalY >= item.y && logicalY < displayMaxY)) {
1145             physicalX = logicalX - item.x;
1146             physicalY = logicalY - item.y;
1147             displayId = item.id;
1148             break;
1149         }
1150     }
1151 }
UpdateAndAdjustMouseLocation(int32_t & displayId,double & x,double & y)1152 void InputWindowsManager::UpdateAndAdjustMouseLocation(int32_t& displayId, double& x, double& y)
1153 {
1154     auto displayInfo = GetPhysicalDisplay(displayId);
1155     CHKPV(displayInfo);
1156     int32_t integerX = static_cast<int32_t>(x);
1157     int32_t integerY = static_cast<int32_t>(y);
1158     int32_t lastDisplayId = displayId;
1159     if (!IsInsideDisplay(*displayInfo, integerX, integerY)) {
1160         FindPhysicalDisplay(*displayInfo, integerX, integerY, displayId);
1161     }
1162     if (displayId != lastDisplayId) {
1163         displayInfo = GetPhysicalDisplay(displayId);
1164         CHKPV(displayInfo);
1165     }
1166     int32_t width = 0;
1167     int32_t height = 0;
1168     if (displayInfo->direction == Direction0 || displayInfo->direction == Direction180) {
1169         width = displayInfo->width;
1170         height = displayInfo->height;
1171     } else {
1172         height = displayInfo->width;
1173         width = displayInfo->height;
1174     }
1175     if (integerX < 0) {
1176         integerX = 0;
1177     }
1178     if (integerX >= width) {
1179         integerX = width - 1;
1180     }
1181     if (integerY < 0) {
1182         integerY = 0;
1183     }
1184     if (integerY >= height) {
1185         integerY = height - 1;
1186     }
1187     x = static_cast<double>(integerX) + (x - floor(x));
1188     y = static_cast<double>(integerY) + (y - floor(y));
1189     mouseLocation_.physicalX = integerX;
1190     mouseLocation_.physicalY = integerY;
1191     MMI_HILOGD("Mouse Data: physicalX:%{public}d,physicalY:%{public}d, displayId:%{public}d",
1192         mouseLocation_.physicalX, mouseLocation_.physicalY, displayId);
1193 }
1194 
GetMouseInfo()1195 MouseLocation InputWindowsManager::GetMouseInfo()
1196 {
1197     if (mouseLocation_.physicalX == -1 || mouseLocation_.physicalY == -1) {
1198         if (!displayGroupInfo_.displaysInfo.empty()) {
1199             mouseLocation_.physicalX = displayGroupInfo_.displaysInfo[0].width / 2;
1200             mouseLocation_.physicalY = displayGroupInfo_.displaysInfo[0].height / 2;
1201         }
1202     }
1203     return mouseLocation_;
1204 }
1205 #endif // OHOS_BUILD_ENABLE_POINTER
1206 
Dump(int32_t fd,const std::vector<std::string> & args)1207 void InputWindowsManager::Dump(int32_t fd, const std::vector<std::string> &args)
1208 {
1209     CALL_DEBUG_ENTER;
1210     mprintf(fd, "Windows information:\t");
1211     mprintf(fd, "windowsInfos,num:%zu", displayGroupInfo_.windowsInfo.size());
1212     for (const auto &item : displayGroupInfo_.windowsInfo) {
1213         mprintf(fd,
1214                 "\t windowsInfos: id:%d | pid:%d | uid:%d | area.x:%d | area.y:%d "
1215                 "| area.width:%d | area.height:%d | defaultHotAreas.size:%zu "
1216                 "| pointerHotAreas.size:%zu | agentWindowId:%d | flags:%d \t",
1217                 item.id, item.pid, item.uid, item.area.x, item.area.y, item.area.width,
1218                 item.area.height, item.defaultHotAreas.size(), item.pointerHotAreas.size(),
1219                 item.agentWindowId, item.flags);
1220         for (const auto &win : item.defaultHotAreas) {
1221             mprintf(fd,
1222                     "\t defaultHotAreas: x:%d | y:%d | width:%d | height:%d \t",
1223                     win.x, win.y, win.width, win.height);
1224         }
1225         for (const auto &pointer : item.pointerHotAreas) {
1226             mprintf(fd,
1227                     "\t pointerHotAreas: x:%d | y:%d | width:%d | height:%d \t",
1228                     pointer.x, pointer.y, pointer.width, pointer.height);
1229         }
1230     }
1231     mprintf(fd, "Displays information:\t");
1232     mprintf(fd, "displayInfos,num:%zu", displayGroupInfo_.displaysInfo.size());
1233     for (const auto &item : displayGroupInfo_.displaysInfo) {
1234         mprintf(fd,
1235                 "\t displayInfos: id:%d | x:%d | y:%d | width:%d | height:%d | name:%s "
1236                 "| uniq:%s | direction:%d \t",
1237                 item.id, item.x, item.y, item.width, item.height, item.name.c_str(),
1238                 item.uniq.c_str(), item.direction);
1239     }
1240 }
1241 } // namespace MMI
1242 } // namespace OHOS
1243