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 ⁢
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 ⁢
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