1 From 7e927a21ecaa70c14873d5f06667dfc3bdaa4d25 Mon Sep 17 00:00:00 2001
2 From: Roger Zanoni <rzanoni@igalia.com>
3 Date: Mon, 15 May 2023 20:32:06 +0200
4 Subject: [PATCH 5/9] Add the essential parts of wayland extensions and
8 ui/base/ui_base_switches.cc | 2 +
9 ui/base/ui_base_switches.h | 3 +
10 ui/ozone/platform/wayland/BUILD.gn | 7 +
11 .../platform/wayland/extensions/agl/BUILD.gn | 40 ++++
12 .../agl/common/wayland_object_agl.cc | 26 +++
13 .../agl/common/wayland_object_agl.h | 34 ++++
14 .../extensions/agl/host/agl_shell_wrapper.cc | 113 +++++++++++
15 .../extensions/agl/host/agl_shell_wrapper.h | 62 ++++++
16 .../agl/host/wayland_extensions_agl.h | 37 ++++
17 .../agl/host/wayland_extensions_agl_impl.cc | 93 +++++++++
18 .../agl/host/wayland_extensions_agl_impl.h | 54 ++++++
19 .../extensions/agl/protocol/agl-shell.xml | 179 ++++++++++++++++++
20 .../wayland/host/wayland_connection.cc | 12 +-
21 .../wayland/host/wayland_connection.h | 6 +
22 .../wayland/host/wayland_extensions.h | 56 ++++++
23 15 files changed, 722 insertions(+), 2 deletions(-)
24 create mode 100644 ui/ozone/platform/wayland/extensions/agl/BUILD.gn
25 create mode 100644 ui/ozone/platform/wayland/extensions/agl/common/wayland_object_agl.cc
26 create mode 100644 ui/ozone/platform/wayland/extensions/agl/common/wayland_object_agl.h
27 create mode 100644 ui/ozone/platform/wayland/extensions/agl/host/agl_shell_wrapper.cc
28 create mode 100644 ui/ozone/platform/wayland/extensions/agl/host/agl_shell_wrapper.h
29 create mode 100644 ui/ozone/platform/wayland/extensions/agl/host/wayland_extensions_agl.h
30 create mode 100644 ui/ozone/platform/wayland/extensions/agl/host/wayland_extensions_agl_impl.cc
31 create mode 100644 ui/ozone/platform/wayland/extensions/agl/host/wayland_extensions_agl_impl.h
32 create mode 100644 ui/ozone/platform/wayland/extensions/agl/protocol/agl-shell.xml
33 create mode 100644 ui/ozone/platform/wayland/host/wayland_extensions.h
35 diff --git a/ui/base/ui_base_switches.cc b/ui/base/ui_base_switches.cc
36 index f8556679a79d8..e72ae83737c04 100644
37 --- a/ui/base/ui_base_switches.cc
38 +++ b/ui/base/ui_base_switches.cc
39 @@ -100,4 +100,6 @@ const char kUIDisablePartialSwap[] = "ui-disable-partial-swap";
40 // Enables the ozone x11 clipboard for linux-chromeos.
41 const char kUseSystemClipboard[] = "use-system-clipboard";
43 +const char kAglShellAppId[] = "agl-shell-appid";
45 } // namespace switches
46 diff --git a/ui/base/ui_base_switches.h b/ui/base/ui_base_switches.h
47 index d35e544f2bc2f..019ba0e5151e5 100644
48 --- a/ui/base/ui_base_switches.h
49 +++ b/ui/base/ui_base_switches.h
50 @@ -45,6 +45,9 @@ COMPONENT_EXPORT(UI_BASE) extern const char kTopChromeTouchUiEnabled[];
51 COMPONENT_EXPORT(UI_BASE) extern const char kUIDisablePartialSwap[];
52 COMPONENT_EXPORT(UI_BASE) extern const char kUseSystemClipboard[];
55 +COMPONENT_EXPORT(UI_BASE) extern const char kAglShellAppId[];
58 COMPONENT_EXPORT(UI_BASE) extern const char kDisallowNonExactResourceReuse[];
59 COMPONENT_EXPORT(UI_BASE) extern const char kMangleLocalizedStrings[];
60 diff --git a/ui/ozone/platform/wayland/BUILD.gn b/ui/ozone/platform/wayland/BUILD.gn
61 index e0f0d7dea3747..1a2f889dc8947 100644
62 --- a/ui/ozone/platform/wayland/BUILD.gn
63 +++ b/ui/ozone/platform/wayland/BUILD.gn
64 @@ -407,6 +407,13 @@ source_set("wayland") {
69 + "host/wayland_extensions.h",
70 + "host/wayland_extensions_stub.cc",
73 + deps += [ "extensions/agl" ]
75 configs += [ "//third_party/khronos:khronos_headers" ]
78 diff --git a/ui/ozone/platform/wayland/extensions/agl/BUILD.gn b/ui/ozone/platform/wayland/extensions/agl/BUILD.gn
80 index 0000000000000..ce289bc5dbbca
82 +++ b/ui/ozone/platform/wayland/extensions/agl/BUILD.gn
84 +# Copyright 2021 LG Electronics, Inc.
86 +# Licensed under the Apache License, Version 2.0 (the "License");
87 +# you may not use this file except in compliance with the License.
88 +# You may obtain a copy of the License at
90 +# http://www.apache.org/licenses/LICENSE-2.0
92 +# Unless required by applicable law or agreed to in writing, software
93 +# distributed under the License is distributed on an "AS IS" BASIS,
94 +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
95 +# See the License for the specific language governing permissions and
96 +# limitations under the License.
98 +# SPDX-License-Identifier: Apache-2.0
100 +import("//third_party/wayland/wayland_protocol.gni")
102 +visibility = [ "//ui/ozone/*" ]
104 +wayland_protocol("agl_shell_protocol") {
105 + sources = [ "protocol/agl-shell.xml" ]
110 + "common/wayland_object_agl.cc",
111 + "common/wayland_object_agl.h",
112 + "host/agl_shell_wrapper.cc",
113 + "host/agl_shell_wrapper.h",
114 + "host/wayland_extensions_agl.h",
115 + "host/wayland_extensions_agl_impl.cc",
116 + "host/wayland_extensions_agl_impl.h",
120 + ":agl_shell_protocol",
121 + "//ui/ozone/platform/wayland/mojom",
124 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
126 index 0000000000000..9f3300766df2c
128 +++ b/ui/ozone/platform/wayland/extensions/agl/common/wayland_object_agl.cc
130 +// Copyright 2021 LG Electronics, Inc.
132 +// Licensed under the Apache License, Version 2.0 (the "License");
133 +// you may not use this file except in compliance with the License.
134 +// You may obtain a copy of the License at
136 +// http://www.apache.org/licenses/LICENSE-2.0
138 +// Unless required by applicable law or agreed to in writing, software
139 +// distributed under the License is distributed on an "AS IS" BASIS,
140 +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
141 +// See the License for the specific language governing permissions and
142 +// limitations under the License.
144 +// SPDX-License-Identifier: Apache-2.0
146 +#include "ui/ozone/platform/wayland/extensions/agl/common/wayland_object_agl.h"
148 +#include <agl-shell-client-protocol.h>
152 +const wl_interface* ObjectTraits<agl_shell>::interface = &agl_shell_interface;
153 +void (*ObjectTraits<agl_shell>::deleter)(agl_shell*) = &agl_shell_destroy;
156 \ No newline at end of file
157 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
159 index 0000000000000..e91ac0da8d2fc
161 +++ b/ui/ozone/platform/wayland/extensions/agl/common/wayland_object_agl.h
163 +// Copyright 2021 LG Electronics, Inc.
165 +// Licensed under the Apache License, Version 2.0 (the "License");
166 +// you may not use this file except in compliance with the License.
167 +// You may obtain a copy of the License at
169 +// http://www.apache.org/licenses/LICENSE-2.0
171 +// Unless required by applicable law or agreed to in writing, software
172 +// distributed under the License is distributed on an "AS IS" BASIS,
173 +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
174 +// See the License for the specific language governing permissions and
175 +// limitations under the License.
177 +// SPDX-License-Identifier: Apache-2.0
179 +#ifndef UI_OZONE_PLATFORM_WAYLAND_EXTENSIONS_AGL_COMMON_WAYLAND_OBJECT_AGL_H_
180 +#define UI_OZONE_PLATFORM_WAYLAND_EXTENSIONS_AGL_COMMON_WAYLAND_OBJECT_AGL_H_
182 +#include "ui/ozone/platform/wayland/common/wayland_object.h"
189 +struct ObjectTraits<agl_shell> {
190 + static const wl_interface* interface;
191 + static void (*deleter)(agl_shell*);
196 +#endif // UI_OZONE_PLATFORM_WAYLAND_EXTENSIONS_AGL_COMMON_WAYLAND_OBJECT_AGL_H_
197 \ No newline at end of file
198 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
200 index 0000000000000..c74fa5d9cd221
202 +++ b/ui/ozone/platform/wayland/extensions/agl/host/agl_shell_wrapper.cc
204 +// Copyright 2021 LG Electronics, Inc.
206 +// Licensed under the Apache License, Version 2.0 (the "License");
207 +// you may not use this file except in compliance with the License.
208 +// You may obtain a copy of the License at
210 +// http://www.apache.org/licenses/LICENSE-2.0
212 +// Unless required by applicable law or agreed to in writing, software
213 +// distributed under the License is distributed on an "AS IS" BASIS,
214 +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
215 +// See the License for the specific language governing permissions and
216 +// limitations under the License.
218 +// SPDX-License-Identifier: Apache-2.0
220 +#include "ui/ozone/platform/wayland/extensions/agl/host/agl_shell_wrapper.h"
222 +#include "agl_shell_wrapper.h"
223 +#include "base/logging.h"
224 +#include "ui/base/ui_base_switches.h"
225 +#include "ui/ozone/platform/wayland/host/wayland_connection.h"
226 +#include "ui/ozone/platform/wayland/host/wayland_output_manager.h"
227 +#include "ui/ozone/platform/wayland/host/wayland_window.h"
231 +static const struct agl_shell_listener shell_listener = {
232 + &AglShellWrapper::AglShellBoundOk,
233 + &AglShellWrapper::AglShellBoundFail,
234 +#ifdef AGL_SHELL_APP_STATE_SINCE_VERSION
235 + &AglShellWrapper::AglAppState,
239 +AglShellWrapper::AglShellWrapper(agl_shell* agl_shell,
240 + WaylandConnection* wayland_connection)
241 + : agl_shell_(agl_shell), connection_(wayland_connection) {
242 + if (wl::get_version_of_object(agl_shell) >= AGL_SHELL_BOUND_OK_SINCE_VERSION)
243 + agl_shell_add_listener(agl_shell, &shell_listener, this);
246 +AglShellWrapper::~AglShellWrapper() = default;
248 +void AglShellWrapper::SetAglActivateApp(const std::string& app_id) {
249 + wl_output* output =
250 + connection_->wayland_output_manager()->GetPrimaryOutput()->get_output();
251 + agl_shell_activate_app(agl_shell_.get(), app_id.c_str(), output);
254 +void AglShellWrapper::SetAglPanel(WaylandWindow* window, uint32_t edge) {
255 + wl_surface* surface = window->root_surface()->surface();
256 + wl_output* output =
257 + connection_->wayland_output_manager()->GetPrimaryOutput()->get_output();
259 + agl_shell_set_panel(agl_shell_.get(), surface, output, edge);
262 +void AglShellWrapper::SetAglBackground(WaylandWindow* window) {
263 + wl_surface* surface = window->root_surface()->surface();
264 + wl_output* output =
265 + connection_->wayland_output_manager()->GetPrimaryOutput()->get_output();
267 + agl_shell_set_background(agl_shell_.get(), surface, output);
270 +void AglShellWrapper::SetAglReady() {
271 + agl_shell_ready(agl_shell_.get());
275 +void AglShellWrapper::AglShellBoundOk(void* data, struct agl_shell*) {
276 + AglShellWrapper* wrapper = static_cast<AglShellWrapper*>(data);
277 + wrapper->wait_for_bound_ = false;
278 + wrapper->bound_ok_ = true;
279 + LOG(INFO) << "Bound to agl_shell (bound_ok)";
283 +void AglShellWrapper::AglShellBoundFail(void* data, struct agl_shell*) {
284 + AglShellWrapper* wrapper = static_cast<AglShellWrapper*>(data);
285 + wrapper->wait_for_bound_ = false;
286 + wrapper->bound_ok_ = false;
287 + LOG(INFO) << "Failed to bind to agl_shell (bound_fail)";
290 +#ifdef AGL_SHELL_APP_STATE_SINCE_VERSION
292 +void AglShellWrapper::AglAppState(void* data,
294 + const char* app_id,
296 + AglShellWrapper* wrapper = static_cast<AglShellWrapper*>(data);
298 + LOG(INFO) << "State for app " << app_id << " changed to " << state;
300 + if (state == AGL_SHELL_APP_STATE_STARTED) {
301 + wrapper->SetAglActivateApp(app_id);
302 + LOG(INFO) << "Activating app " << app_id;
307 +bool AglShellWrapper::WaitUntilBoundOk() {
309 + while (ret != -1 && wait_for_bound_) {
310 + ret = wl_display_dispatch(connection_->display());
317 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
319 index 0000000000000..2ab765883057e
321 +++ b/ui/ozone/platform/wayland/extensions/agl/host/agl_shell_wrapper.h
323 +// Copyright 2021 LG Electronics, Inc.
325 +// Licensed under the Apache License, Version 2.0 (the "License");
326 +// you may not use this file except in compliance with the License.
327 +// You may obtain a copy of the License at
329 +// http://www.apache.org/licenses/LICENSE-2.0
331 +// Unless required by applicable law or agreed to in writing, software
332 +// distributed under the License is distributed on an "AS IS" BASIS,
333 +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
334 +// See the License for the specific language governing permissions and
335 +// limitations under the License.
337 +// SPDX-License-Identifier: Apache-2.0
339 +#ifndef UI_OZONE_PLATFORM_WAYLAND_EXTENSIONS_AGL_HOST_AGL_SHELL_WRAPPER_H_
340 +#define UI_OZONE_PLATFORM_WAYLAND_EXTENSIONS_AGL_HOST_AGL_SHELL_WRAPPER_H_
344 +#include <agl-shell-client-protocol.h>
346 +#include "ui/ozone/platform/wayland/extensions/agl/common/wayland_object_agl.h"
350 +class WaylandConnection;
351 +class WaylandWindow;
353 +class AglShellWrapper {
355 + AglShellWrapper(agl_shell* agl_shell, WaylandConnection* wayland_connection);
356 + AglShellWrapper(const AglShellWrapper&) = delete;
357 + AglShellWrapper& operator=(const AglShellWrapper&) = delete;
358 + ~AglShellWrapper();
360 + void SetAglActivateApp(const std::string& app_id);
361 + void SetAglPanel(WaylandWindow* window, uint32_t edge);
362 + void SetAglBackground(WaylandWindow* window);
363 + void SetAglReady();
364 + bool WaitUntilBoundOk();
366 + static void AglShellBoundOk(void* data, struct agl_shell*);
367 + static void AglShellBoundFail(void* data, struct agl_shell*);
368 +#ifdef AGL_SHELL_APP_STATE_SINCE_VERSION
369 + static void AglAppState(void* data,
371 + const char* app_id,
376 + wl::Object<agl_shell> agl_shell_;
377 + WaylandConnection* connection_;
378 + bool wait_for_bound_ = true;
379 + bool bound_ok_ = false;
384 +#endif // UI_OZONE_PLATFORM_WAYLAND_EXTENSIONS_AGL_HOST_AGL_SHELL_WRAPPER_H_
385 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
387 index 0000000000000..df42fc00c84da
389 +++ b/ui/ozone/platform/wayland/extensions/agl/host/wayland_extensions_agl.h
391 +// Copyright 2021 LG Electronics, Inc.
393 +// Licensed under the Apache License, Version 2.0 (the "License");
394 +// you may not use this file except in compliance with the License.
395 +// You may obtain a copy of the License at
397 +// http://www.apache.org/licenses/LICENSE-2.0
399 +// Unless required by applicable law or agreed to in writing, software
400 +// distributed under the License is distributed on an "AS IS" BASIS,
401 +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
402 +// See the License for the specific language governing permissions and
403 +// limitations under the License.
405 +// SPDX-License-Identifier: Apache-2.0
407 +#ifndef UI_OZONE_PLATFORM_WAYLAND_EXTENSIONS_AGL_HOST_WAYLAND_EXTENSIONS_AGL_H_
408 +#define UI_OZONE_PLATFORM_WAYLAND_EXTENSIONS_AGL_HOST_WAYLAND_EXTENSIONS_AGL_H_
412 +class AglShellWrapper;
414 +// AGL extensions implementation for webOS/Lite
415 +class WaylandExtensionsAgl {
417 + WaylandExtensionsAgl() = default;
418 + WaylandExtensionsAgl(const WaylandExtensionsAgl&) = delete;
419 + WaylandExtensionsAgl& operator=(const WaylandExtensionsAgl&) = delete;
420 + virtual ~WaylandExtensionsAgl() = default;
422 + virtual AglShellWrapper* GetAglShell() = 0;
427 +#endif // UI_OZONE_PLATFORM_WAYLAND_EXTENSIONS_AGL_HOST_WAYLAND_EXTENSIONS_AGL_H_
428 \ No newline at end of file
429 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
431 index 0000000000000..26a5f0550c302
433 +++ b/ui/ozone/platform/wayland/extensions/agl/host/wayland_extensions_agl_impl.cc
435 +// Copyright 2021 LG Electronics, Inc.
437 +// Licensed under the Apache License, Version 2.0 (the "License");
438 +// you may not use this file except in compliance with the License.
439 +// You may obtain a copy of the License at
441 +// http://www.apache.org/licenses/LICENSE-2.0
443 +// Unless required by applicable law or agreed to in writing, software
444 +// distributed under the License is distributed on an "AS IS" BASIS,
445 +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
446 +// See the License for the specific language governing permissions and
447 +// limitations under the License.
449 +// SPDX-License-Identifier: Apache-2.0
451 +#include "ui/ozone/platform/wayland/extensions/agl/host/wayland_extensions_agl_impl.h"
455 +#include "base/command_line.h"
456 +#include "base/logging.h"
457 +#include "ui/base/ui_base_switches.h"
458 +#include "ui/ozone/platform/wayland/extensions/agl/host/agl_shell_wrapper.h"
459 +#include "ui/ozone/platform/wayland/extensions/agl/common/wayland_object_agl.h"
460 +#include "ui/ozone/platform/wayland/host/wayland_connection.h"
466 +constexpr uint32_t kMinAglShellExtensionVersion = 1;
467 +constexpr uint32_t kMaxAglShellExtensionVersion = 3;
471 +WaylandExtensionsAglImpl::WaylandExtensionsAglImpl(
472 + WaylandConnection* connection)
473 + : connection_(connection) {}
475 +WaylandExtensionsAglImpl::~WaylandExtensionsAglImpl() = default;
477 +bool WaylandExtensionsAglImpl::Bind(wl_registry* registry,
479 + const char* interface,
480 + uint32_t version) {
481 + bool should_use_agl_shell = base::CommandLine::ForCurrentProcess()->HasSwitch(
482 + switches::kAglShellAppId);
483 + bool can_bind = wl::CanBind(interface, version, kMinAglShellExtensionVersion,
484 + kMaxAglShellExtensionVersion);
485 + bool is_agl_shell_interface = (strcmp(interface, "agl_shell") == 0);
487 + if (!is_agl_shell_interface) {
491 + LOG(INFO) << "should_use_agl_shell: " << should_use_agl_shell <<
492 + " can_bind: " << can_bind;
494 + if (should_use_agl_shell && !agl_shell_ &&
495 + is_agl_shell_interface && can_bind) {
496 + wl::Object<agl_shell> aglshell = wl::Bind<agl_shell>(
497 + registry, name, std::min(version, kMaxAglShellExtensionVersion));
499 + LOG(ERROR) << "Failed to bind to agl_shell global";
503 + std::make_unique<AglShellWrapper>(aglshell.release(), connection_);
505 + LOG(INFO) << "Waiting until bound...";
506 + return agl_shell_->WaitUntilBoundOk();
508 + LOG(INFO) << "Cant bind.";
514 +bool WaylandExtensionsAglImpl::HasShellObject() const {
515 + return !!agl_shell_;
518 +AglShellWrapper* WaylandExtensionsAglImpl::GetAglShell() {
519 + return agl_shell_.get();
522 +std::unique_ptr<WaylandExtensions> CreateWaylandExtensions(
523 + WaylandConnection* connection) {
524 + return std::make_unique<WaylandExtensionsAglImpl>(connection);
528 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
530 index 0000000000000..f6cbabe99ed0b
532 +++ b/ui/ozone/platform/wayland/extensions/agl/host/wayland_extensions_agl_impl.h
534 +// Copyright 2021 LG Electronics, Inc.
536 +// Licensed under the Apache License, Version 2.0 (the "License");
537 +// you may not use this file except in compliance with the License.
538 +// You may obtain a copy of the License at
540 +// http://www.apache.org/licenses/LICENSE-2.0
542 +// Unless required by applicable law or agreed to in writing, software
543 +// distributed under the License is distributed on an "AS IS" BASIS,
544 +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
545 +// See the License for the specific language governing permissions and
546 +// limitations under the License.
548 +// SPDX-License-Identifier: Apache-2.0
550 +#ifndef UI_OZONE_PLATFORM_WAYLAND_EXTENSIONS_AGL_HOST_WAYLAND_EXTENSIONS_AGL_IMPL_H_
551 +#define UI_OZONE_PLATFORM_WAYLAND_EXTENSIONS_AGL_HOST_WAYLAND_EXTENSIONS_AGL_IMPL_H_
553 +#include "ui/ozone/platform/wayland/extensions/agl/host/wayland_extensions_agl.h"
554 +#include "ui/ozone/platform/wayland/host/wayland_extensions.h"
558 +class AglShellWrapper;
560 +// AGL extension implementation for webOS/Lite
561 +class WaylandExtensionsAglImpl : public WaylandExtensions,
562 + public WaylandExtensionsAgl {
564 + explicit WaylandExtensionsAglImpl(WaylandConnection* connection);
565 + WaylandExtensionsAglImpl(const WaylandExtensionsAglImpl&) = delete;
566 + WaylandExtensionsAglImpl& operator=(const WaylandExtensionsAglImpl&) = delete;
567 + ~WaylandExtensionsAglImpl() override;
569 + // WaylandExtensions overrides
570 + bool Bind(wl_registry* registry,
572 + const char* interface,
573 + uint32_t version) override;
575 + bool HasShellObject() const override;
577 + // WaylandExtensionsAgl overrides
578 + AglShellWrapper* GetAglShell() override;
581 + std::unique_ptr<AglShellWrapper> agl_shell_;
582 + WaylandConnection* connection_;
587 +#endif // UI_OZONE_PLATFORM_WAYLAND_EXTENSIONS_AGL_HOST_WAYLAND_EXTENSIONS_AGL_IMPL_H_
588 diff --git a/ui/ozone/platform/wayland/extensions/agl/protocol/agl-shell.xml b/ui/ozone/platform/wayland/extensions/agl/protocol/agl-shell.xml
590 index 0000000000000..ad5553d61f189
592 +++ b/ui/ozone/platform/wayland/extensions/agl/protocol/agl-shell.xml
594 +<?xml version="1.0" encoding="UTF-8"?>
595 +<protocol name="agl_shell">
597 + Copyright © 2019, 2022 Collabora, Ltd.
599 + Permission is hereby granted, free of charge, to any person obtaining a
600 + copy of this software and associated documentation files (the "Software"),
601 + to deal in the Software without restriction, including without limitation
602 + the rights to use, copy, modify, merge, publish, distribute, sublicense,
603 + and/or sell copies of the Software, and to permit persons to whom the
604 + Software is furnished to do so, subject to the following conditions:
606 + The above copyright notice and this permission notice (including the next
607 + paragraph) shall be included in all copies or substantial portions of the
610 + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
611 + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
612 + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
613 + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
614 + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
615 + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
616 + DEALINGS IN THE SOFTWARE.
618 + <interface name="agl_shell" version="3">
619 + <description summary="user interface for Automotive Grade Linux platform">
620 + Starting with version 2 of the protocol, the client is required to wait
621 + for the 'bound_ok' or 'bound_fail' events in order to proceed further.
623 + In case the client gets a 'bound_fail' event then it should consider that
624 + there's another client already bound to the agl_shell protocol.
625 + A client that receives a 'bound_ok' event should consider that there's
626 + no other client already bound to the interface and can proceed further.
628 + If the client uses an older version of the protocol it will receive
629 + automatically an error and the compositor will terminate the connection,
630 + if there's another client already bound the interface.
632 + If the client receives the 'bound_fail' event and attempts to use the
633 + interface further it will receive an error and the compositor will
634 + terminate the connection. After the 'bound_fail' event was received the
635 + client should call the destructor, which has been added with version 2
636 + of the protocol. The client is free to try at a later point in time to
637 + see if it will receive the 'bound_ok' event, but there's no explicit way
638 + of finding out when that event will be delivered.
639 + It is assumed that it can infer that information through other
640 + means/other channels.
643 + <enum name="error">
644 + <entry name="invalid_argument" value="0"/>
645 + <entry name="background_exists" value="1"/>
646 + <entry name="panel_exists" value="2"/>
650 + <entry name="top" value="0"/>
651 + <entry name="bottom" value="1"/>
652 + <entry name="left" value="2"/>
653 + <entry name="right" value="3"/>
656 + <enum name="app_state" since="3">
657 + <entry name="started" value="0"/>
658 + <entry name="terminated" value="1"/>
659 + <entry name="activated" value="2"/>
660 + <entry name="deactivated" value="3"/>
663 + <request name="ready">
664 + <description summary="client is ready to be shown">
665 + Tell the server that this client is ready to be shown. The server
666 + will delay presentation during start-up until all shell clients are
667 + ready to be shown, and will display a black screen instead.
668 + This gives the client an opportunity to set up and configure several
669 + surfaces into a coherent interface.
671 + The client that binds to this interface must send this request, otherwise
672 + they may stall the compositor unnecessarily.
674 + If this request is called after the compositor has already finished
675 + start-up, no operation is performed.
679 + <request name="set_background">
680 + <description summary="set surface as output's background">
681 + Set the surface to act as the background of an output. After this
682 + request, the server will immediately send a configure event with
683 + the dimensions the client should use to cover the entire output.
685 + The surface must have a "desktop" surface role, as supported by
688 + Only a single surface may be the background for any output. If a
689 + background surface already exists, a protocol error is raised.
691 + <arg name="surface" type="object" interface="wl_surface"/>
692 + <arg name="output" type="object" interface="wl_output"/>
695 + <request name="set_panel">
696 + <description summary="set surface as panel">
697 + Set the surface to act as a panel of an output. The 'edge' argument
698 + says what edge of the output the surface will be anchored to.
699 + After this request, the server will send a configure event with the
700 + corresponding width/height that the client should use, and 0 for the
701 + other dimension. E.g. if the edge is 'top', the width will be the
702 + output's width, and the height will be 0.
704 + The surface must have a "desktop" surface role, as supported by
707 + The compositor will take the panel's window geometry into account when
708 + positioning other windows, so the panels are not covered.
710 + XXX: What happens if e.g. both top and left are used at the same time?
711 + Who gets to have the corner?
713 + Only a single surface may be the panel for an output's edge. If a
714 + surface already exists on an edge, a protocol error is raised.
716 + <arg name="surface" type="object" interface="wl_surface"/>
717 + <arg name="output" type="object" interface="wl_output"/>
718 + <arg name="edge" type="uint" enum="edge"/>
721 + <request name="activate_app">
722 + <description summary="make client current window">
723 + Ask the compositor to make a toplevel to become the current/focused
724 + window for window management purposes.
726 + See xdg_toplevel.set_app_id from the xdg-shell protocol for a
727 + description of app_id.
729 + If multiple toplevels have the same app_id, the result is unspecified.
731 + XXX: Do we need feedback to say it didn't work? (e.g. client does
734 + <arg name="app_id" type="string"/>
735 + <arg name="output" type="object" interface="wl_output"/>
738 + <event name="bound_ok" since="2">
739 + <description summary="event sent if binding was ok">
740 + Informs the client that it was able to bind the agl_shell
741 + interface succesfully. Clients are required to wait for this
742 + event before continuing further.
746 + <event name="bound_fail" since="2">
747 + <description summary="event sent if binding was nok">
748 + Informs the client that binding to the agl_shell interface was
749 + unsuccesfull. Clients are required to wait for this event for
750 + continuing further.
754 + <request name="destroy" type="destructor" since="2">
755 + <description summary="destroys the factory object">
759 + <event name="app_state" since="3">
760 + <description summary="event sent when an application suffered state modification">
761 + Informs the client that an application has changed its state to another,
762 + specified by the app_state enum. Client can use this event to track
763 + current application state. For instance to know when the application has
764 + started, or when terminated/stopped.
766 + <arg name="app_id" type="string"/>
767 + <arg name="state" type="uint" enum="app_state"/>
773 diff --git a/ui/ozone/platform/wayland/host/wayland_connection.cc b/ui/ozone/platform/wayland/host/wayland_connection.cc
774 index 6d44128e56458..93427c52e1284 100644
775 --- a/ui/ozone/platform/wayland/host/wayland_connection.cc
776 +++ b/ui/ozone/platform/wayland/host/wayland_connection.cc
778 #include "ui/ozone/platform/wayland/host/zwp_primary_selection_device_manager.h"
779 #include "ui/platform_window/common/platform_window_defaults.h"
781 +#include "ui/ozone/platform/wayland/host/wayland_extensions.h"
783 #if defined(USE_LIBWAYLAND_STUBS)
786 @@ -238,6 +240,10 @@ bool WaylandConnection::Initialize() {
790 + if (!extensions_) {
791 + extensions_ = CreateWaylandExtensions(this);
794 // Now that the connection with the display server has been properly
795 // estabilished, initialize the event source and input objects.
796 DCHECK(!event_source_);
797 @@ -264,7 +270,7 @@ bool WaylandConnection::Initialize() {
798 LOG(ERROR) << "No wl_shm object";
801 - if (!shell_v6_ && !shell_) {
802 + if (!shell_v6_ && !shell_ && !(extensions_ && extensions_->HasShellObject())) {
803 LOG(ERROR) << "No Wayland shell found";
806 @@ -434,7 +440,9 @@ void WaylandConnection::Global(void* data,
807 auto* connection = static_cast<WaylandConnection*>(data);
809 auto factory_it = connection->global_object_factories_.find(interface);
810 - if (factory_it != connection->global_object_factories_.end()) {
811 + if (connection->extensions_->Bind(registry, name, interface, version)) {
812 + DVLOG(1) << "Successfully bound to " << interface;
813 + } else if (factory_it != connection->global_object_factories_.end()) {
814 (*factory_it->second)(connection, registry, name, interface, version);
815 } else if (!connection->compositor_ &&
816 strcmp(interface, "wl_compositor") == 0) {
817 diff --git a/ui/ozone/platform/wayland/host/wayland_connection.h b/ui/ozone/platform/wayland/host/wayland_connection.h
818 index d33959ad4066f..dfd1d060c73f2 100644
819 --- a/ui/ozone/platform/wayland/host/wayland_connection.h
820 +++ b/ui/ozone/platform/wayland/host/wayland_connection.h
821 @@ -45,6 +45,7 @@ class WaylandBufferManagerHost;
823 class WaylandCursorBufferListener;
824 class WaylandEventSource;
825 +class WaylandExtensions;
826 class WaylandOutputManager;
828 class WaylandZAuraShell;
829 @@ -185,6 +186,8 @@ class WaylandConnection {
831 WaylandZAuraShell* zaura_shell() const { return zaura_shell_.get(); }
833 + WaylandExtensions* extensions() { return extensions_.get(); }
835 WaylandZcrColorManager* zcr_color_manager() const {
836 return zcr_color_manager_.get();
838 @@ -424,6 +427,9 @@ class WaylandConnection {
839 std::unique_ptr<OverlayPrioritizer> overlay_prioritizer_;
840 std::unique_ptr<SurfaceAugmenter> surface_augmenter_;
842 + std::unique_ptr<WaylandExtensions> extensions_;
845 // Clipboard-related objects. |clipboard_| must be declared after all
846 // DeviceManager instances it depends on, otherwise tests may crash with
847 // UAFs while attempting to access already destroyed manager pointers.
848 diff --git a/ui/ozone/platform/wayland/host/wayland_extensions.h b/ui/ozone/platform/wayland/host/wayland_extensions.h
850 index 0000000000000..3bd2fd7a211ae
852 +++ b/ui/ozone/platform/wayland/host/wayland_extensions.h
854 +// Copyright 2019 LG Electronics, Inc.
856 +// Licensed under the Apache License, Version 2.0 (the "License");
857 +// you may not use this file except in compliance with the License.
858 +// You may obtain a copy of the License at
860 +// http://www.apache.org/licenses/LICENSE-2.0
862 +// Unless required by applicable law or agreed to in writing, software
863 +// distributed under the License is distributed on an "AS IS" BASIS,
864 +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
865 +// See the License for the specific language governing permissions and
866 +// limitations under the License.
868 +// SPDX-License-Identifier: Apache-2.0
870 +#ifndef UI_OZONE_PLATFORM_WAYLAND_HOST_WAYLAND_EXTENSIONS_H_
871 +#define UI_OZONE_PLATFORM_WAYLAND_HOST_WAYLAND_EXTENSIONS_H_
875 +#include "ui/ozone/platform/wayland/common/wayland_object.h"
879 +class ShellToplevelWrapper;
880 +class ShellPopupWrapper;
881 +class WaylandConnection;
883 +// Wayland extensions abstract interface to support extending of the Wayland
884 +// protocol. Inherit it to provide your own Wayland extensions implementation.
885 +class WaylandExtensions {
887 + WaylandExtensions() = default;
888 + WaylandExtensions(const WaylandExtensions&) = delete;
889 + WaylandExtensions& operator=(const WaylandExtensions&) = delete;
890 + virtual ~WaylandExtensions() = default;
892 + // Binds to the extensions interface(s). Can encapsulate binding of several
893 + // interfaces, defined by |interface|.
894 + virtual bool Bind(wl_registry* registry,
896 + const char* interface,
897 + uint32_t version) = 0;
899 + // Checks whether the extensions have bound shell object(s).
900 + virtual bool HasShellObject() const = 0;
903 +// Creates Wayland extensions.
904 +std::unique_ptr<WaylandExtensions> CreateWaylandExtensions(
905 + WaylandConnection* connection);
909 +#endif // UI_OZONE_PLATFORM_WAYLAND_HOST_WAYLAND_EXTENSIONS_H_