123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101 |
- // Copyright 2018 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- #include "components/exo/wayland/wayland_display_output.h"
- #include <cstring>
- #include <wayland-server-core.h>
- #include <wayland-server-protocol-core.h>
- #include "base/containers/cxx20_erase.h"
- #include "base/logging.h"
- #include "base/task/thread_pool.h"
- #include "components/exo/surface.h"
- #include "components/exo/wayland/server_util.h"
- namespace exo {
- namespace wayland {
- namespace {
- base::TimeDelta kDeleteTaskDelay = base::Seconds(3);
- void DoDelete(WaylandDisplayOutput* output, int retry_count) {
- if (retry_count > 0 && output->output_counts() > 0) {
- // Try a few times to give a client chance to release it.
- base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
- FROM_HERE, base::BindOnce(&DoDelete, output, retry_count - 1),
- kDeleteTaskDelay);
- } else {
- delete output;
- }
- }
- } // namespace
- WaylandDisplayOutput::WaylandDisplayOutput(int64_t id) : id_(id) {}
- WaylandDisplayOutput::~WaylandDisplayOutput() {
- // Empty the output_ids_ so that Unregister will be no op.
- auto ids = std::move(output_ids_);
- for (auto pair : ids)
- wl_resource_destroy(pair.second);
- if (global_)
- wl_global_destroy(global_);
- }
- void WaylandDisplayOutput::OnDisplayRemoved() {
- if (global_)
- wl_global_remove(global_);
- base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
- FROM_HERE, base::BindOnce(&DoDelete, this, /*retry_count=*/3),
- kDeleteTaskDelay);
- }
- int64_t WaylandDisplayOutput::id() const {
- return id_;
- }
- void WaylandDisplayOutput::set_global(wl_global* global) {
- global_ = global;
- }
- void WaylandDisplayOutput::UnregisterOutput(wl_resource* output_resource) {
- base::EraseIf(output_ids_, [output_resource](auto& pair) {
- return pair.second == output_resource;
- });
- }
- void WaylandDisplayOutput::RegisterOutput(wl_resource* output_resource) {
- auto* client = wl_resource_get_client(output_resource);
- output_ids_.insert(std::make_pair(client, output_resource));
- // Notify All wl surfaces that a new output was added.
- wl_client_for_each_resource(
- client,
- [](wl_resource* resource, void*) {
- constexpr char kWlSurfaceClass[] = "wl_surface";
- const char* class_name = wl_resource_get_class(resource);
- if (std::strcmp(kWlSurfaceClass, class_name) == 0) {
- auto* surface = GetUserDataAs<Surface>(resource);
- if (surface)
- surface->OnNewOutputAdded();
- }
- return WL_ITERATOR_CONTINUE;
- },
- nullptr);
- }
- wl_resource* WaylandDisplayOutput::GetOutputResourceForClient(
- wl_client* client) {
- auto iter = output_ids_.find(client);
- if (iter == output_ids_.end())
- return nullptr;
- return iter->second;
- }
- } // namespace wayland
- } // namespace exo
|