| /* |
| * Copyright (C) 2019 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #include "host/libs/wayland/wayland_server.h" |
| |
| #include <android-base/logging.h> |
| |
| #include <wayland-server-core.h> |
| #include <wayland-server-protocol.h> |
| |
| #include "host/libs/wayland/wayland_compositor.h" |
| #include "host/libs/wayland/wayland_dmabuf.h" |
| #include "host/libs/wayland/wayland_seat.h" |
| #include "host/libs/wayland/wayland_shell.h" |
| #include "host/libs/wayland/wayland_subcompositor.h" |
| #include "host/libs/wayland/wayland_surface.h" |
| #include "host/libs/wayland/wayland_utils.h" |
| #include "host/libs/wayland/wayland_virtio_gpu_metadata.h" |
| |
| namespace wayland { |
| namespace internal { |
| |
| struct WaylandServerState { |
| struct wl_display* display_ = nullptr; |
| |
| Surfaces surfaces_; |
| }; |
| |
| } // namespace internal |
| |
| WaylandServer::WaylandServer(int wayland_socket_fd) { |
| server_thread_ = |
| std::thread( |
| [this, wayland_socket_fd]() { |
| ServerLoop(wayland_socket_fd); |
| }); |
| |
| std::unique_lock<std::mutex> lock(server_ready_mutex_); |
| server_ready_cv_.wait(lock, [&]{return server_ready_; }); |
| } |
| |
| WaylandServer::~WaylandServer() { |
| wl_display_terminate(server_state_->display_); |
| server_thread_.join(); |
| } |
| |
| void WaylandServer::ServerLoop(int fd) { |
| server_state_.reset(new internal::WaylandServerState()); |
| |
| server_state_->display_ = wl_display_create(); |
| CHECK(server_state_->display_ != nullptr) |
| << "Failed to start WaylandServer: failed to create display"; |
| |
| if (fd < 0) { |
| const char* socket = wl_display_add_socket_auto(server_state_->display_); |
| CHECK(socket != nullptr) |
| << "Failed to start WaylandServer: failed to create socket"; |
| |
| LOG(INFO) << "WaylandServer running on socket " << socket; |
| } else { |
| CHECK(wl_display_add_socket_fd(server_state_->display_, fd) == 0) |
| << "Failed to start WaylandServer: failed to use fd " << fd; |
| |
| LOG(INFO) << "WaylandServer running on socket " << fd; |
| } |
| |
| wl_display_init_shm(server_state_->display_); |
| |
| BindCompositorInterface(server_state_->display_, &server_state_->surfaces_); |
| BindVirtioGpuMetadataInterface(server_state_->display_, |
| &server_state_->surfaces_); |
| BindDmabufInterface(server_state_->display_); |
| BindSubcompositorInterface(server_state_->display_); |
| BindSeatInterface(server_state_->display_); |
| BindShellInterface(server_state_->display_); |
| |
| { |
| std::lock_guard<std::mutex> lock(server_ready_mutex_); |
| server_ready_ = true; |
| } |
| server_ready_cv_.notify_one(); |
| |
| wl_display_run(server_state_->display_); |
| wl_display_destroy(server_state_->display_); |
| } |
| |
| void WaylandServer::SetFrameCallback(Surfaces::FrameCallback callback) { |
| server_state_->surfaces_.SetFrameCallback(std::move(callback)); |
| } |
| |
| } // namespace wayland |