Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1281)

Unified Diff: components/exo/wayland/client_demo/wayland_client_demo.cc

Issue 1752723003: exo: produce libwayland-client.so (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « components/exo/wayland/client_demo/DEPS ('k') | third_party/wayland/BUILD.gn » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: components/exo/wayland/client_demo/wayland_client_demo.cc
diff --git a/components/exo/wayland/client_demo/wayland_client_demo.cc b/components/exo/wayland/client_demo/wayland_client_demo.cc
new file mode 100644
index 0000000000000000000000000000000000000000..beeb01f3c4532456101d8a921bb1615dc2e21be9
--- /dev/null
+++ b/components/exo/wayland/client_demo/wayland_client_demo.cc
@@ -0,0 +1,345 @@
+// Copyright 2016 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 <fcntl.h>
+#include <string.h>
+#include <unistd.h>
+#include <wayland-client.h>
+
+#include <memory>
+#include <sys/mman.h>
+
+namespace {
+
+class WaylandClient {
+ public:
+ static WaylandClient* Create() {
+ std::unique_ptr<WaylandClient> client(new WaylandClient);
+ if (client->Initialize())
+ return client.release();
+ return nullptr;
+ }
+
+ ~WaylandClient() {
+ wl_pointer_destroy(pointer_);
+ wl_seat_destroy(seat_);
+ wl_shell_destroy(shell_);
+ wl_shm_destroy(shm_);
+ wl_compositor_destroy(compositor_);
+ wl_display_disconnect(display_);
+ }
+
+ bool running() const { return running_; }
+ struct wl_compositor* compositor() const {
+ return compositor_;
+ }
+ struct wl_display* display() const {
+ return display_;
+ }
+ struct wl_shell* shell() const {
+ return shell_;
+ }
+ struct wl_shm* shm() const {
+ return shm_;
+ }
+
+ private:
+ WaylandClient() {}
+ WaylandClient(const WaylandClient&) = delete;
+ void operator=(const WaylandClient&) = delete;
+
+ bool Initialize() {
+ display_ = wl_display_connect(nullptr);
+ if (!display_) {
+ perror("Cannot open display");
+ return false;
+ }
+
+ struct wl_registry* registry = wl_display_get_registry(display_);
+ const struct wl_registry_listener registry_listener = {
+ WaylandClient::OnRegistry, WaylandClient::OnRemoveRegistry};
+ wl_registry_add_listener(registry, &registry_listener, this);
+ wl_display_roundtrip(display_);
+ wl_registry_destroy(registry);
+ running_ = true;
+
+ return true;
+ }
+
+ static void OnRemoveRegistry(void* a, struct wl_registry* b, uint32_t c) {}
+
+ static void OnRegistry(void* data,
+ struct wl_registry* registry,
+ uint32_t name,
+ const char* interface,
+ uint32_t version) {
+ WaylandClient* me = static_cast<WaylandClient*>(data);
+ if (!strcmp(interface, wl_compositor_interface.name)) {
+ me->compositor_ = static_cast<wl_compositor*>(
+ wl_registry_bind(registry, name, &wl_compositor_interface, version));
+ } else if (!strcmp(interface, wl_shm_interface.name)) {
+ me->shm_ = static_cast<wl_shm*>(
+ wl_registry_bind(registry, name, &wl_shm_interface, version));
+ } else if (!strcmp(interface, wl_shell_interface.name)) {
+ me->shell_ = static_cast<wl_shell*>(
+ wl_registry_bind(registry, name, &wl_shell_interface, version));
+ } else if (!strcmp(interface, wl_seat_interface.name)) {
+ me->seat_ = static_cast<wl_seat*>(
+ wl_registry_bind(registry, name, &wl_seat_interface, version));
+ me->pointer_ = wl_seat_get_pointer(me->seat_);
+ const struct wl_pointer_listener pointer_listener = {
+ OnPointerEnter, OnPointerLeave, OnPointerMotion, OnPointerButton,
+ OnPointerAxis};
+ wl_pointer_add_listener(me->pointer_, &pointer_listener, data);
+ }
+ }
+
+ static void OnPointerEnter(void* data,
+ struct wl_pointer* wl_pointer,
+ uint32_t serial,
+ struct wl_surface* surface,
+ wl_fixed_t surface_x,
+ wl_fixed_t surface_y) {}
+ static void OnPointerLeave(void* data,
+ struct wl_pointer* wl_pointer,
+ uint32_t serial,
+ struct wl_surface* wl_surface) {}
+
+ static void OnPointerMotion(void* data,
+ struct wl_pointer* wl_pointer,
+ uint32_t time,
+ wl_fixed_t surface_x,
+ wl_fixed_t surface_y) {}
+
+ // Program exits if clicking any mouse buttons.
+ static void OnPointerButton(void* data,
+ struct wl_pointer* wl_pointer,
+ uint32_t serial,
+ uint32_t time,
+ uint32_t button,
+ uint32_t state) {
+ WaylandClient* me = static_cast<WaylandClient*>(data);
+ me->running_ = false;
+ }
+
+ static void OnPointerAxis(void* data,
+ struct wl_pointer* wl_pointer,
+ uint32_t time,
+ uint32_t axis,
+ wl_fixed_t value) {}
+
+ bool running_ = false;
+ struct wl_compositor* compositor_ = nullptr;
+ struct wl_display* display_ = nullptr;
+ struct wl_pointer* pointer_ = nullptr;
+ struct wl_seat* seat_ = nullptr;
+ struct wl_shell* shell_ = nullptr;
+ struct wl_shm* shm_ = nullptr;
+};
+
+class DemoWindow {
+ public:
+ DemoWindow() {}
+ ~DemoWindow() {
+ wl_buffer_destroy(buffer_);
+ wl_shell_surface_destroy(shell_surface_);
+ wl_surface_destroy(surface_);
+ }
+
+ int Run() {
+ client_.reset(WaylandClient::Create());
+ if (!client_) {
+ perror("Cannot create WaylandClient");
+ return EXIT_FAILURE;
+ }
+
+ if (!CreateBuffer()) {
+ perror("Creating a buffer failed");
+ return EXIT_FAILURE;
+ }
+
+ if (!CreateSurface()) {
+ perror("Creating a surface failed");
+ return EXIT_FAILURE;
+ }
+
+ Redraw(this, nullptr, 0);
+ int ret = 0;
+ while (client_->running() && ret != -1)
+ ret = wl_display_dispatch(client_->display());
+
+ return EXIT_SUCCESS;
+ }
+
+ private:
+ DemoWindow(const DemoWindow&) = delete;
+ void operator=(const DemoWindow&) = delete;
+
+ bool CreateBuffer() {
+ int stride = WIDTH * 4;
+ int size = stride * HEIGHT;
+ ScopedFD fd(CreateAnonymousFile(size));
+ if (fd.Get() < 0) {
+ perror("Creating a buffer file failed");
+ return false;
+ }
+ data_ =
+ mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd.Get(), 0);
+ if (data_ == MAP_FAILED) {
+ perror("mmap failed");
+ return false;
+ }
+
+ struct wl_shm_pool* pool =
+ wl_shm_create_pool(client_->shm(), fd.Get(), size);
+ buffer_ = wl_shm_pool_create_buffer(pool, 0, WIDTH, HEIGHT, stride,
+ WL_SHM_FORMAT_XRGB8888);
+ wl_shm_pool_destroy(pool);
+ return true;
+ }
+
+ class ScopedFD {
+ public:
+ explicit ScopedFD(int fd) : fd_(fd) {}
+ ~ScopedFD() {
+ if (auto_close_)
+ close(fd_);
+ }
+ int Get() { return fd_; }
+ int Release() {
+ auto_close_ = false;
+ return fd_;
+ }
+
+ private:
+ ScopedFD(const ScopedFD&) = delete;
+ void operator=(const ScopedFD&) = delete;
+
+ const int fd_;
+ bool auto_close_ = true;
+ };
+
+ int CreateAnonymousFile(off_t size) {
+ static const std::string file_name = "/weston-shared-XXXXXX";
+ const std::string path = getenv("XDG_RUNTIME_DIR");
+ if (path.empty()) {
+ errno = ENOENT;
+ return -1;
+ }
+
+ std::string name = path + file_name;
+ char* c_name = const_cast<char*>(name.data());
+ ScopedFD fd(mkstemp(c_name));
+ if (fd.Get() < 0)
+ return -1;
+
+ long flags = fcntl(fd.Get(), F_GETFD);
+ if (flags == -1)
+ return -1;
+ if (fcntl(fd.Get(), F_SETFD, flags | FD_CLOEXEC) == -1)
+ return -1;
+ if (ftruncate(fd.Get(), size) < 0)
+ return -1;
+
+ return fd.Release();
+ }
+
+ bool CreateSurface() {
+ surface_ = wl_compositor_create_surface(client_->compositor());
+ if (!surface_)
+ return false;
+
+ shell_surface_ = wl_shell_get_shell_surface(client_->shell(), surface_);
+ if (!shell_surface_) {
+ wl_surface_destroy(surface_);
+ return false;
+ }
+
+ wl_shell_surface_set_toplevel(shell_surface_);
+ wl_shell_surface_set_user_data(shell_surface_, surface_);
+ wl_surface_set_user_data(surface_, nullptr);
+ return true;
+ }
+
+ static void Redraw(void* data, struct wl_callback* callback, uint32_t time) {
+ DemoWindow* me = static_cast<DemoWindow*>(data);
+
+ PaintPixels(me->data_, 20, WIDTH, HEIGHT, time);
+
+ const int border_width = 20;
+ wl_surface_attach(me->surface_, me->buffer_, 0, 0);
+ wl_surface_damage(me->surface_, border_width, border_width,
+ WIDTH - 2 * border_width, HEIGHT - 2 * border_width);
+ if (callback)
+ wl_callback_destroy(callback);
+ me->callback_ = wl_surface_frame(me->surface_);
+ const struct wl_callback_listener frame_listener = {Redraw};
+ wl_callback_add_listener(me->callback_, &frame_listener, me);
+ wl_surface_commit(me->surface_);
+ }
+
+ // Copied from
+ // https://cgit.freedesktop.org/wayland/weston/tree/clients/simple-shm.c
+ // which is in MIT license.
+ static void PaintPixels(void* image,
+ int padding,
+ int width,
+ int height,
+ uint32_t time) {
+ uint32_t* pixel = static_cast<uint32_t*>(image);
+ const int halfh = padding + (height - padding * 2) / 2;
+ const int halfw = padding + (width - padding * 2) / 2;
+
+ /* squared radii thresholds */
+ int outr = (halfw < halfh ? halfw : halfh) - 8;
+ int inr = outr - 32;
+ outr *= outr;
+ inr *= inr;
+
+ pixel += padding * width;
+ for (int y = padding; y < height - padding; y++) {
+ int y2 = (y - halfh) * (y - halfh);
+ pixel += padding;
+ for (int x = padding; x < width - padding; x++) {
+ uint32_t v;
+
+ /* squared distance from center */
+ int r2 = (x - halfw) * (x - halfw) + y2;
+
+ if (r2 < inr)
+ v = (r2 / 32 + time / 64) * 0x0080401;
+ else if (r2 < outr)
+ v = (y + time / 32) * 0x0080401;
+ else
+ v = (x + time / 16) * 0x0080401;
+ v &= 0x00ffffff;
+
+ /* cross if compositor uses X from XRGB as alpha */
+ if (abs(x - y) > 6 && abs(x + y - height) > 6)
+ v |= 0xff000000;
+
+ *pixel++ = v;
+ }
+
+ pixel += padding;
+ }
+ }
+
+ static const unsigned WIDTH = 300;
+ static const unsigned HEIGHT = 300;
+
+ std::unique_ptr<WaylandClient> client_;
+ struct wl_shell_surface* shell_surface_ = nullptr;
+ struct wl_surface* surface_ = nullptr;
+ struct wl_buffer* buffer_ = nullptr;
+ void* data_ = nullptr;
+ struct wl_callback* callback_ = nullptr;
+};
+
+} // namespace
+
+int main(int argc, char** argv) {
+ std::unique_ptr<DemoWindow> window(new DemoWindow);
+ return window->Run();
+}
« no previous file with comments | « components/exo/wayland/client_demo/DEPS ('k') | third_party/wayland/BUILD.gn » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698