From 37c2ebcf00bd018ee2f6e7407cc08ac2773b1c80 Mon Sep 17 00:00:00 2001 From: jiangwenyu1 Date: Wed, 13 Sep 2023 10:32:50 +0800 Subject: [PATCH] support wl_seat and wl_pointer --- build/prebuild.sh | 3 +- etc/ft.xml | 9 -- etc/ft_wl.xml | 29 +++++ runFT_wayland.sh | 15 +++ wayland_adapter/framework/BUILD.gn | 1 + .../framework/core/wayland_pointer.cpp | 59 +++++++++ .../framework/core/wayland_pointer.h | 5 + .../framework/core/wayland_seat.cpp | 112 +++++++++++++++++- wayland_adapter/framework/core/wayland_seat.h | 14 ++- .../framework/core/wayland_surface.cpp | 93 +++++++++++++++ .../framework/core/wayland_surface.h | 1 + .../framework/stable/wayland_xdg_surface.cpp | 5 + .../framework/stable/wayland_xdg_surface.h | 2 + .../framework/stable/wayland_xdg_toplevel.cpp | 1 + wayland_adapter/test/wayland_demo.cpp | 92 +++++++++++++- .../utils/src/wayland_resource_object.cpp | 1 + wayland_adapter/wayland_server.cpp | 2 + wayland_adapter/wayland_server.h | 2 + 18 files changed, 430 insertions(+), 16 deletions(-) create mode 100644 etc/ft_wl.xml create mode 100755 runFT_wayland.sh diff --git a/build/prebuild.sh b/build/prebuild.sh index 5ce7e96..69352e2 100755 --- a/build/prebuild.sh +++ b/build/prebuild.sh @@ -90,7 +90,7 @@ if [ ! -d ${FT_PREBUILD_DIR}/inc ]; then git clone https://gitee.com/yanansong/devel_inc.git ${FT_PREBUILD_DIR}/inc fi -# copy include files to /usr/include. +# copy include files to /usr/include. cd ${FT_PREBUILD_DIR}/inc sudo cp -fr * /usr/local/include @@ -105,6 +105,7 @@ cd ${PROJECT_DIR} # copy FT sa file to /usr/local/share/ft/ sudo mkdir -p /usr/local/share/ft sudo cp -fr ${PROJECT_DIR}/etc/ft.xml /usr/local/share/ft/ +sudo cp -fr ${PROJECT_DIR}/etc/ft_wl.xml /usr/local/share/ft/ sudo cp -fr ${PROJECT_DIR}/etc/icon /usr/local/share/ft/ sudo cp -fr ${PROJECT_DIR}/etc/desktop /usr/local/share/ft/ diff --git a/etc/ft.xml b/etc/ft.xml index db4c5af..ab60f35 100644 --- a/etc/ft.xml +++ b/etc/ft.xml @@ -19,7 +19,6 @@ /usr/lib64/librender_service.so /usr/lib64/libmmi-server.so /usr/lib64/libdms.so - /usr/lib64/libwayland_adapter.so /usr/lib64/libwms.so @@ -39,14 +38,6 @@ 1 - - 4600 - /usr/lib64/libwayland_adapter.so - true - false - 1 - - 4607 /usr/lib64/libdms.so diff --git a/etc/ft_wl.xml b/etc/ft_wl.xml new file mode 100644 index 0000000..a8f6fb8 --- /dev/null +++ b/etc/ft_wl.xml @@ -0,0 +1,29 @@ + + + + + ft_wl + + /usr/lib64/libwayland_adapter.so + + + + 4600 + /usr/lib64/libwayland_adapter.so + true + false + 1 + + diff --git a/runFT_wayland.sh b/runFT_wayland.sh new file mode 100755 index 0000000..4f81625 --- /dev/null +++ b/runFT_wayland.sh @@ -0,0 +1,15 @@ +# 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. + + +sa_main /usr/local/share/ft/ft_wl.xml diff --git a/wayland_adapter/framework/BUILD.gn b/wayland_adapter/framework/BUILD.gn index 7ebb236..6ed5758 100644 --- a/wayland_adapter/framework/BUILD.gn +++ b/wayland_adapter/framework/BUILD.gn @@ -52,6 +52,7 @@ ft_source_set("wayland_framewok_sources") { "$display_server_root/rosen/modules/render_service_client/ft_build:librender_service_client", "//build/gn/configs/system_libs:hilog", "//build/gn/configs/system_libs:image", + "//build/gn/configs/system_libs:mmi", "//display_server/drivers/hal/base:ft_event_loop", "//wayland_adapter/utils:wayland_adapter_utils_sources", "//wayland_adapter/wayland_protocols:wayland_protocols_sources", diff --git a/wayland_adapter/framework/core/wayland_pointer.cpp b/wayland_adapter/framework/core/wayland_pointer.cpp index 3168935..85dcea3 100644 --- a/wayland_adapter/framework/core/wayland_pointer.cpp +++ b/wayland_adapter/framework/core/wayland_pointer.cpp @@ -53,6 +53,65 @@ WaylandPointer::WaylandPointer(struct wl_client *client, uint32_t version, uint3 WaylandPointer::~WaylandPointer() noexcept {} + +void WaylandPointer::OnPointerButton(uint32_t time, uint32_t button, bool isPressed) +{ + wl_resource *pointer = WlResource(); + if (pointer == nullptr) { + return; + } + wl_display *display = WlDisplay(); + if (display == nullptr) { + return; + } + uint32_t serial = wl_display_next_serial(display); + uint32_t state = isPressed ? WL_POINTER_BUTTON_STATE_PRESSED : WL_POINTER_BUTTON_STATE_RELEASED; + wl_pointer_send_button(pointer, serial, time, button, state); +} + +void WaylandPointer::OnPointerMotionAbsolute(uint32_t time, int32_t posX, int32_t posY) +{ + wl_fixed_t posFixedX = wl_fixed_from_int(posX); + wl_fixed_t posFixedY = wl_fixed_from_int(posY); + wl_resource *pointer = WlResource(); + if (pointer == nullptr) { + return; + } + + wl_pointer_send_motion(pointer, time, posFixedX, posFixedY); +} + +void WaylandPointer::OnPointerLeave(struct wl_resource *surface_resource) +{ + LOG_WARN("WaylandPointer::OnPointerLeave in"); + wl_display *display = WlDisplay(); + if (display == nullptr) { + return; + } + uint32_t serial = wl_display_next_serial(display); + wl_resource *pointer = WlResource(); + if (pointer == nullptr) { + return; + } + wl_pointer_send_leave(pointer, serial, surface_resource); +} +void WaylandPointer::OnPointerEnter(int32_t posX, int32_t posY, struct wl_resource *surface_resource) +{ + LOG_WARN("WaylandPointer::OnPointerEnter in"); + wl_fixed_t posFixedX = wl_fixed_from_int(posX); + wl_fixed_t posFixedY = wl_fixed_from_int(posY); + wl_resource *pointer = WlResource(); + if (pointer == nullptr) { + return; + } + wl_display *display = WlDisplay(); + if (display == nullptr) { + return; + } + uint32_t serial = wl_display_next_serial(display); + wl_pointer_send_enter(pointer, serial, surface_resource, posFixedX, posFixedY); +} + void WaylandPointer::SetCursor(uint32_t serial, struct wl_resource *surface, int32_t hotsPotx, int32_t hotsPoty) {} } // namespace Wayland } // namespace FT \ No newline at end of file diff --git a/wayland_adapter/framework/core/wayland_pointer.h b/wayland_adapter/framework/core/wayland_pointer.h index a787897..8e75716 100644 --- a/wayland_adapter/framework/core/wayland_pointer.h +++ b/wayland_adapter/framework/core/wayland_pointer.h @@ -32,6 +32,11 @@ public: static OHOS::sptr Create(struct wl_client *client, uint32_t version, uint32_t id); ~WaylandPointer() noexcept override; + void OnPointerLeave(struct wl_resource *surface_resource); + void OnPointerEnter(int32_t posX, int32_t posY, struct wl_resource *surface_resource); + void OnPointerButton(uint32_t time, uint32_t button, bool isPressed); + void OnPointerMotionAbsolute(uint32_t time, int32_t posX, int32_t posY); + private: WaylandPointer(struct wl_client *client, uint32_t version, uint32_t id); void SetCursor(uint32_t serial, struct wl_resource *surface, int32_t hotsPotx, int32_t hotsPoty); diff --git a/wayland_adapter/framework/core/wayland_seat.cpp b/wayland_adapter/framework/core/wayland_seat.cpp index 01909f2..67d3cd5 100644 --- a/wayland_adapter/framework/core/wayland_seat.cpp +++ b/wayland_adapter/framework/core/wayland_seat.cpp @@ -13,17 +13,24 @@ * limitations under the License. */ +#include #include "wayland_seat.h" #include "wayland_objects_pool.h" #include "version.h" +#include "input_manager.h" +#include +using namespace OHOS::MMI; namespace FT { namespace Wayland { namespace { constexpr HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_WAYLAND, "WaylandSeat"}; } +static OHOS::sptr wl_seat_global = nullptr; +std::mutex wl_seat_global_mutex_; + struct wl_seat_interface IWaylandSeat::impl_ = { .get_pointer = GetPointer, .get_keyboard = GetKeyboard, @@ -50,18 +57,38 @@ void IWaylandSeat::GetTouch(struct wl_client *client, struct wl_resource *resour OHOS::sptr WaylandSeat::Create(struct wl_display *display) { + std::lock_guard lock(wl_seat_global_mutex_); if (display == nullptr) { LOG_ERROR("display is nullptr"); return nullptr; } - return OHOS::sptr(new WaylandSeat(display)); + if (wl_seat_global != nullptr) { + return wl_seat_global; + } + + wl_seat_global = OHOS::sptr(new WaylandSeat(display)); + return wl_seat_global; +} + +OHOS::sptr WaylandSeat::GetWaylandSeatGlobal() +{ + std::lock_guard lock(wl_seat_global_mutex_); + return wl_seat_global; } WaylandSeat::WaylandSeat(struct wl_display *display) : WaylandGlobal(display, &wl_seat_interface, WL_SEAT_MAX_VERSION) {} -WaylandSeat::~WaylandSeat() noexcept {} +WaylandSeat::~WaylandSeat() noexcept +{ + if (thread_ != nullptr) { + if (thread_->joinable()) { + thread_->join(); + } + thread_ = nullptr; + } +} void WaylandSeat::Bind(struct wl_client *client, uint32_t version, uint32_t id) { @@ -71,6 +98,81 @@ void WaylandSeat::Bind(struct wl_client *client, uint32_t version, uint32_t id) return; } WaylandObjectsPool::GetInstance().AddObject(ObjectId(object->WlClient(), object->Id()), object); + seatResourcesMap_[client] = object; + + if (thread_ != nullptr) { + if (thread_->joinable()) { + thread_->join(); + } + thread_ = nullptr; + } + thread_ = std::make_unique(&WaylandSeat::UpdateCapabilities, this); +} + +OHOS::sptr WaylandSeat::GetPointerResource(struct wl_client *client) +{ + if (seatResourcesMap_.count(client) == 0) { + return nullptr; + } + + auto seatResource = seatResourcesMap_.at(client); + // Erase seat resource from map if it is destroyed. + if (seatResource == nullptr) { + seatResourcesMap_.erase(client); + return nullptr; + } + LOG_INFO("get seatResource name=%{public}s, id=%{public}d", seatResource->Name().c_str(), seatResource->Id()); + return seatResource->GetChildPointer(); +} + +void WaylandSeat::UpdateCapabilities() +{ + LOG_INFO("UpdateCapabilities in"); + uint32_t cap = 0; + int32_t DevNums = 0; + int32_t hasGetDevNums = 0; + bool isGetIds = false; + int32_t wait_count = 0; + + auto GetDeviceCb = [&hasGetDevNums, &cap](std::shared_ptr inputDevice) { + LOG_INFO("Get device success, id=%{public}d, name=%{public}s, type=%{public}d", + inputDevice->GetId(), inputDevice->GetName().c_str(), inputDevice->GetType()); + if (inputDevice->GetType() == (int32_t)DEVICE_TYPE_MOUSE) { + cap |= WL_SEAT_CAPABILITY_POINTER; + } else if (inputDevice->GetType() == (int32_t)DEVICE_TYPE_KEYBOARD) { + cap |= WL_SEAT_CAPABILITY_KEYBOARD; + } + hasGetDevNums++; + }; + auto GetDeviceIdsCb = [&DevNums, &isGetIds](std::vector ids) { + DevNums = ids.size(); + isGetIds = true; + }; + (void)InputManager::GetInstance()->GetDeviceIds(GetDeviceIdsCb); + while (!isGetIds && wait_count < 100) { + usleep(3 * 1000); // wait for GetDeviceIdsCb finish + wait_count++; + } + + for (int32_t i = 0; i < DevNums; i++) { + InputManager::GetInstance()->GetDevice(i, GetDeviceCb); + } + + wait_count = 0; + while (hasGetDevNums != DevNums && wait_count < 100) { + usleep(3 * 1000); // wait for GetDeviceCb finish + wait_count++; + } + + for (auto iter = seatResourcesMap_.begin(); iter != seatResourcesMap_.end();) { + auto seatObj = iter->second; + if (seatObj == nullptr) { + iter = seatResourcesMap_.erase(iter); + } else { + wl_seat_send_capabilities(seatObj->WlResource(), cap); + ++iter; + } + } } WaylandSeatObject::WaylandSeatObject(struct wl_client *client, uint32_t version, uint32_t id) @@ -78,6 +180,11 @@ WaylandSeatObject::WaylandSeatObject(struct wl_client *client, uint32_t version, WaylandSeatObject::~WaylandSeatObject() noexcept {} +OHOS::sptr WaylandSeatObject::GetChildPointer() +{ + return pointer_; +} + void WaylandSeatObject::GetPointer(uint32_t id) { auto pointer = WaylandPointer::Create(WlClient(), wl_resource_get_version(WlResource()), id); @@ -85,7 +192,6 @@ void WaylandSeatObject::GetPointer(uint32_t id) LOG_ERROR("no memory"); return; } - pointer_ = pointer; } diff --git a/wayland_adapter/framework/core/wayland_seat.h b/wayland_adapter/framework/core/wayland_seat.h index 2afb70e..f0e0122 100644 --- a/wayland_adapter/framework/core/wayland_seat.h +++ b/wayland_adapter/framework/core/wayland_seat.h @@ -15,6 +15,7 @@ #pragma once +#include #include "wayland_global.h" #include "wayland_pointer.h" #include "wayland_keyboard.h" @@ -28,16 +29,24 @@ struct IWaylandSeat { static struct wl_seat_interface impl_; }; + +class WaylandSeatObject; + class WaylandSeat final : public WaylandGlobal { friend struct IWaylandSeat; public: static OHOS::sptr Create(struct wl_display *display); + static OHOS::sptr GetWaylandSeatGlobal(); + OHOS::sptr GetPointerResource(struct wl_client *client); ~WaylandSeat() noexcept override; private: WaylandSeat(struct wl_display *display); void Bind(struct wl_client *client, uint32_t version, uint32_t id) override; + void UpdateCapabilities(); + std::unordered_map> seatResourcesMap_; + std::unique_ptr thread_ = nullptr; }; class WaylandSeatObject final : public WaylandResourceObject { @@ -46,14 +55,15 @@ class WaylandSeatObject final : public WaylandResourceObject { public: WaylandSeatObject(struct wl_client *client, uint32_t version, uint32_t id); ~WaylandSeatObject() noexcept; + OHOS::sptr GetChildPointer(); private: void GetPointer(uint32_t id); void GetKeyboard(uint32_t id); void GetTouch(uint32_t id); - OHOS::wptr pointer_; - OHOS::wptr keyboard_; + OHOS::sptr pointer_; + OHOS::sptr keyboard_; }; } // namespace Wayland } // namespace FT diff --git a/wayland_adapter/framework/core/wayland_surface.cpp b/wayland_adapter/framework/core/wayland_surface.cpp index d3866f6..dbd5d55 100644 --- a/wayland_adapter/framework/core/wayland_surface.cpp +++ b/wayland_adapter/framework/core/wayland_surface.cpp @@ -13,11 +13,14 @@ * limitations under the License. */ +#include #include "wayland_surface.h" #include "wayland_objects_pool.h" #include "ui/rs_surface_extractor.h" #include "wayland_region.h" +#include "wayland_seat.h" +#include "input_manager.h" namespace FT { namespace Wayland { @@ -25,6 +28,86 @@ namespace { constexpr HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_WAYLAND, "WaylandSurface"}; } +class InputEventConsumer : public OHOS::Rosen::IInputEventConsumer +{ +public: + InputEventConsumer(OHOS::sptr wlSurface) + { + wlSurface_ = wlSurface; + } + + bool OnInputEvent(const std::shared_ptr& keyEvent) const override; + bool OnInputEvent(const std::shared_ptr& axisEvent) const override; + bool OnInputEvent(const std::shared_ptr& pointerEvent) const override; +private: + OHOS::sptr wlSurface_ = nullptr; + int32_t MapPointerActionButton(int32_t PointerActionButtonType) const; + const std::map ptrActionMap_ = { + {OHOS::MMI::PointerEvent::MOUSE_BUTTON_LEFT, BTN_LEFT}, + {OHOS::MMI::PointerEvent::MOUSE_BUTTON_RIGHT, BTN_RIGHT}, + }; + +}; + +int32_t InputEventConsumer::MapPointerActionButton(int32_t PointerActionButtonType) const +{ + auto it = ptrActionMap_.find(PointerActionButtonType); + if (it == ptrActionMap_.end()) { + return OHOS::MMI::PointerEvent::BUTTON_NONE; + } + return it->second; +} + +bool InputEventConsumer::OnInputEvent(const std::shared_ptr& keyEvent) const +{ + keyEvent->MarkProcessed(); + return true; +} + +bool InputEventConsumer::OnInputEvent(const std::shared_ptr& axisEvent) const +{ + axisEvent->MarkProcessed(); + return true; +} + +bool InputEventConsumer::OnInputEvent(const std::shared_ptr& pointerEvent) const +{ + OHOS::sptr wlSeat = WaylandSeat::GetWaylandSeatGlobal(); + if (wlSeat == nullptr) { + return false; + } + pointerEvent->MarkProcessed(); + auto pointer = wlSeat->GetPointerResource(wlSurface_->WlClient()); + if (pointer == nullptr) { + LOG_WARN("GetPointerResource fail"); + return false; + } + + OHOS::MMI::PointerEvent::PointerItem pointerItem; + int32_t pointId = pointerEvent->GetPointerId(); + if (!pointerEvent->GetPointerItem(pointId, pointerItem)) { + LOG_WARN("GetPointerItem fail"); + return false; + } + + if (pointerEvent->GetPointerAction() == OHOS::MMI::PointerEvent::POINTER_ACTION_ENTER_WINDOW) { + pointer->OnPointerEnter(pointerItem.GetDisplayX(), pointerItem.GetDisplayY(), wlSurface_->WlResource()); + } else if (pointerEvent->GetPointerAction() == OHOS::MMI::PointerEvent::POINTER_ACTION_LEAVE_WINDOW) { + pointer->OnPointerLeave(wlSurface_->WlResource()); + } else if (pointerEvent->GetPointerAction() == OHOS::MMI::PointerEvent::POINTER_ACTION_BUTTON_DOWN || + pointerEvent->GetPointerAction() == OHOS::MMI::PointerEvent::POINTER_ACTION_BUTTON_UP) { + int32_t buttonId = MapPointerActionButton(pointerEvent->GetButtonId()); + if (buttonId != OHOS::MMI::PointerEvent::BUTTON_NONE) { + pointer->OnPointerButton(pointerEvent->GetActionTime(), buttonId, pointerItem.IsPressed()); + } + } else if (pointerEvent->GetPointerAction() == OHOS::MMI::PointerEvent::POINTER_ACTION_MOVE) { + pointer->OnPointerMotionAbsolute( + pointerEvent->GetActionTime(), pointerItem.GetDisplayX(), pointerItem.GetDisplayY()); + } + return true; +} + + struct wl_surface_interface IWaylandSurface::impl_ = { .destroy = &WaylandResourceObject::DefaultDestroyResource, .attach = Attach, @@ -189,6 +272,13 @@ void WaylandSurface::SetInputRegion(struct wl_resource *regionResource) rect.x, rect.y, rect.width, rect.height); } +void WaylandSurface::StartMove() +{ + if (window_ != nullptr) { + window_->StartMove(); + } +} + void WaylandSurface::Commit() { if (window_ == nullptr) { @@ -258,6 +348,7 @@ void WaylandSurface::CreateWindow() OHOS::sptr option(new OHOS::Rosen::WindowOption()); option->SetWindowType(OHOS::Rosen::WindowType::APP_MAIN_WINDOW_BASE); option->SetWindowMode(OHOS::Rosen::WindowMode::WINDOW_MODE_FLOATING); + option->SetMainHandlerAvailable(false); static int count = 0; std::string windowName = "WaylandWindow" + std::to_string(count++); @@ -266,6 +357,8 @@ void WaylandSurface::CreateWindow() LOG_ERROR("Window::Create failed"); return; } + auto listener = std::make_shared(this); + window_->SetInputEventConsumer(listener); window_->Show(); surfaceNode_ = window_->GetSurfaceNode(); diff --git a/wayland_adapter/framework/core/wayland_surface.h b/wayland_adapter/framework/core/wayland_surface.h index c7d81f4..e7854b4 100644 --- a/wayland_adapter/framework/core/wayland_surface.h +++ b/wayland_adapter/framework/core/wayland_surface.h @@ -55,6 +55,7 @@ public: void AddCommitCallback(SurfaceCommitCallback callback); void AddRectCallback(SurfaceRectCallback callback); + void StartMove(); private: WaylandSurface(struct wl_client *client, struct wl_resource *parent, uint32_t version, uint32_t id); diff --git a/wayland_adapter/framework/stable/wayland_xdg_surface.cpp b/wayland_adapter/framework/stable/wayland_xdg_surface.cpp index 873d11e..e315351 100644 --- a/wayland_adapter/framework/stable/wayland_xdg_surface.cpp +++ b/wayland_adapter/framework/stable/wayland_xdg_surface.cpp @@ -109,6 +109,11 @@ void WaylandXdgSurface::AckConfigure(uint32_t serial) { } +void WaylandXdgSurface::StartMove() +{ + surface_->StartMove(); +} + void WaylandXdgSurface::OnSurfaceCommit() { if (role_ == SurfaceRole::XDG_TOPLEVEL) { diff --git a/wayland_adapter/framework/stable/wayland_xdg_surface.h b/wayland_adapter/framework/stable/wayland_xdg_surface.h index 56d9ad4..6f1a016 100644 --- a/wayland_adapter/framework/stable/wayland_xdg_surface.h +++ b/wayland_adapter/framework/stable/wayland_xdg_surface.h @@ -41,6 +41,8 @@ public: WaylandXdgSurface(const OHOS::sptr &xdgWm, const OHOS::sptr &surface, uint32_t id); ~WaylandXdgSurface() noexcept override; + void StartMove(); + private: friend struct IWaylandXdgSurface; diff --git a/wayland_adapter/framework/stable/wayland_xdg_toplevel.cpp b/wayland_adapter/framework/stable/wayland_xdg_toplevel.cpp index 993aa52..32832be 100644 --- a/wayland_adapter/framework/stable/wayland_xdg_toplevel.cpp +++ b/wayland_adapter/framework/stable/wayland_xdg_toplevel.cpp @@ -143,6 +143,7 @@ void WaylandXdgToplevel::SetTitle(const char *title) void WaylandXdgToplevel::Move(uint32_t serial) { + xdgSurface_->StartMove(); } void WaylandXdgToplevel::Resize(uint32_t serial, uint32_t edges) diff --git a/wayland_adapter/test/wayland_demo.cpp b/wayland_adapter/test/wayland_demo.cpp index 8dcc262..44b2b6b 100644 --- a/wayland_adapter/test/wayland_demo.cpp +++ b/wayland_adapter/test/wayland_demo.cpp @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -47,6 +48,7 @@ constexpr int32_t WINDOW_WIDTH = 500; constexpr int32_t WINDOW_HEIGHT = 400; +struct window; struct display { struct wl_display *display; @@ -54,6 +56,9 @@ struct display { struct wl_compositor *compositor; struct xdg_wm_base *wm_base; struct wl_shm *shm; + struct wl_seat *seat; + struct wl_pointer *pointer; + struct window *window; bool has_rgba8888 = false; }; @@ -242,7 +247,7 @@ static struct window *CreateWindow(struct display *display, int32_t width, int32 wl_surface_set_opaque_region(pWindow->surface, pWindow->region); wl_surface_set_input_region(pWindow->surface, pWindow->region); wl_region_destroy(pWindow->region); - + display->window = pWindow; return pWindow; } @@ -542,6 +547,87 @@ static void XdgWmBasePing(void *data, struct xdg_wm_base *shell, uint32_t serial static const struct xdg_wm_base_listener xdg_wm_base_listener = {XdgWmBasePing}; +void pointer_enter(void *data, struct wl_pointer *wl_pointer, uint32_t serial, struct wl_surface *surface, wl_fixed_t surface_x, wl_fixed_t surface_y) +{ + fprintf(stderr, "pointer_enter in, surface_x=%d, surface_y=%d\n", wl_fixed_to_int(surface_x), wl_fixed_to_int(surface_y)); +} + +void pointer_leave(void *data, struct wl_pointer *wl_pointer, uint32_t serial, struct wl_surface *surface) +{ + fprintf(stderr, "pointer_leave in\n"); +} + +void pointer_motion(void *data, struct wl_pointer *wl_pointer, uint32_t time, wl_fixed_t surface_x, wl_fixed_t surface_y) +{ + fprintf(stderr, "pointer_motion in, surface_x=%d, surface_y=%d\n", wl_fixed_to_int(surface_x), wl_fixed_to_int(surface_y)); +} + +void pointer_button(void *data, struct wl_pointer *wl_pointer, uint32_t serial, uint32_t time, uint32_t button, uint32_t state) +{ + struct display *d = static_cast(data); + fprintf(stderr, "pointer_button in, button=%d, state=%d\n", button, state); + if (button == BTN_LEFT && state == WL_POINTER_BUTTON_STATE_PRESSED) { + xdg_toplevel_move(d->window->xdg_toplevel, d->seat, serial); + } +} + +void pointer_axis(void *data, struct wl_pointer *wl_pointer, uint32_t time, uint32_t axis, wl_fixed_t value) +{ + fprintf(stderr, "pointer_axis in\n"); +} + +void pointer_frame(void *data, struct wl_pointer *wl_pointer) +{ + fprintf(stderr, "pointer_frame in\n"); +} + +void pointer_axis_source(void *data, struct wl_pointer *wl_pointer, uint32_t axis_source) +{ + fprintf(stderr, "pointer_axis_source in\n"); +} + +void pointer_axis_stop(void *data, struct wl_pointer *wl_pointer, uint32_t time, uint32_t axis) +{ + fprintf(stderr, "pointer_axis_stop in\n"); +} + +void pointer_axis_discrete(void *data, struct wl_pointer *wl_pointer, uint32_t axis, int32_t discrete) +{ + fprintf(stderr, "pointer_axis_discrete in\n"); +} + +struct wl_pointer_listener pointer_listener = { + .enter = pointer_enter, + .leave = pointer_leave, + .motion = pointer_motion, + .button = pointer_button, + .axis = pointer_axis, + .frame = pointer_frame, + .axis_source = pointer_axis_source, + .axis_stop = pointer_axis_stop, + .axis_discrete = pointer_axis_discrete, +}; + +void wl_seat_capabilities(void *data, struct wl_seat *wl_seat, uint32_t capabilities) +{ + struct display *d = static_cast(data); + if (capabilities & WL_SEAT_CAPABILITY_POINTER) { + fprintf(stderr, "fangtian has a pointer, get it!\n"); + d->pointer = wl_seat_get_pointer(d->seat); + wl_pointer_add_listener(d->pointer, &pointer_listener, d); + } + if (capabilities & WL_SEAT_CAPABILITY_KEYBOARD) { + fprintf(stderr, "fangtian has a keyboard\n"); + } +} + +void wl_seat_name(void *data, struct wl_seat *wl_seat, const char *name) {} + +struct wl_seat_listener seat_listener = { + wl_seat_capabilities, + wl_seat_name, +}; + static void RegistryGlobal(void *data, struct wl_registry *registry, uint32_t id, const char *interface, uint32_t version) { @@ -555,6 +641,9 @@ static void RegistryGlobal(void *data, struct wl_registry *registry, } else if (strcmp(interface, "wl_shm") == 0) { d->shm = (struct wl_shm *)wl_registry_bind(registry, id, &wl_shm_interface, 1); wl_shm_add_listener(d->shm, &shm_listener, d); + } else if (strcmp(interface, "wl_seat") == 0) { + d->seat = (struct wl_seat *)wl_registry_bind(registry, id, &wl_seat_interface, 1); + wl_seat_add_listener(d->seat, &seat_listener, d); } } @@ -595,6 +684,7 @@ static struct display *CreateDisplay() static void DestroyDisplay(struct display *display) { + display->window = nullptr; if (display->shm) { wl_shm_destroy(display->shm); } diff --git a/wayland_adapter/utils/src/wayland_resource_object.cpp b/wayland_adapter/utils/src/wayland_resource_object.cpp index 7b4cb8a..bf1e73f 100644 --- a/wayland_adapter/utils/src/wayland_resource_object.cpp +++ b/wayland_adapter/utils/src/wayland_resource_object.cpp @@ -41,6 +41,7 @@ WaylandResourceObject::WaylandResourceObject(struct wl_client *client, const str id_ = wl_resource_get_id(resource_); wl_resource_set_implementation(resource_, implementation_, this, &WaylandResourceObject::OnDestroy); name_ = std::string(interface_->name) + "_" + std::to_string(version_) + "_" + std::to_string(id_); + LOG_INFO("create WaylandResourceObject, name=%{public}s, id=%{public}d", name_.c_str(), id_); } WaylandResourceObject::~WaylandResourceObject() noexcept diff --git a/wayland_adapter/wayland_server.cpp b/wayland_adapter/wayland_server.cpp index 8ee00f9..8523628 100644 --- a/wayland_adapter/wayland_server.cpp +++ b/wayland_adapter/wayland_server.cpp @@ -39,6 +39,7 @@ void WaylandServer::CreateGlobalObjects() compositorGlobal_ = WaylandCompositor::Create(display_); xdgWmBaseGlobal_ = WaylandXdgWmBase::Create(display_); outputGlobal_ = WaylandOutput::Create(display_); + seatGlobal_ = WaylandSeat::Create(display_); wl_display_add_shm_format(display_, WL_SHM_FORMAT_RGBA8888); wl_display_init_shm(display_); } @@ -102,6 +103,7 @@ void WaylandServer::OnStop() loop_ = nullptr; compositorGlobal_ = nullptr; xdgWmBaseGlobal_ = nullptr; + seatGlobal_ = nullptr; } void WaylandServer::OnAddSystemAbility(int32_t systemAbilityId, const std::string &deviceId) diff --git a/wayland_adapter/wayland_server.h b/wayland_adapter/wayland_server.h index aa88d18..56e86e1 100644 --- a/wayland_adapter/wayland_server.h +++ b/wayland_adapter/wayland_server.h @@ -24,6 +24,7 @@ #include "wayland_compositor.h" #include "wayland_xdg_wm_base.h" #include "wayland_output.h" +#include "wayland_seat.h" namespace FT { namespace Wayland { @@ -52,6 +53,7 @@ private: OHOS::sptr compositorGlobal_; OHOS::sptr xdgWmBaseGlobal_; OHOS::sptr outputGlobal_; + OHOS::sptr seatGlobal_; }; } // namespace Wayland } // namespace FT -- Gitee