diff --git a/window_manager/wmserver/ft_build/BUILD.gn b/window_manager/wmserver/ft_build/BUILD.gn index 5eed6d5d4e50d39086c481069140657a2c0d44f3..cb94cc5756e019f2a808c4fae65c9e669cf2c390 100644 --- a/window_manager/wmserver/ft_build/BUILD.gn +++ b/window_manager/wmserver/ft_build/BUILD.gn @@ -25,6 +25,7 @@ config("libwms_config") { "$window_manager_path/interfaces/innerkits/wm", "$window_manager_path/interfaces/innerkits/dm", "$window_manager_path/ft_adapter", + "pointer_draw", "$window_manager_path/wm/include", "$window_manager_path/utils/include", "$window_manager_path/dm/include", @@ -76,6 +77,7 @@ ft_shared_library("libwms") { "$window_manager_path/wmserver/src/window_zorder_policy.cpp", "$window_manager_path/wmserver/src/zidl/ressched_report.cpp", "$window_manager_path/wmserver/src/zidl/window_manager_stub.cpp", + "pointer_draw/pointer_draw.cpp", ] configs = [ @@ -92,11 +94,10 @@ ft_shared_library("libwms") { "$window_manager_path/dmserver/ft_build:libdms", "$window_manager_path/utils/ft_build:libwmutil", "$window_manager_path/wm/ft_build:libwm", - - "//build/gn/configs/system_libs:safwk", "//build/gn/configs/system_libs:eventhandler", - "//build/gn/configs/system_libs:skia", "//build/gn/configs/system_libs:image", "//build/gn/configs/system_libs:mmi", + "//build/gn/configs/system_libs:safwk", + "//build/gn/configs/system_libs:skia", ] } diff --git a/window_manager/wmserver/ft_build/pointer_draw/pointer_draw.cpp b/window_manager/wmserver/ft_build/pointer_draw/pointer_draw.cpp new file mode 100644 index 0000000000000000000000000000000000000000..79eea750442d6d6ffe6c124e2fdc6005c9151584 --- /dev/null +++ b/window_manager/wmserver/ft_build/pointer_draw/pointer_draw.cpp @@ -0,0 +1,164 @@ +/* + * Copyright (c) 2023 Huawei Technologies Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "pointer_draw.h" + +#include "window_manager_hilog.h" +#include "display_manager_service_inner.h" +#include "ui/rs_surface_extractor.h" +#include "transaction/rs_transaction.h" + +using namespace OHOS; +using namespace OHOS::Rosen; + +namespace FangTian { +namespace { + constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_WINDOW, "PointerDraw"}; + constexpr int32_t ICON_WIDTH = 30; + constexpr int32_t ICON_HEIGHT = 30; +} +WM_IMPLEMENT_SINGLE_INSTANCE(PointerDraw) + +WMError PointerDraw::Init() +{ + if (InitDisplayInfo() != WMError::WM_OK) { + WLOGFE("InitDisplayInfo fail"); + return WMError::WM_ERROR_INNER; + } + + if (InitLayerNode() != WMError::WM_OK) { + WLOGFE("InitLayerNode fail"); + return WMError::WM_ERROR_INNER; + } + + if (InitDisplayNode() != WMError::WM_OK) { + WLOGFE("InitDisplayNode fail"); + return WMError::WM_ERROR_INNER; + } + + runner_ = AppExecFwk::EventRunner::Create("PointerDraw"); + handler_ = std::make_shared(runner_); + + return WMError::WM_OK; +} + +void PointerDraw::AsyncMove(int32_t x, int32_t y) +{ + int32_t posx = (x >= 0) ? x : 0; + posx = (posx <= displayWidth_) ? posx : displayWidth_; + + int32_t posy = (y >= 0) ? y : 0; + posy = (posy <= displayHeight_) ? posy : displayHeight_; + + PostAsyncTask([this, posx, posy]() { + MoveTo(posx, posy); + }); +} + +WMError PointerDraw::InitDisplayInfo() +{ + auto displayInfo = DisplayManagerServiceInner::GetInstance().GetDefaultDisplay(); + if (displayInfo == nullptr) { + WLOGFE("GetDefaultDisplay fail"); + return WMError::WM_ERROR_NULLPTR; + } + displayWidth_ = displayInfo->GetWidth(); + displayHeight_ = displayInfo->GetHeight(); + displayId_ = DisplayManagerServiceInner::GetInstance().GetDefaultDisplayId(); + + if (displayWidth_ <= 0 || displayHeight_ <= 0) { + WLOGFE("Invalid display info"); + return WMError::WM_ERROR_INVALID_PARAM; + } + + return WMError::WM_OK; +} + +WMError PointerDraw::InitLayerNode() +{ + RSSurfaceNodeConfig config; + surfaceNode_ = RSSurfaceNode::Create(config); + if (surfaceNode_ == nullptr) { + WLOGFE("RSSurfaceNode::Create fail"); + return WMError::WM_ERROR_NULLPTR; + } + + surfaceNode_->SetBounds(0, 0, ICON_WIDTH, ICON_HEIGHT); + rsSurface_ = RSSurfaceExtractor::ExtractRSSurface(surfaceNode_); + if (rsSurface_ == nullptr) { + WLOGFE("ExtractRSSurface fail"); + return WMError::WM_ERROR_NULLPTR; + } + + auto framePtr = rsSurface_->RequestFrame(ICON_WIDTH, ICON_HEIGHT); + if (framePtr == nullptr) { + WLOGFE("RequestFrame fail"); + return WMError::WM_ERROR_NULLPTR; + } + + auto canvas = framePtr->GetCanvas(); + canvas->clear(SK_ColorTRANSPARENT); + SkPaint paint; + paint.setAntiAlias(true); + paint.setStyle(SkPaint::kFill_Style); + paint.setStrokeJoin(SkPaint::kRound_Join); + paint.setColor(SK_ColorBLUE); + canvas->drawRect(SkRect::MakeXYWH(0, 0, ICON_WIDTH, ICON_HEIGHT), paint); + framePtr->SetDamageRegion(0, 0, ICON_WIDTH, ICON_HEIGHT); + rsSurface_->FlushFrame(framePtr); + + return WMError::WM_OK; +} + +WMError PointerDraw::InitDisplayNode() +{ + RSDisplayNodeConfig config; + displayNode_ = RSDisplayNode::Create(config); + if (displayNode_ == nullptr) { + WLOGFE("RSDisplayNode::Create fail"); + return WMError::WM_ERROR_NULLPTR; + } + + displayNode_->SetScreenId(displayId_); + displayNode_->SetBounds(0, 0, displayWidth_, displayHeight_); + displayNode_->AddChild(surfaceNode_, -1); + RSTransaction::FlushImplicitTransaction(); + + return WMError::WM_OK; +} + +WMError PointerDraw::MoveTo(int32_t x, int32_t y) +{ + if (surfaceNode_ == nullptr) { + WLOGFE("surfaceNode_ is nullptr"); + return WMError::WM_ERROR_NULLPTR; + } + + surfaceNode_->SetBounds(x, y, ICON_WIDTH, ICON_HEIGHT); + RSTransaction::FlushImplicitTransaction(); + + return WMError::WM_OK; +} + +void PointerDraw::PostAsyncTask(Task task) +{ + if (handler_ != nullptr) { + bool ret = handler_->PostTask(task, AppExecFwk::EventQueue::Priority::IMMEDIATE); + if (!ret) { + WLOGFE("EventHandler PostTask Failed"); + } + } +} +} // FangTian diff --git a/window_manager/wmserver/ft_build/pointer_draw/pointer_draw.h b/window_manager/wmserver/ft_build/pointer_draw/pointer_draw.h new file mode 100644 index 0000000000000000000000000000000000000000..5ded3dc5fbcd13b38fc56fca1121cc61b3e751cf --- /dev/null +++ b/window_manager/wmserver/ft_build/pointer_draw/pointer_draw.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2023 Huawei Technologies Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef POINTER_DRAW_H +#define POINTER_DRAW_H + +#include "graphic_common.h" +#include "wm_single_instance.h" +#include "ui/rs_display_node.h" +#include "ui/rs_surface_node.h" +#include "event_handler.h" + +namespace FangTian { +class PointerDraw { +WM_DECLARE_SINGLE_INSTANCE_BASE(PointerDraw); +public: + OHOS::WMError Init(); + void AsyncMove(int32_t x, int32_t y); + +private: + PointerDraw() = default; + virtual ~PointerDraw() = default; + using Task = std::function; + + OHOS::WMError InitDisplayInfo(); + OHOS::WMError InitLayerNode(); + OHOS::WMError InitDisplayNode(); + OHOS::WMError MoveTo(int32_t x, int32_t y); + void PostAsyncTask(Task task); + + int32_t displayWidth_ = 0; + int32_t displayHeight_ = 0; + uint64_t displayId_ = 0; + OHOS::Rosen::RSDisplayNode::SharedPtr displayNode_ = nullptr; + OHOS::Rosen::RSSurfaceNode::SharedPtr surfaceNode_ = nullptr; + std::shared_ptr rsSurface_ = nullptr; + std::shared_ptr runner_ = nullptr; + std::shared_ptr handler_ = nullptr; +}; +} // namespace FangTian +#endif // POINTER_DRAW_H diff --git a/window_manager/wmserver/src/window_inner_manager.cpp b/window_manager/wmserver/src/window_inner_manager.cpp index 747135890ba2878ba71bcdc931277ad279608171..46dc0b91bc46cbe20f78eafd3ee66553b9cee98e 100644 --- a/window_manager/wmserver/src/window_inner_manager.cpp +++ b/window_manager/wmserver/src/window_inner_manager.cpp @@ -17,6 +17,7 @@ #include "ability_manager_client.h" #include "memory_guard.h" +#include "pointer_draw.h" #include "window.h" #include "window_manager_hilog.h" @@ -56,6 +57,8 @@ bool WindowInnerManager::Init() return false; } + FangTian::PointerDraw::GetInstance().Init(); + WLOGFI("init window inner manager service success."); return true; } @@ -304,6 +307,15 @@ void WindowInnerManager::NotifyWindowRemovedOrDestroyed(uint32_t windowId) void WindowInnerManager::ConsumePointerEvent(const std::shared_ptr& pointerEvent) { + if (pointerEvent->GetPointerAction() == MMI::PointerEvent::POINTER_ACTION_MOVE && + pointerEvent->GetSourceType() == MMI::PointerEvent::SOURCE_TYPE_MOUSE) { + MMI::PointerEvent::PointerItem pointerItem; + int32_t pointId = pointerEvent->GetPointerId(); + if (pointerEvent->GetPointerItem(pointId, pointerItem)) { + FangTian::PointerDraw::GetInstance().AsyncMove(pointerItem.GetDisplayX(), pointerItem.GetDisplayY()); + } + } + uint32_t windowId = static_cast(pointerEvent->GetAgentWindowId()); if (moveDragController_->GetActiveWindowId() != windowId || moveDragController_->GetActiveWindowId() == INVALID_WINDOW_ID) {