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

Side by Side 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, 9 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 unified diff | 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 »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include <fcntl.h>
6 #include <string.h>
7 #include <unistd.h>
8 #include <wayland-client.h>
9
10 #include <memory>
11 #include <sys/mman.h>
12
13 namespace {
14
15 class WaylandClient {
16 public:
17 static WaylandClient* Create() {
18 std::unique_ptr<WaylandClient> client(new WaylandClient);
19 if (client->Initialize())
20 return client.release();
21 return nullptr;
22 }
23
24 ~WaylandClient() {
25 wl_pointer_destroy(pointer_);
26 wl_seat_destroy(seat_);
27 wl_shell_destroy(shell_);
28 wl_shm_destroy(shm_);
29 wl_compositor_destroy(compositor_);
30 wl_display_disconnect(display_);
31 }
32
33 bool running() const { return running_; }
34 struct wl_compositor* compositor() const {
35 return compositor_;
36 }
37 struct wl_display* display() const {
38 return display_;
39 }
40 struct wl_shell* shell() const {
41 return shell_;
42 }
43 struct wl_shm* shm() const {
44 return shm_;
45 }
46
47 private:
48 WaylandClient() {}
49 WaylandClient(const WaylandClient&) = delete;
50 void operator=(const WaylandClient&) = delete;
51
52 bool Initialize() {
53 display_ = wl_display_connect(nullptr);
54 if (!display_) {
55 perror("Cannot open display");
56 return false;
57 }
58
59 struct wl_registry* registry = wl_display_get_registry(display_);
60 const struct wl_registry_listener registry_listener = {
61 WaylandClient::OnRegistry, WaylandClient::OnRemoveRegistry};
62 wl_registry_add_listener(registry, &registry_listener, this);
63 wl_display_roundtrip(display_);
64 wl_registry_destroy(registry);
65 running_ = true;
66
67 return true;
68 }
69
70 static void OnRemoveRegistry(void* a, struct wl_registry* b, uint32_t c) {}
71
72 static void OnRegistry(void* data,
73 struct wl_registry* registry,
74 uint32_t name,
75 const char* interface,
76 uint32_t version) {
77 WaylandClient* me = static_cast<WaylandClient*>(data);
78 if (!strcmp(interface, wl_compositor_interface.name)) {
79 me->compositor_ = static_cast<wl_compositor*>(
80 wl_registry_bind(registry, name, &wl_compositor_interface, version));
81 } else if (!strcmp(interface, wl_shm_interface.name)) {
82 me->shm_ = static_cast<wl_shm*>(
83 wl_registry_bind(registry, name, &wl_shm_interface, version));
84 } else if (!strcmp(interface, wl_shell_interface.name)) {
85 me->shell_ = static_cast<wl_shell*>(
86 wl_registry_bind(registry, name, &wl_shell_interface, version));
87 } else if (!strcmp(interface, wl_seat_interface.name)) {
88 me->seat_ = static_cast<wl_seat*>(
89 wl_registry_bind(registry, name, &wl_seat_interface, version));
90 me->pointer_ = wl_seat_get_pointer(me->seat_);
91 const struct wl_pointer_listener pointer_listener = {
92 OnPointerEnter, OnPointerLeave, OnPointerMotion, OnPointerButton,
93 OnPointerAxis};
94 wl_pointer_add_listener(me->pointer_, &pointer_listener, data);
95 }
96 }
97
98 static void OnPointerEnter(void* data,
99 struct wl_pointer* wl_pointer,
100 uint32_t serial,
101 struct wl_surface* surface,
102 wl_fixed_t surface_x,
103 wl_fixed_t surface_y) {}
104 static void OnPointerLeave(void* data,
105 struct wl_pointer* wl_pointer,
106 uint32_t serial,
107 struct wl_surface* wl_surface) {}
108
109 static void OnPointerMotion(void* data,
110 struct wl_pointer* wl_pointer,
111 uint32_t time,
112 wl_fixed_t surface_x,
113 wl_fixed_t surface_y) {}
114
115 // Program exits if clicking any mouse buttons.
116 static void OnPointerButton(void* data,
117 struct wl_pointer* wl_pointer,
118 uint32_t serial,
119 uint32_t time,
120 uint32_t button,
121 uint32_t state) {
122 WaylandClient* me = static_cast<WaylandClient*>(data);
123 me->running_ = false;
124 }
125
126 static void OnPointerAxis(void* data,
127 struct wl_pointer* wl_pointer,
128 uint32_t time,
129 uint32_t axis,
130 wl_fixed_t value) {}
131
132 bool running_ = false;
133 struct wl_compositor* compositor_ = nullptr;
134 struct wl_display* display_ = nullptr;
135 struct wl_pointer* pointer_ = nullptr;
136 struct wl_seat* seat_ = nullptr;
137 struct wl_shell* shell_ = nullptr;
138 struct wl_shm* shm_ = nullptr;
139 };
140
141 class DemoWindow {
142 public:
143 DemoWindow() {}
144 ~DemoWindow() {
145 wl_buffer_destroy(buffer_);
146 wl_shell_surface_destroy(shell_surface_);
147 wl_surface_destroy(surface_);
148 }
149
150 int Run() {
151 client_.reset(WaylandClient::Create());
152 if (!client_) {
153 perror("Cannot create WaylandClient");
154 return EXIT_FAILURE;
155 }
156
157 if (!CreateBuffer()) {
158 perror("Creating a buffer failed");
159 return EXIT_FAILURE;
160 }
161
162 if (!CreateSurface()) {
163 perror("Creating a surface failed");
164 return EXIT_FAILURE;
165 }
166
167 Redraw(this, nullptr, 0);
168 int ret = 0;
169 while (client_->running() && ret != -1)
170 ret = wl_display_dispatch(client_->display());
171
172 return EXIT_SUCCESS;
173 }
174
175 private:
176 DemoWindow(const DemoWindow&) = delete;
177 void operator=(const DemoWindow&) = delete;
178
179 bool CreateBuffer() {
180 int stride = WIDTH * 4;
181 int size = stride * HEIGHT;
182 ScopedFD fd(CreateAnonymousFile(size));
183 if (fd.Get() < 0) {
184 perror("Creating a buffer file failed");
185 return false;
186 }
187 data_ =
188 mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd.Get(), 0);
189 if (data_ == MAP_FAILED) {
190 perror("mmap failed");
191 return false;
192 }
193
194 struct wl_shm_pool* pool =
195 wl_shm_create_pool(client_->shm(), fd.Get(), size);
196 buffer_ = wl_shm_pool_create_buffer(pool, 0, WIDTH, HEIGHT, stride,
197 WL_SHM_FORMAT_XRGB8888);
198 wl_shm_pool_destroy(pool);
199 return true;
200 }
201
202 class ScopedFD {
203 public:
204 explicit ScopedFD(int fd) : fd_(fd) {}
205 ~ScopedFD() {
206 if (auto_close_)
207 close(fd_);
208 }
209 int Get() { return fd_; }
210 int Release() {
211 auto_close_ = false;
212 return fd_;
213 }
214
215 private:
216 ScopedFD(const ScopedFD&) = delete;
217 void operator=(const ScopedFD&) = delete;
218
219 const int fd_;
220 bool auto_close_ = true;
221 };
222
223 int CreateAnonymousFile(off_t size) {
224 static const std::string file_name = "/weston-shared-XXXXXX";
225 const std::string path = getenv("XDG_RUNTIME_DIR");
226 if (path.empty()) {
227 errno = ENOENT;
228 return -1;
229 }
230
231 std::string name = path + file_name;
232 char* c_name = const_cast<char*>(name.data());
233 ScopedFD fd(mkstemp(c_name));
234 if (fd.Get() < 0)
235 return -1;
236
237 long flags = fcntl(fd.Get(), F_GETFD);
238 if (flags == -1)
239 return -1;
240 if (fcntl(fd.Get(), F_SETFD, flags | FD_CLOEXEC) == -1)
241 return -1;
242 if (ftruncate(fd.Get(), size) < 0)
243 return -1;
244
245 return fd.Release();
246 }
247
248 bool CreateSurface() {
249 surface_ = wl_compositor_create_surface(client_->compositor());
250 if (!surface_)
251 return false;
252
253 shell_surface_ = wl_shell_get_shell_surface(client_->shell(), surface_);
254 if (!shell_surface_) {
255 wl_surface_destroy(surface_);
256 return false;
257 }
258
259 wl_shell_surface_set_toplevel(shell_surface_);
260 wl_shell_surface_set_user_data(shell_surface_, surface_);
261 wl_surface_set_user_data(surface_, nullptr);
262 return true;
263 }
264
265 static void Redraw(void* data, struct wl_callback* callback, uint32_t time) {
266 DemoWindow* me = static_cast<DemoWindow*>(data);
267
268 PaintPixels(me->data_, 20, WIDTH, HEIGHT, time);
269
270 const int border_width = 20;
271 wl_surface_attach(me->surface_, me->buffer_, 0, 0);
272 wl_surface_damage(me->surface_, border_width, border_width,
273 WIDTH - 2 * border_width, HEIGHT - 2 * border_width);
274 if (callback)
275 wl_callback_destroy(callback);
276 me->callback_ = wl_surface_frame(me->surface_);
277 const struct wl_callback_listener frame_listener = {Redraw};
278 wl_callback_add_listener(me->callback_, &frame_listener, me);
279 wl_surface_commit(me->surface_);
280 }
281
282 // Copied from
283 // https://cgit.freedesktop.org/wayland/weston/tree/clients/simple-shm.c
284 // which is in MIT license.
285 static void PaintPixels(void* image,
286 int padding,
287 int width,
288 int height,
289 uint32_t time) {
290 uint32_t* pixel = static_cast<uint32_t*>(image);
291 const int halfh = padding + (height - padding * 2) / 2;
292 const int halfw = padding + (width - padding * 2) / 2;
293
294 /* squared radii thresholds */
295 int outr = (halfw < halfh ? halfw : halfh) - 8;
296 int inr = outr - 32;
297 outr *= outr;
298 inr *= inr;
299
300 pixel += padding * width;
301 for (int y = padding; y < height - padding; y++) {
302 int y2 = (y - halfh) * (y - halfh);
303 pixel += padding;
304 for (int x = padding; x < width - padding; x++) {
305 uint32_t v;
306
307 /* squared distance from center */
308 int r2 = (x - halfw) * (x - halfw) + y2;
309
310 if (r2 < inr)
311 v = (r2 / 32 + time / 64) * 0x0080401;
312 else if (r2 < outr)
313 v = (y + time / 32) * 0x0080401;
314 else
315 v = (x + time / 16) * 0x0080401;
316 v &= 0x00ffffff;
317
318 /* cross if compositor uses X from XRGB as alpha */
319 if (abs(x - y) > 6 && abs(x + y - height) > 6)
320 v |= 0xff000000;
321
322 *pixel++ = v;
323 }
324
325 pixel += padding;
326 }
327 }
328
329 static const unsigned WIDTH = 300;
330 static const unsigned HEIGHT = 300;
331
332 std::unique_ptr<WaylandClient> client_;
333 struct wl_shell_surface* shell_surface_ = nullptr;
334 struct wl_surface* surface_ = nullptr;
335 struct wl_buffer* buffer_ = nullptr;
336 void* data_ = nullptr;
337 struct wl_callback* callback_ = nullptr;
338 };
339
340 } // namespace
341
342 int main(int argc, char** argv) {
343 std::unique_ptr<DemoWindow> window(new DemoWindow);
344 return window->Run();
345 }
OLDNEW
« 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