Commit a6a3384f authored by Shawn Gallea's avatar Shawn Gallea Committed by Commit Bot

Add fullscreen client

Added a sample fullscreen client. The client demonstrates usage of the
Wayland Fullscreen Shell protocol.

Does not run without server-side fullscreen shell implementation.

Bug: 896710
Test: Compiled client on ChromeOS and verified it still builds.
Change-Id: I681e864c739faafee07b257fd4c15c49929859cc
Reviewed-on: https://chromium-review.googlesource.com/c/1281424
Commit-Queue: Shawn Gallea <sagallea@google.com>
Reviewed-by: default avatarDaniele Castagna <dcastagna@chromium.org>
Reviewed-by: default avatarDaniel Nicoara <dnicoara@chromium.org>
Cr-Commit-Position: refs/heads/master@{#603146}
parent 4572662a
...@@ -135,6 +135,7 @@ source_set("client_support") { ...@@ -135,6 +135,7 @@ source_set("client_support") {
public_deps = [ public_deps = [
"//skia", "//skia",
"//third_party/wayland:wayland_client", "//third_party/wayland:wayland_client",
"//third_party/wayland-protocols:fullscreen_shell_protocol",
"//third_party/wayland-protocols:input_timestamps_protocol", "//third_party/wayland-protocols:input_timestamps_protocol",
"//third_party/wayland-protocols:linux_dmabuf_protocol", "//third_party/wayland-protocols:linux_dmabuf_protocol",
"//third_party/wayland-protocols:presentation_time_protocol", "//third_party/wayland-protocols:presentation_time_protocol",
...@@ -205,6 +206,29 @@ source_set("simple") { ...@@ -205,6 +206,29 @@ source_set("simple") {
} }
} }
source_set("fullscreen_shell") {
sources = [
"clients/fullscreen_shell.cc",
"clients/fullscreen_shell.h",
]
deps = [
":client_support",
"//base",
"//build/config/linux/libdrm",
"//skia",
"//third_party/wayland:wayland_client",
"//third_party/wayland-protocols:linux_dmabuf_protocol",
"//third_party/wayland-protocols:presentation_time_protocol",
"//ui/gfx/geometry",
"//ui/gl",
]
if (ozone_platform_gbm) {
configs += [ "//ui/gl:gl_config" ]
}
}
executable("wayland_simple_client") { executable("wayland_simple_client") {
sources = [ sources = [
"clients/simple_main.cc", "clients/simple_main.cc",
...@@ -216,6 +240,17 @@ executable("wayland_simple_client") { ...@@ -216,6 +240,17 @@ executable("wayland_simple_client") {
] ]
} }
executable("wayland_fullscreen_client") {
sources = [
"clients/fullscreen_shell_main.cc",
]
deps = [
":client_support",
":fullscreen_shell",
"//base",
]
}
executable("wayland_subsurface_client") { executable("wayland_subsurface_client") {
sources = [ sources = [
"clients/subsurface.cc", "clients/subsurface.cc",
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#include <aura-shell-client-protocol.h> #include <aura-shell-client-protocol.h>
#include <fcntl.h> #include <fcntl.h>
#include <fullscreen-shell-unstable-v1-client-protocol.h>
#include <linux-dmabuf-unstable-v1-client-protocol.h> #include <linux-dmabuf-unstable-v1-client-protocol.h>
#include <presentation-time-client-protocol.h> #include <presentation-time-client-protocol.h>
#include <wayland-client-core.h> #include <wayland-client-core.h>
...@@ -80,6 +81,10 @@ const size_t kBytesPerPixel = 4; ...@@ -80,6 +81,10 @@ const size_t kBytesPerPixel = 4;
const char kDriRenderNodeTemplate[] = "/dev/dri/renderD%u"; const char kDriRenderNodeTemplate[] = "/dev/dri/renderD%u";
#endif #endif
ClientBase* CastToClientBase(void* data) {
return static_cast<ClientBase*>(data);
}
void RegistryHandler(void* data, void RegistryHandler(void* data,
wl_registry* registry, wl_registry* registry,
uint32_t id, uint32_t id,
...@@ -115,6 +120,12 @@ void RegistryHandler(void* data, ...@@ -115,6 +120,12 @@ void RegistryHandler(void* data,
globals->input_timestamps_manager.reset( globals->input_timestamps_manager.reset(
static_cast<zwp_input_timestamps_manager_v1*>(wl_registry_bind( static_cast<zwp_input_timestamps_manager_v1*>(wl_registry_bind(
registry, id, &zwp_input_timestamps_manager_v1_interface, 1))); registry, id, &zwp_input_timestamps_manager_v1_interface, 1)));
} else if (strcmp(interface, "zwp_fullscreen_shell_v1") == 0) {
globals->fullscreen_shell.reset(static_cast<zwp_fullscreen_shell_v1*>(
wl_registry_bind(registry, id, &zwp_fullscreen_shell_v1_interface, 1)));
} else if (strcmp(interface, "wl_output") == 0) {
globals->output.reset(static_cast<wl_output*>(
wl_registry_bind(registry, id, &wl_output_interface, 1)));
} }
} }
...@@ -491,23 +502,6 @@ bool ClientBase::Init(const InitParams& params) { ...@@ -491,23 +502,6 @@ bool ClientBase::Init(const InitParams& params) {
#endif // defined(USE_VULKAN) #endif // defined(USE_VULKAN)
} }
#endif // defined(USE_GBM) #endif // defined(USE_GBM)
for (size_t i = 0; i < params.num_buffers; ++i) {
auto buffer = CreateBuffer(size_, params.drm_format, params.bo_usage);
if (!buffer) {
LOG(ERROR) << "Failed to create buffer";
return false;
}
buffers_.push_back(std::move(buffer));
}
for (size_t i = 0; i < buffers_.size(); ++i) {
// If the buffer handle doesn't exist, we would either be killed by the
// server or die here.
if (!buffers_[i]->buffer) {
LOG(ERROR) << "buffer handle uninitialized.";
return false;
}
}
surface_.reset(static_cast<wl_surface*>( surface_.reset(static_cast<wl_surface*>(
wl_compositor_create_surface(globals_.compositor.get()))); wl_compositor_create_surface(globals_.compositor.get())));
...@@ -527,33 +521,118 @@ bool ClientBase::Init(const InitParams& params) { ...@@ -527,33 +521,118 @@ bool ClientBase::Init(const InitParams& params) {
wl_region_add(opaque_region.get(), 0, 0, size_.width(), size_.height()); wl_region_add(opaque_region.get(), 0, 0, size_.width(), size_.height());
wl_surface_set_opaque_region(surface_.get(), opaque_region.get()); wl_surface_set_opaque_region(surface_.get(), opaque_region.get());
} }
std::unique_ptr<wl_shell_surface> shell_surface(
static_cast<wl_shell_surface*>(
wl_shell_get_shell_surface(globals_.shell.get(), surface_.get())));
if (!shell_surface) {
LOG(ERROR) << "Can't get shell surface";
return false;
}
wl_shell_surface_set_title(shell_surface.get(), params.title.c_str()); if (params.allocate_buffers_with_output_mode) {
static wl_output_listener kOutputListener = {
[](void* data, struct wl_output* wl_output, int32_t x, int32_t y,
int32_t physical_width, int32_t physical_height, int32_t subpixel,
const char* make, const char* model, int32_t transform) {
CastToClientBase(data)->HandleGeometry(
data, wl_output, x, y, physical_width, physical_height, subpixel,
make, model, transform);
},
[](void* data, struct wl_output* wl_output, uint32_t flags,
int32_t width, int32_t height, int32_t refresh) {
CastToClientBase(data)->HandleMode(data, wl_output, flags, width,
height, refresh);
},
[](void* data, struct wl_output* wl_output) {
CastToClientBase(data)->HandleDone(data, wl_output);
},
[](void* data, struct wl_output* wl_output, int32_t factor) {
CastToClientBase(data)->HandleScale(data, wl_output, factor);
}};
wl_output_add_listener(globals_.output.get(), &kOutputListener, this);
} else {
for (size_t i = 0; i < params.num_buffers; ++i) {
auto buffer = CreateBuffer(size_, params.drm_format, params.bo_usage);
if (!buffer) {
LOG(ERROR) << "Failed to create buffer";
return false;
}
buffers_.push_back(std::move(buffer));
}
std::unique_ptr<zaura_surface> aura_surface( for (size_t i = 0; i < buffers_.size(); ++i) {
static_cast<zaura_surface*>( // If the buffer handle doesn't exist, we would either be killed by the
zaura_shell_get_aura_surface(globals_.aura_shell.get(), // server or die here.
surface_.get()))); if (!buffers_[i]->buffer) {
if (!aura_surface) { LOG(ERROR) << "buffer handle uninitialized.";
LOG(ERROR) << "Can't get aura surface"; return false;
return false; }
}
} }
zaura_surface_set_frame(aura_surface.get(), ZAURA_SURFACE_FRAME_TYPE_NORMAL); if (params.use_fullscreen_shell) {
zwp_fullscreen_shell_v1_present_surface(globals_.fullscreen_shell.get(),
surface_.get(), 0, nullptr);
if (fullscreen_) {
wl_shell_surface_set_fullscreen(shell_surface.get(),
WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT,
0, nullptr);
} else { } else {
wl_shell_surface_set_toplevel(shell_surface.get()); std::unique_ptr<wl_shell_surface> shell_surface(
static_cast<wl_shell_surface*>(
wl_shell_get_shell_surface(globals_.shell.get(), surface_.get())));
if (!shell_surface) {
LOG(ERROR) << "Can't get shell surface";
return false;
}
wl_shell_surface_set_title(shell_surface.get(), params.title.c_str());
std::unique_ptr<zaura_surface> aura_surface(
static_cast<zaura_surface*>(zaura_shell_get_aura_surface(
globals_.aura_shell.get(), surface_.get())));
if (!aura_surface) {
LOG(ERROR) << "Can't get aura surface";
return false;
}
zaura_surface_set_frame(aura_surface.get(),
ZAURA_SURFACE_FRAME_TYPE_NORMAL);
if (fullscreen_) {
wl_shell_surface_set_fullscreen(
shell_surface.get(), WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT, 0,
nullptr);
} else {
wl_shell_surface_set_toplevel(shell_surface.get());
}
}
if (params.use_touch) {
static wl_touch_listener kTouchListener = {
[](void* data, struct wl_touch* wl_touch, uint32_t serial,
uint32_t time, struct wl_surface* surface, int32_t id, wl_fixed_t x,
wl_fixed_t y) {
CastToClientBase(data)->HandleDown(data, wl_touch, serial, time,
surface, id, x, y);
},
[](void* data, struct wl_touch* wl_touch, uint32_t serial,
uint32_t time, int32_t id) {
CastToClientBase(data)->HandleUp(data, wl_touch, serial, time, id);
},
[](void* data, struct wl_touch* wl_touch, uint32_t time, int32_t id,
wl_fixed_t x, wl_fixed_t y) {
CastToClientBase(data)->HandleMotion(data, wl_touch, time, id, x, y);
},
[](void* data, struct wl_touch* wl_touch) {
CastToClientBase(data)->HandleFrame(data, wl_touch);
},
[](void* data, struct wl_touch* wl_touch) {
CastToClientBase(data)->HandleCancel(data, wl_touch);
},
[](void* data, struct wl_touch* wl_touch, int32_t id, wl_fixed_t major,
wl_fixed_t minor) {
CastToClientBase(data)->HandleShape(data, wl_touch, id, major, minor);
},
[](void* data, struct wl_touch* wl_touch, int32_t id,
wl_fixed_t orientation) {
CastToClientBase(data)->HandleOrientation(data, wl_touch, id,
orientation);
}};
wl_touch* touch = wl_seat_get_touch(globals_.seat.get());
wl_touch_add_listener(touch, &kTouchListener, this);
} }
return true; return true;
...@@ -567,7 +646,71 @@ ClientBase::ClientBase() {} ...@@ -567,7 +646,71 @@ ClientBase::ClientBase() {}
ClientBase::~ClientBase() {} ClientBase::~ClientBase() {}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// ClientBase, private: // wl_touch_listener
void ClientBase::HandleDown(void* data,
struct wl_touch* wl_touch,
uint32_t serial,
uint32_t time,
struct wl_surface* surface,
int32_t id,
wl_fixed_t x,
wl_fixed_t y) {}
void ClientBase::HandleUp(void* data,
struct wl_touch* wl_touch,
uint32_t serial,
uint32_t time,
int32_t id) {}
void ClientBase::HandleMotion(void* data,
struct wl_touch* wl_touch,
uint32_t time,
int32_t id,
wl_fixed_t x,
wl_fixed_t y) {}
void ClientBase::HandleFrame(void* data, struct wl_touch* wl_touch) {}
void ClientBase::HandleCancel(void* data, struct wl_touch* wl_touch) {}
void ClientBase::HandleShape(void* data,
struct wl_touch* wl_touch,
int32_t id,
wl_fixed_t major,
wl_fixed_t minor) {}
void ClientBase::HandleOrientation(void* data,
struct wl_touch* wl_touch,
int32_t id,
wl_fixed_t orientation) {}
////////////////////////////////////////////////////////////////////////////////
// wl_output_listener
void ClientBase::HandleGeometry(void* data,
struct wl_output* wl_output,
int32_t x,
int32_t y,
int32_t physical_width,
int32_t physical_height,
int32_t subpixel,
const char* make,
const char* model,
int32_t transform) {}
void ClientBase::HandleMode(void* data,
struct wl_output* wl_output,
uint32_t flags,
int32_t width,
int32_t height,
int32_t refresh) {}
void ClientBase::HandleDone(void* data, struct wl_output* wl_output) {}
void ClientBase::HandleScale(void* data,
struct wl_output* wl_output,
int32_t factor) {}
std::unique_ptr<ClientBase::Buffer> ClientBase::CreateBuffer( std::unique_ptr<ClientBase::Buffer> ClientBase::CreateBuffer(
const gfx::Size& size, const gfx::Size& size,
......
...@@ -54,12 +54,16 @@ class ClientBase { ...@@ -54,12 +54,16 @@ class ClientBase {
std::string use_drm_value; std::string use_drm_value;
int32_t drm_format = 0; int32_t drm_format = 0;
int32_t bo_usage = 0; int32_t bo_usage = 0;
bool allocate_buffers_with_output_mode = false;
bool use_fullscreen_shell = false;
bool use_touch = false;
}; };
struct Globals { struct Globals {
Globals(); Globals();
~Globals(); ~Globals();
std::unique_ptr<wl_output> output;
std::unique_ptr<wl_compositor> compositor; std::unique_ptr<wl_compositor> compositor;
std::unique_ptr<wl_shm> shm; std::unique_ptr<wl_shm> shm;
std::unique_ptr<wp_presentation> presentation; std::unique_ptr<wp_presentation> presentation;
...@@ -67,7 +71,9 @@ class ClientBase { ...@@ -67,7 +71,9 @@ class ClientBase {
std::unique_ptr<wl_shell> shell; std::unique_ptr<wl_shell> shell;
std::unique_ptr<wl_seat> seat; std::unique_ptr<wl_seat> seat;
std::unique_ptr<wl_subcompositor> subcompositor; std::unique_ptr<wl_subcompositor> subcompositor;
std::unique_ptr<wl_touch> touch;
std::unique_ptr<zaura_shell> aura_shell; std::unique_ptr<zaura_shell> aura_shell;
std::unique_ptr<zwp_fullscreen_shell_v1> fullscreen_shell;
std::unique_ptr<zwp_input_timestamps_manager_v1> input_timestamps_manager; std::unique_ptr<zwp_input_timestamps_manager_v1> input_timestamps_manager;
}; };
...@@ -108,6 +114,60 @@ class ClientBase { ...@@ -108,6 +114,60 @@ class ClientBase {
int32_t bo_usage); int32_t bo_usage);
ClientBase::Buffer* DequeueBuffer(); ClientBase::Buffer* DequeueBuffer();
// wl_output_listener
virtual void HandleGeometry(void* data,
struct wl_output* wl_output,
int32_t x,
int32_t y,
int32_t physical_width,
int32_t physical_height,
int32_t subpixel,
const char* make,
const char* model,
int32_t transform);
virtual void HandleMode(void* data,
struct wl_output* wl_output,
uint32_t flags,
int32_t width,
int32_t height,
int32_t refresh);
virtual void HandleDone(void* data, struct wl_output* wl_output);
virtual void HandleScale(void* data,
struct wl_output* wl_output,
int32_t factor);
// wl_touch_listener
virtual void HandleDown(void* data,
struct wl_touch* wl_touch,
uint32_t serial,
uint32_t time,
struct wl_surface* surface,
int32_t id,
wl_fixed_t x,
wl_fixed_t y);
virtual void HandleUp(void* data,
struct wl_touch* wl_touch,
uint32_t serial,
uint32_t time,
int32_t id);
virtual void HandleMotion(void* data,
struct wl_touch* wl_touch,
uint32_t time,
int32_t id,
wl_fixed_t x,
wl_fixed_t y);
virtual void HandleFrame(void* data, struct wl_touch* wl_touch);
virtual void HandleCancel(void* data, struct wl_touch* wl_touch);
virtual void HandleShape(void* data,
struct wl_touch* wl_touch,
int32_t id,
wl_fixed_t major,
wl_fixed_t minor);
virtual void HandleOrientation(void* data,
struct wl_touch* wl_touch,
int32_t id,
wl_fixed_t orientation);
gfx::Size size_ = gfx::Size(256, 256); gfx::Size size_ = gfx::Size(256, 256);
int scale_ = 1; int scale_ = 1;
int transform_ = WL_OUTPUT_TRANSFORM_NORMAL; int transform_ = WL_OUTPUT_TRANSFORM_NORMAL;
......
...@@ -49,6 +49,7 @@ DEFAULT_DELETER(struct wp_presentation_feedback, ...@@ -49,6 +49,7 @@ DEFAULT_DELETER(struct wp_presentation_feedback,
DEFAULT_DELETER(zaura_shell, zaura_shell_destroy) DEFAULT_DELETER(zaura_shell, zaura_shell_destroy)
DEFAULT_DELETER(zaura_surface, zaura_surface_destroy) DEFAULT_DELETER(zaura_surface, zaura_surface_destroy)
DEFAULT_DELETER(zaura_output, zaura_output_destroy) DEFAULT_DELETER(zaura_output, zaura_output_destroy)
DEFAULT_DELETER(zwp_fullscreen_shell_v1, zwp_fullscreen_shell_v1_destroy)
DEFAULT_DELETER(zwp_input_timestamps_manager_v1, DEFAULT_DELETER(zwp_input_timestamps_manager_v1,
zwp_input_timestamps_manager_v1_destroy); zwp_input_timestamps_manager_v1_destroy);
DEFAULT_DELETER(zwp_input_timestamps_v1, zwp_input_timestamps_v1_destroy) DEFAULT_DELETER(zwp_input_timestamps_v1, zwp_input_timestamps_v1_destroy)
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#ifndef COMPONENTS_EXO_WAYLAND_CLIENTS_CLIENT_HELPER_H_ #ifndef COMPONENTS_EXO_WAYLAND_CLIENTS_CLIENT_HELPER_H_
#define COMPONENTS_EXO_WAYLAND_CLIENTS_CLIENT_HELPER_H_ #define COMPONENTS_EXO_WAYLAND_CLIENTS_CLIENT_HELPER_H_
#include <fullscreen-shell-unstable-v1-client-protocol.h>
#include <input-timestamps-unstable-v1-client-protocol.h> #include <input-timestamps-unstable-v1-client-protocol.h>
#include <linux-dmabuf-unstable-v1-client-protocol.h> #include <linux-dmabuf-unstable-v1-client-protocol.h>
#include <presentation-time-client-protocol.h> #include <presentation-time-client-protocol.h>
...@@ -54,6 +55,7 @@ DEFAULT_DELETER_FDECL(struct wp_presentation_feedback) ...@@ -54,6 +55,7 @@ DEFAULT_DELETER_FDECL(struct wp_presentation_feedback)
DEFAULT_DELETER_FDECL(zaura_shell) DEFAULT_DELETER_FDECL(zaura_shell)
DEFAULT_DELETER_FDECL(zaura_surface) DEFAULT_DELETER_FDECL(zaura_surface)
DEFAULT_DELETER_FDECL(zaura_output) DEFAULT_DELETER_FDECL(zaura_output)
DEFAULT_DELETER_FDECL(zwp_fullscreen_shell_v1)
DEFAULT_DELETER_FDECL(zwp_input_timestamps_manager_v1) DEFAULT_DELETER_FDECL(zwp_input_timestamps_manager_v1)
DEFAULT_DELETER_FDECL(zwp_input_timestamps_v1) DEFAULT_DELETER_FDECL(zwp_input_timestamps_v1)
DEFAULT_DELETER_FDECL(zwp_linux_buffer_params_v1) DEFAULT_DELETER_FDECL(zwp_linux_buffer_params_v1)
......
// 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/clients/fullscreen_shell.h"
#include "base/command_line.h"
#include "base/logging.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/stringprintf.h"
#include "third_party/skia/include/core/SkCanvas.h"
#include "third_party/skia/include/core/SkRefCnt.h"
#include "third_party/skia/include/core/SkSurface.h"
#include "third_party/skia/include/gpu/GrBackendSurface.h"
#include "third_party/skia/include/gpu/GrContext.h"
#include "third_party/skia/include/gpu/gl/GrGLAssembleInterface.h"
#include "third_party/skia/include/gpu/gl/GrGLInterface.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/skia_util.h"
#include "ui/gl/gl_bindings.h"
namespace exo {
namespace wayland {
namespace clients {
namespace {
void FrameCallback(void* data, wl_callback* callback, uint32_t time) {
bool* frame_callback_pending = static_cast<bool*>(data);
*frame_callback_pending = false;
}
} // namespace
////////////////////////////////////////////////////////////////////////////////
// FullscreenClient, public:
FullscreenClient::FullscreenClient() {}
FullscreenClient::~FullscreenClient() {}
bool FullscreenClient::Run(const InitParams& params) {
wl_callback_listener frame_listener = {FrameCallback};
// Wait for screen mode to be received
while (wl_display_dispatch(display_.get()) != -1) {
if (done_receiving_modes_ && !has_mode_) {
LOG(ERROR) << "Did not receive screen mode";
return false;
} else if (has_mode_) {
break;
}
}
AllocateBuffers(params);
do {
if (frame_callback_pending_)
continue;
if (frame_count_ == frames_)
break;
Paint(frame_listener);
} while (wl_display_dispatch(display_.get()) != -1);
return true;
}
////////////////////////////////////////////////////////////////////////////////
// FullscreenClient: Private
void FullscreenClient::AllocateBuffers(const InitParams& params) {
for (size_t i = 0; i < params.num_buffers; ++i) {
auto buffer = CreateBuffer(size_, params.drm_format, params.bo_usage);
if (!buffer) {
LOG(ERROR) << "Failed to create buffer";
return;
}
buffers_.push_back(std::move(buffer));
}
}
void FullscreenClient::Paint(const wl_callback_listener& frame_listener) {
Buffer* buffer = DequeueBuffer();
if (!buffer)
return;
++frame_count_;
int left = point_.x();
int top = point_.y();
int right = point_.x() + square_size_.width();
int bottom = point_.y() + square_size_.height();
if (right >= size_.width() || left <= 0) {
dir_x_ *= -1;
}
if (top <= 0 || bottom >= size_.height()) {
dir_y_ *= -1;
}
point_.set_x(point_.x() + dir_x_ * step_size_);
point_.set_y(point_.y() + dir_y_ * step_size_);
SkCanvas* canvas = buffer->sk_surface->getCanvas();
canvas->clear(color_);
const SkRect rect = gfx::RectToSkRect(gfx::Rect{point_, square_size_});
const SkPaint paint;
canvas->drawRect(rect, paint);
if (gr_context_) {
gr_context_->flush();
glFinish();
}
wl_surface_set_buffer_scale(surface_.get(), scale_);
wl_surface_set_buffer_transform(surface_.get(), transform_);
wl_surface_damage(surface_.get(), 0, 0, size_.width(), size_.height());
wl_surface_attach(surface_.get(), buffer->buffer.get(), 0, 0);
// Set up the frame callback.
frame_callback_pending_ = true;
frame_callback_.reset(wl_surface_frame(surface_.get()));
wl_callback_add_listener(frame_callback_.get(), &frame_listener,
&frame_callback_pending_);
wl_surface_commit(surface_.get());
wl_display_flush(display_.get());
}
void FullscreenClient::HandleDown(void* data,
struct wl_touch* wl_touch,
uint32_t serial,
uint32_t time,
struct wl_surface* surface,
int32_t id,
wl_fixed_t x,
wl_fixed_t y) {
if (color_ == SK_ColorBLUE) {
color_ = SK_ColorRED;
} else {
color_ = SK_ColorBLUE;
}
}
void FullscreenClient::HandleMode(void* data,
struct wl_output* wl_output,
uint32_t flags,
int32_t width,
int32_t height,
int32_t refresh) {
if ((WL_OUTPUT_MODE_CURRENT & flags) != WL_OUTPUT_MODE_CURRENT)
return;
size_.SetSize(width, height);
std::unique_ptr<wl_region> opaque_region(static_cast<wl_region*>(
wl_compositor_create_region(globals_.compositor.get())));
if (!opaque_region) {
LOG(ERROR) << "Can't create region";
return;
}
wl_region_add(opaque_region.get(), 0, 0, size_.width(), size_.height());
wl_surface_set_opaque_region(surface_.get(), opaque_region.get());
wl_surface_set_input_region(surface_.get(), opaque_region.get());
has_mode_ = true;
}
void FullscreenClient::HandleDone(void* data, struct wl_output* wl_output) {
done_receiving_modes_ = true;
}
} // namespace clients
} // namespace wayland
} // namespace exo
// 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.
#ifndef COMPONENTS_EXO_WAYLAND_CLIENTS_FULLSCREEN_SHELL_H_
#define COMPONENTS_EXO_WAYLAND_CLIENTS_FULLSCREEN_SHELL_H_
#include "components/exo/wayland/clients/client_base.h"
#include "ui/gfx/geometry/point.h"
#include "ui/gfx/geometry/size.h"
namespace exo {
namespace wayland {
namespace clients {
// Sample Wayland client that uses the Fullscreen Shell protocol
// to display a fullscreen application with touch support.
class FullscreenClient : public ClientBase {
public:
FullscreenClient();
~FullscreenClient() override;
bool Run(const InitParams& params);
private:
void AllocateBuffers(const InitParams& params);
void Paint(const wl_callback_listener& frame_listener);
// Overridden from ClientBase
void HandleDown(void* data,
struct wl_touch* wl_touch,
uint32_t serial,
uint32_t time,
struct wl_surface* surface,
int32_t id,
wl_fixed_t x,
wl_fixed_t y) override;
void HandleMode(void* data,
struct wl_output* wl_output,
uint32_t flags,
int32_t width,
int32_t height,
int32_t refresh) override;
void HandleDone(void* data, struct wl_output* wl_output) override;
bool has_mode_ = false;
bool done_receiving_modes_ = false;
int frame_count_ = 0;
int frames_ = 300;
gfx::Point point_ = {100, 100};
const gfx::Size square_size_ = {100, 100};
int dir_x_ = 1;
int dir_y_ = 1;
const int step_size_ = 20;
SkColor color_ = SK_ColorBLUE;
std::unique_ptr<wl_callback> frame_callback_;
bool frame_callback_pending_ = false;
DISALLOW_COPY_AND_ASSIGN(FullscreenClient);
};
} // namespace clients
} // namespace wayland
} // namespace exo
#endif // COMPONENTS_EXO_WAYLAND_CLIENTS_FULLSCREEN_SHELL_H_
// 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/clients/fullscreen_shell.h"
#include "base/at_exit.h"
#include "base/command_line.h"
#include "base/message_loop/message_loop.h"
int main(int argc, char* argv[]) {
base::AtExitManager exit_manager;
base::CommandLine::Init(argc, argv);
base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
exo::wayland::clients::FullscreenClient::InitParams params;
params.allocate_buffers_with_output_mode = true;
params.use_fullscreen_shell = true;
params.use_touch = true;
if (!params.FromCommandLine(*command_line))
return 1;
base::MessageLoopForUI message_loop;
exo::wayland::clients::FullscreenClient client;
if (!client.Init(params))
return 1;
if (!client.Run(params))
return 1;
return 0;
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment