From 019d5dea79b9ac8ec17d5925546aab66473f67f5 Mon Sep 17 00:00:00 2001 From: Roger Zanoni Date: Mon, 15 May 2023 20:32:06 +0200 Subject: [PATCH 01/33] [agl][compositor] Add agl_shell_wrapper / AGL wayland extension This is a backport of the chages we did on top of chromium webosose to be able to communicate with the agl-compositor Signed-off-by: Roger Zanoni --- ui/base/ui_base_switches.cc | 2 + ui/base/ui_base_switches.h | 3 + ui/ozone/platform/wayland/BUILD.gn | 7 + .../platform/wayland/extensions/agl/BUILD.gn | 40 ++++ .../agl/common/wayland_object_agl.cc | 26 +++ .../agl/common/wayland_object_agl.h | 34 ++++ .../extensions/agl/host/agl_shell_wrapper.cc | 113 +++++++++++ .../extensions/agl/host/agl_shell_wrapper.h | 62 ++++++ .../agl/host/wayland_extensions_agl.h | 37 ++++ .../agl/host/wayland_extensions_agl_impl.cc | 93 +++++++++ .../agl/host/wayland_extensions_agl_impl.h | 54 ++++++ .../extensions/agl/protocol/agl-shell.xml | 179 ++++++++++++++++++ .../wayland/host/wayland_connection.cc | 12 +- .../wayland/host/wayland_connection.h | 4 + .../wayland/host/wayland_extensions.h | 56 ++++++ 15 files changed, 720 insertions(+), 2 deletions(-) create mode 100644 ui/ozone/platform/wayland/extensions/agl/BUILD.gn create mode 100644 ui/ozone/platform/wayland/extensions/agl/common/wayland_object_agl.cc create mode 100644 ui/ozone/platform/wayland/extensions/agl/common/wayland_object_agl.h create mode 100644 ui/ozone/platform/wayland/extensions/agl/host/agl_shell_wrapper.cc create mode 100644 ui/ozone/platform/wayland/extensions/agl/host/agl_shell_wrapper.h create mode 100644 ui/ozone/platform/wayland/extensions/agl/host/wayland_extensions_agl.h create mode 100644 ui/ozone/platform/wayland/extensions/agl/host/wayland_extensions_agl_impl.cc create mode 100644 ui/ozone/platform/wayland/extensions/agl/host/wayland_extensions_agl_impl.h create mode 100644 ui/ozone/platform/wayland/extensions/agl/protocol/agl-shell.xml create mode 100644 ui/ozone/platform/wayland/host/wayland_extensions.h diff --git a/ui/base/ui_base_switches.cc b/ui/base/ui_base_switches.cc index 514bb3cdb580d..d94e2c5e78306 100644 --- a/ui/base/ui_base_switches.cc +++ b/ui/base/ui_base_switches.cc @@ -112,4 +112,6 @@ const char kUIDisablePartialSwap[] = "ui-disable-partial-swap"; // Enables the ozone x11 clipboard for linux-chromeos. const char kUseSystemClipboard[] = "use-system-clipboard"; +const char kAglShellAppId[] = "agl-shell-appid"; + } // namespace switches diff --git a/ui/base/ui_base_switches.h b/ui/base/ui_base_switches.h index ec664b866c5d2..cf483e0339072 100644 --- a/ui/base/ui_base_switches.h +++ b/ui/base/ui_base_switches.h @@ -53,6 +53,9 @@ COMPONENT_EXPORT(UI_BASE) extern const char kTopChromeTouchUiEnabled[]; COMPONENT_EXPORT(UI_BASE) extern const char kUIDisablePartialSwap[]; COMPONENT_EXPORT(UI_BASE) extern const char kUseSystemClipboard[]; +// Agl related +COMPONENT_EXPORT(UI_BASE) extern const char kAglShellAppId[]; + // Test related. COMPONENT_EXPORT(UI_BASE) extern const char kDisallowNonExactResourceReuse[]; COMPONENT_EXPORT(UI_BASE) extern const char kMangleLocalizedStrings[]; diff --git a/ui/ozone/platform/wayland/BUILD.gn b/ui/ozone/platform/wayland/BUILD.gn index ae763d441d55c..8a436de0fafe3 100644 --- a/ui/ozone/platform/wayland/BUILD.gn +++ b/ui/ozone/platform/wayland/BUILD.gn @@ -397,6 +397,13 @@ source_set("wayland") { ] configs += [ "//third_party/khronos:khronos_headers" ] + + sources += [ + "host/wayland_extensions.h", + "host/wayland_extensions_stub.cc", + ] + + deps += [ "extensions/agl" ] } source_set("test_support") { diff --git a/ui/ozone/platform/wayland/extensions/agl/BUILD.gn b/ui/ozone/platform/wayland/extensions/agl/BUILD.gn new file mode 100644 index 0000000000000..ce289bc5dbbca --- /dev/null +++ b/ui/ozone/platform/wayland/extensions/agl/BUILD.gn @@ -0,0 +1,40 @@ +# Copyright 2021 LG Electronics, Inc. +# +# 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. +# +# SPDX-License-Identifier: Apache-2.0 + +import("//third_party/wayland/wayland_protocol.gni") + +visibility = [ "//ui/ozone/*" ] + +wayland_protocol("agl_shell_protocol") { + sources = [ "protocol/agl-shell.xml" ] +} + +source_set("agl") { + sources = [ + "common/wayland_object_agl.cc", + "common/wayland_object_agl.h", + "host/agl_shell_wrapper.cc", + "host/agl_shell_wrapper.h", + "host/wayland_extensions_agl.h", + "host/wayland_extensions_agl_impl.cc", + "host/wayland_extensions_agl_impl.h", + ] + + deps = [ + ":agl_shell_protocol", + "//ui/ozone/platform/wayland/mojom", + ] +} diff --git a/ui/ozone/platform/wayland/extensions/agl/common/wayland_object_agl.cc b/ui/ozone/platform/wayland/extensions/agl/common/wayland_object_agl.cc new file mode 100644 index 0000000000000..9f3300766df2c --- /dev/null +++ b/ui/ozone/platform/wayland/extensions/agl/common/wayland_object_agl.cc @@ -0,0 +1,26 @@ +// Copyright 2021 LG Electronics, Inc. +// +// 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. +// +// SPDX-License-Identifier: Apache-2.0 + +#include "ui/ozone/platform/wayland/extensions/agl/common/wayland_object_agl.h" + +#include + +namespace wl { + +const wl_interface* ObjectTraits::interface = &agl_shell_interface; +void (*ObjectTraits::deleter)(agl_shell*) = &agl_shell_destroy; + +} // namespace wl \ No newline at end of file diff --git a/ui/ozone/platform/wayland/extensions/agl/common/wayland_object_agl.h b/ui/ozone/platform/wayland/extensions/agl/common/wayland_object_agl.h new file mode 100644 index 0000000000000..e91ac0da8d2fc --- /dev/null +++ b/ui/ozone/platform/wayland/extensions/agl/common/wayland_object_agl.h @@ -0,0 +1,34 @@ +// Copyright 2021 LG Electronics, Inc. +// +// 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. +// +// SPDX-License-Identifier: Apache-2.0 + +#ifndef UI_OZONE_PLATFORM_WAYLAND_EXTENSIONS_AGL_COMMON_WAYLAND_OBJECT_AGL_H_ +#define UI_OZONE_PLATFORM_WAYLAND_EXTENSIONS_AGL_COMMON_WAYLAND_OBJECT_AGL_H_ + +#include "ui/ozone/platform/wayland/common/wayland_object.h" + +struct agl_shell; + +namespace wl { + +template <> +struct ObjectTraits { + static const wl_interface* interface; + static void (*deleter)(agl_shell*); +}; + +} // namespace wl + +#endif // UI_OZONE_PLATFORM_WAYLAND_EXTENSIONS_AGL_COMMON_WAYLAND_OBJECT_AGL_H_ \ No newline at end of file diff --git a/ui/ozone/platform/wayland/extensions/agl/host/agl_shell_wrapper.cc b/ui/ozone/platform/wayland/extensions/agl/host/agl_shell_wrapper.cc new file mode 100644 index 0000000000000..c74fa5d9cd221 --- /dev/null +++ b/ui/ozone/platform/wayland/extensions/agl/host/agl_shell_wrapper.cc @@ -0,0 +1,113 @@ +// Copyright 2021 LG Electronics, Inc. +// +// 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. +// +// SPDX-License-Identifier: Apache-2.0 + +#include "ui/ozone/platform/wayland/extensions/agl/host/agl_shell_wrapper.h" + +#include "agl_shell_wrapper.h" +#include "base/logging.h" +#include "ui/base/ui_base_switches.h" +#include "ui/ozone/platform/wayland/host/wayland_connection.h" +#include "ui/ozone/platform/wayland/host/wayland_output_manager.h" +#include "ui/ozone/platform/wayland/host/wayland_window.h" + +namespace ui { + +static const struct agl_shell_listener shell_listener = { + &AglShellWrapper::AglShellBoundOk, + &AglShellWrapper::AglShellBoundFail, +#ifdef AGL_SHELL_APP_STATE_SINCE_VERSION + &AglShellWrapper::AglAppState, +#endif +}; + +AglShellWrapper::AglShellWrapper(agl_shell* agl_shell, + WaylandConnection* wayland_connection) + : agl_shell_(agl_shell), connection_(wayland_connection) { + if (wl::get_version_of_object(agl_shell) >= AGL_SHELL_BOUND_OK_SINCE_VERSION) + agl_shell_add_listener(agl_shell, &shell_listener, this); +} + +AglShellWrapper::~AglShellWrapper() = default; + +void AglShellWrapper::SetAglActivateApp(const std::string& app_id) { + wl_output* output = + connection_->wayland_output_manager()->GetPrimaryOutput()->get_output(); + agl_shell_activate_app(agl_shell_.get(), app_id.c_str(), output); +} + +void AglShellWrapper::SetAglPanel(WaylandWindow* window, uint32_t edge) { + wl_surface* surface = window->root_surface()->surface(); + wl_output* output = + connection_->wayland_output_manager()->GetPrimaryOutput()->get_output(); + + agl_shell_set_panel(agl_shell_.get(), surface, output, edge); +} + +void AglShellWrapper::SetAglBackground(WaylandWindow* window) { + wl_surface* surface = window->root_surface()->surface(); + wl_output* output = + connection_->wayland_output_manager()->GetPrimaryOutput()->get_output(); + + agl_shell_set_background(agl_shell_.get(), surface, output); +} + +void AglShellWrapper::SetAglReady() { + agl_shell_ready(agl_shell_.get()); +} + +// static +void AglShellWrapper::AglShellBoundOk(void* data, struct agl_shell*) { + AglShellWrapper* wrapper = static_cast(data); + wrapper->wait_for_bound_ = false; + wrapper->bound_ok_ = true; + LOG(INFO) << "Bound to agl_shell (bound_ok)"; +} + +// static +void AglShellWrapper::AglShellBoundFail(void* data, struct agl_shell*) { + AglShellWrapper* wrapper = static_cast(data); + wrapper->wait_for_bound_ = false; + wrapper->bound_ok_ = false; + LOG(INFO) << "Failed to bind to agl_shell (bound_fail)"; +} + +#ifdef AGL_SHELL_APP_STATE_SINCE_VERSION +// static +void AglShellWrapper::AglAppState(void* data, + struct agl_shell*, + const char* app_id, + uint32_t state) { + AglShellWrapper* wrapper = static_cast(data); + + LOG(INFO) << "State for app " << app_id << " changed to " << state; + + if (state == AGL_SHELL_APP_STATE_STARTED) { + wrapper->SetAglActivateApp(app_id); + LOG(INFO) << "Activating app " << app_id; + } +} +#endif + +bool AglShellWrapper::WaitUntilBoundOk() { + int ret = 0; + while (ret != -1 && wait_for_bound_) { + ret = wl_display_dispatch(connection_->display()); + } + + return bound_ok_; +} + +} // namespace ui diff --git a/ui/ozone/platform/wayland/extensions/agl/host/agl_shell_wrapper.h b/ui/ozone/platform/wayland/extensions/agl/host/agl_shell_wrapper.h new file mode 100644 index 0000000000000..2ab765883057e --- /dev/null +++ b/ui/ozone/platform/wayland/extensions/agl/host/agl_shell_wrapper.h @@ -0,0 +1,62 @@ +// Copyright 2021 LG Electronics, Inc. +// +// 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. +// +// SPDX-License-Identifier: Apache-2.0 + +#ifndef UI_OZONE_PLATFORM_WAYLAND_EXTENSIONS_AGL_HOST_AGL_SHELL_WRAPPER_H_ +#define UI_OZONE_PLATFORM_WAYLAND_EXTENSIONS_AGL_HOST_AGL_SHELL_WRAPPER_H_ + +#include + +#include + +#include "ui/ozone/platform/wayland/extensions/agl/common/wayland_object_agl.h" + +namespace ui { + +class WaylandConnection; +class WaylandWindow; + +class AglShellWrapper { + public: + AglShellWrapper(agl_shell* agl_shell, WaylandConnection* wayland_connection); + AglShellWrapper(const AglShellWrapper&) = delete; + AglShellWrapper& operator=(const AglShellWrapper&) = delete; + ~AglShellWrapper(); + + void SetAglActivateApp(const std::string& app_id); + void SetAglPanel(WaylandWindow* window, uint32_t edge); + void SetAglBackground(WaylandWindow* window); + void SetAglReady(); + bool WaitUntilBoundOk(); + + static void AglShellBoundOk(void* data, struct agl_shell*); + static void AglShellBoundFail(void* data, struct agl_shell*); +#ifdef AGL_SHELL_APP_STATE_SINCE_VERSION + static void AglAppState(void* data, + struct agl_shell*, + const char* app_id, + uint32_t state); +#endif + + private: + wl::Object agl_shell_; + WaylandConnection* connection_; + bool wait_for_bound_ = true; + bool bound_ok_ = false; +}; + +} // namespace ui + +#endif // UI_OZONE_PLATFORM_WAYLAND_EXTENSIONS_AGL_HOST_AGL_SHELL_WRAPPER_H_ diff --git a/ui/ozone/platform/wayland/extensions/agl/host/wayland_extensions_agl.h b/ui/ozone/platform/wayland/extensions/agl/host/wayland_extensions_agl.h new file mode 100644 index 0000000000000..df42fc00c84da --- /dev/null +++ b/ui/ozone/platform/wayland/extensions/agl/host/wayland_extensions_agl.h @@ -0,0 +1,37 @@ +// Copyright 2021 LG Electronics, Inc. +// +// 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. +// +// SPDX-License-Identifier: Apache-2.0 + +#ifndef UI_OZONE_PLATFORM_WAYLAND_EXTENSIONS_AGL_HOST_WAYLAND_EXTENSIONS_AGL_H_ +#define UI_OZONE_PLATFORM_WAYLAND_EXTENSIONS_AGL_HOST_WAYLAND_EXTENSIONS_AGL_H_ + +namespace ui { + +class AglShellWrapper; + +// AGL extensions implementation for webOS/Lite +class WaylandExtensionsAgl { + public: + WaylandExtensionsAgl() = default; + WaylandExtensionsAgl(const WaylandExtensionsAgl&) = delete; + WaylandExtensionsAgl& operator=(const WaylandExtensionsAgl&) = delete; + virtual ~WaylandExtensionsAgl() = default; + + virtual AglShellWrapper* GetAglShell() = 0; +}; + +} // namespace ui + +#endif // UI_OZONE_PLATFORM_WAYLAND_EXTENSIONS_AGL_HOST_WAYLAND_EXTENSIONS_AGL_H_ \ No newline at end of file diff --git a/ui/ozone/platform/wayland/extensions/agl/host/wayland_extensions_agl_impl.cc b/ui/ozone/platform/wayland/extensions/agl/host/wayland_extensions_agl_impl.cc new file mode 100644 index 0000000000000..26a5f0550c302 --- /dev/null +++ b/ui/ozone/platform/wayland/extensions/agl/host/wayland_extensions_agl_impl.cc @@ -0,0 +1,93 @@ +// Copyright 2021 LG Electronics, Inc. +// +// 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. +// +// SPDX-License-Identifier: Apache-2.0 + +#include "ui/ozone/platform/wayland/extensions/agl/host/wayland_extensions_agl_impl.h" + +#include + +#include "base/command_line.h" +#include "base/logging.h" +#include "ui/base/ui_base_switches.h" +#include "ui/ozone/platform/wayland/extensions/agl/host/agl_shell_wrapper.h" +#include "ui/ozone/platform/wayland/extensions/agl/common/wayland_object_agl.h" +#include "ui/ozone/platform/wayland/host/wayland_connection.h" + +namespace ui { + +namespace { + +constexpr uint32_t kMinAglShellExtensionVersion = 1; +constexpr uint32_t kMaxAglShellExtensionVersion = 3; + +} // namespace + +WaylandExtensionsAglImpl::WaylandExtensionsAglImpl( + WaylandConnection* connection) + : connection_(connection) {} + +WaylandExtensionsAglImpl::~WaylandExtensionsAglImpl() = default; + +bool WaylandExtensionsAglImpl::Bind(wl_registry* registry, + uint32_t name, + const char* interface, + uint32_t version) { + bool should_use_agl_shell = base::CommandLine::ForCurrentProcess()->HasSwitch( + switches::kAglShellAppId); + bool can_bind = wl::CanBind(interface, version, kMinAglShellExtensionVersion, + kMaxAglShellExtensionVersion); + bool is_agl_shell_interface = (strcmp(interface, "agl_shell") == 0); + + if (!is_agl_shell_interface) { + return false; + } + + LOG(INFO) << "should_use_agl_shell: " << should_use_agl_shell << + " can_bind: " << can_bind; + + if (should_use_agl_shell && !agl_shell_ && + is_agl_shell_interface && can_bind) { + wl::Object aglshell = wl::Bind( + registry, name, std::min(version, kMaxAglShellExtensionVersion)); + if (!aglshell) { + LOG(ERROR) << "Failed to bind to agl_shell global"; + return false; + } + agl_shell_ = + std::make_unique(aglshell.release(), connection_); + + LOG(INFO) << "Waiting until bound..."; + return agl_shell_->WaitUntilBoundOk(); + } else { + LOG(INFO) << "Cant bind."; + } + + return false; +} + +bool WaylandExtensionsAglImpl::HasShellObject() const { + return !!agl_shell_; +} + +AglShellWrapper* WaylandExtensionsAglImpl::GetAglShell() { + return agl_shell_.get(); +} + +std::unique_ptr CreateWaylandExtensions( + WaylandConnection* connection) { + return std::make_unique(connection); +} + +} // namespace ui diff --git a/ui/ozone/platform/wayland/extensions/agl/host/wayland_extensions_agl_impl.h b/ui/ozone/platform/wayland/extensions/agl/host/wayland_extensions_agl_impl.h new file mode 100644 index 0000000000000..f6cbabe99ed0b --- /dev/null +++ b/ui/ozone/platform/wayland/extensions/agl/host/wayland_extensions_agl_impl.h @@ -0,0 +1,54 @@ +// Copyright 2021 LG Electronics, Inc. +// +// 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. +// +// SPDX-License-Identifier: Apache-2.0 + +#ifndef UI_OZONE_PLATFORM_WAYLAND_EXTENSIONS_AGL_HOST_WAYLAND_EXTENSIONS_AGL_IMPL_H_ +#define UI_OZONE_PLATFORM_WAYLAND_EXTENSIONS_AGL_HOST_WAYLAND_EXTENSIONS_AGL_IMPL_H_ + +#include "ui/ozone/platform/wayland/extensions/agl/host/wayland_extensions_agl.h" +#include "ui/ozone/platform/wayland/host/wayland_extensions.h" + +namespace ui { + +class AglShellWrapper; + +// AGL extension implementation for webOS/Lite +class WaylandExtensionsAglImpl : public WaylandExtensions, + public WaylandExtensionsAgl { + public: + explicit WaylandExtensionsAglImpl(WaylandConnection* connection); + WaylandExtensionsAglImpl(const WaylandExtensionsAglImpl&) = delete; + WaylandExtensionsAglImpl& operator=(const WaylandExtensionsAglImpl&) = delete; + ~WaylandExtensionsAglImpl() override; + + // WaylandExtensions overrides + bool Bind(wl_registry* registry, + uint32_t name, + const char* interface, + uint32_t version) override; + + bool HasShellObject() const override; + + // WaylandExtensionsAgl overrides + AglShellWrapper* GetAglShell() override; + + private: + std::unique_ptr agl_shell_; + WaylandConnection* connection_; +}; + +} // namespace ui + +#endif // UI_OZONE_PLATFORM_WAYLAND_EXTENSIONS_AGL_HOST_WAYLAND_EXTENSIONS_AGL_IMPL_H_ diff --git a/ui/ozone/platform/wayland/extensions/agl/protocol/agl-shell.xml b/ui/ozone/platform/wayland/extensions/agl/protocol/agl-shell.xml new file mode 100644 index 0000000000000..ad5553d61f189 --- /dev/null +++ b/ui/ozone/platform/wayland/extensions/agl/protocol/agl-shell.xml @@ -0,0 +1,179 @@ + + + + Copyright © 2019, 2022 Collabora, Ltd. + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice (including the next + paragraph) shall be included in all copies or substantial portions of the + Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. + + + + Starting with version 2 of the protocol, the client is required to wait + for the 'bound_ok' or 'bound_fail' events in order to proceed further. + + In case the client gets a 'bound_fail' event then it should consider that + there's another client already bound to the agl_shell protocol. + A client that receives a 'bound_ok' event should consider that there's + no other client already bound to the interface and can proceed further. + + If the client uses an older version of the protocol it will receive + automatically an error and the compositor will terminate the connection, + if there's another client already bound the interface. + + If the client receives the 'bound_fail' event and attempts to use the + interface further it will receive an error and the compositor will + terminate the connection. After the 'bound_fail' event was received the + client should call the destructor, which has been added with version 2 + of the protocol. The client is free to try at a later point in time to + see if it will receive the 'bound_ok' event, but there's no explicit way + of finding out when that event will be delivered. + It is assumed that it can infer that information through other + means/other channels. + + + + + + + + + + + + + + + + + + + + + + + + + Tell the server that this client is ready to be shown. The server + will delay presentation during start-up until all shell clients are + ready to be shown, and will display a black screen instead. + This gives the client an opportunity to set up and configure several + surfaces into a coherent interface. + + The client that binds to this interface must send this request, otherwise + they may stall the compositor unnecessarily. + + If this request is called after the compositor has already finished + start-up, no operation is performed. + + + + + + Set the surface to act as the background of an output. After this + request, the server will immediately send a configure event with + the dimensions the client should use to cover the entire output. + + The surface must have a "desktop" surface role, as supported by + libweston-desktop. + + Only a single surface may be the background for any output. If a + background surface already exists, a protocol error is raised. + + + + + + + + Set the surface to act as a panel of an output. The 'edge' argument + says what edge of the output the surface will be anchored to. + After this request, the server will send a configure event with the + corresponding width/height that the client should use, and 0 for the + other dimension. E.g. if the edge is 'top', the width will be the + output's width, and the height will be 0. + + The surface must have a "desktop" surface role, as supported by + libweston-desktop. + + The compositor will take the panel's window geometry into account when + positioning other windows, so the panels are not covered. + + XXX: What happens if e.g. both top and left are used at the same time? + Who gets to have the corner? + + Only a single surface may be the panel for an output's edge. If a + surface already exists on an edge, a protocol error is raised. + + + + + + + + + Ask the compositor to make a toplevel to become the current/focused + window for window management purposes. + + See xdg_toplevel.set_app_id from the xdg-shell protocol for a + description of app_id. + + If multiple toplevels have the same app_id, the result is unspecified. + + XXX: Do we need feedback to say it didn't work? (e.g. client does + not exist) + + + + + + + + Informs the client that it was able to bind the agl_shell + interface succesfully. Clients are required to wait for this + event before continuing further. + + + + + + Informs the client that binding to the agl_shell interface was + unsuccesfull. Clients are required to wait for this event for + continuing further. + + + + + + + + + + + Informs the client that an application has changed its state to another, + specified by the app_state enum. Client can use this event to track + current application state. For instance to know when the application has + started, or when terminated/stopped. + + + + + + + + diff --git a/ui/ozone/platform/wayland/host/wayland_connection.cc b/ui/ozone/platform/wayland/host/wayland_connection.cc index ad3bbd6e37157..7a47d4a636998 100644 --- a/ui/ozone/platform/wayland/host/wayland_connection.cc +++ b/ui/ozone/platform/wayland/host/wayland_connection.cc @@ -68,6 +68,8 @@ #include "ui/ozone/platform/wayland/host/zwp_primary_selection_device_manager.h" #include "ui/platform_window/common/platform_window_defaults.h" +#include "ui/ozone/platform/wayland/host/wayland_extensions.h" + namespace ui { namespace { @@ -212,6 +214,10 @@ bool WaylandConnection::Initialize(bool use_threaded_polling) { use_threaded_polling = false; } + if (!extensions_) { + extensions_ = CreateWaylandExtensions(this); + } + // Now that the connection with the display server has been properly // estabilished, initialize the event source and input objects. DCHECK(!event_source_); @@ -243,7 +249,7 @@ bool WaylandConnection::Initialize(bool use_threaded_polling) { LOG(ERROR) << "No wl_shm object"; return false; } - if (!shell_) { + if (!shell_ && !(extensions_ && extensions_->HasShellObject())) { LOG(ERROR) << "No Wayland shell found"; return false; } @@ -538,7 +544,9 @@ void WaylandConnection::HandleGlobal(wl_registry* registry, const char* interface, uint32_t version) { auto factory_it = global_object_factories_.find(interface); - if (factory_it != global_object_factories_.end()) { + if (extensions_->Bind(registry, name, interface, version)) { + DVLOG(1) << "Successfully bound to " << interface; + } else if (factory_it != global_object_factories_.end()) { (*factory_it->second)(this, registry, name, interface, version); } else if (!compositor_ && strcmp(interface, "wl_compositor") == 0) { compositor_ = wl::Bind( diff --git a/ui/ozone/platform/wayland/host/wayland_connection.h b/ui/ozone/platform/wayland/host/wayland_connection.h index 6659bc54bd475..ba293e5bcd088 100644 --- a/ui/ozone/platform/wayland/host/wayland_connection.h +++ b/ui/ozone/platform/wayland/host/wayland_connection.h @@ -50,6 +50,7 @@ class WaylandBufferManagerHost; class WaylandCursor; class WaylandCursorBufferListener; class WaylandEventSource; +class WaylandExtensions; class WaylandOutputManager; class WaylandSeat; class WaylandZAuraShell; @@ -201,6 +202,8 @@ class WaylandConnection { WaylandZAuraShell* zaura_shell() const { return zaura_shell_.get(); } + WaylandExtensions* extensions() { return extensions_.get(); } + WaylandZcrColorManager* zcr_color_manager() const { return zcr_color_manager_.get(); } @@ -486,6 +489,7 @@ class WaylandConnection { std::unique_ptr overlay_prioritizer_; std::unique_ptr surface_augmenter_; std::unique_ptr single_pixel_buffer_; + std::unique_ptr extensions_; // Clipboard-related objects. |clipboard_| must be declared after all // DeviceManager instances it depends on, otherwise tests may crash with diff --git a/ui/ozone/platform/wayland/host/wayland_extensions.h b/ui/ozone/platform/wayland/host/wayland_extensions.h new file mode 100644 index 0000000000000..3bd2fd7a211ae --- /dev/null +++ b/ui/ozone/platform/wayland/host/wayland_extensions.h @@ -0,0 +1,56 @@ +// Copyright 2019 LG Electronics, Inc. +// +// 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. +// +// SPDX-License-Identifier: Apache-2.0 + +#ifndef UI_OZONE_PLATFORM_WAYLAND_HOST_WAYLAND_EXTENSIONS_H_ +#define UI_OZONE_PLATFORM_WAYLAND_HOST_WAYLAND_EXTENSIONS_H_ + +#include + +#include "ui/ozone/platform/wayland/common/wayland_object.h" + +namespace ui { + +class ShellToplevelWrapper; +class ShellPopupWrapper; +class WaylandConnection; + +// Wayland extensions abstract interface to support extending of the Wayland +// protocol. Inherit it to provide your own Wayland extensions implementation. +class WaylandExtensions { + public: + WaylandExtensions() = default; + WaylandExtensions(const WaylandExtensions&) = delete; + WaylandExtensions& operator=(const WaylandExtensions&) = delete; + virtual ~WaylandExtensions() = default; + + // Binds to the extensions interface(s). Can encapsulate binding of several + // interfaces, defined by |interface|. + virtual bool Bind(wl_registry* registry, + uint32_t name, + const char* interface, + uint32_t version) = 0; + + // Checks whether the extensions have bound shell object(s). + virtual bool HasShellObject() const = 0; +}; + +// Creates Wayland extensions. +std::unique_ptr CreateWaylandExtensions( + WaylandConnection* connection); + +} // namespace ui + +#endif // UI_OZONE_PLATFORM_WAYLAND_HOST_WAYLAND_EXTENSIONS_H_ -- 2.42.1