OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2015 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 // TODO(reveman): Most of code in this file could be auto-generated from | |
6 // the Wayland protocol description. | |
7 | |
8 #ifndef COMPONENTS_EXO_WAYLAND_WAYLAND_BINDINGS_H_ | |
9 #define COMPONENTS_EXO_WAYLAND_WAYLAND_BINDINGS_H_ | |
10 | |
11 template <class T> | |
12 T* DataAs(void* data) { | |
piman
2015/11/18 04:31:51
nit: this is only used in a single place (l.18), m
reveman
2015/11/18 06:48:36
Done.
| |
13 return static_cast<T*>(data); | |
14 } | |
15 | |
16 template <class T> | |
17 T* GetUserDataAs(wl_resource* resource) { | |
18 return DataAs<T>(wl_resource_get_user_data(resource)); | |
19 } | |
20 | |
21 template <class T> | |
22 scoped_ptr<T> TakeUserDataAs(wl_resource* resource) { | |
23 scoped_ptr<T> user_data = make_scoped_ptr(GetUserDataAs<T>(resource)); | |
24 wl_resource_set_user_data(resource, nullptr); | |
25 return user_data.Pass(); | |
26 } | |
27 | |
28 template <class T> | |
29 void DestroyUserData(wl_resource* resource) { | |
30 TakeUserDataAs<T>(resource); | |
31 } | |
32 | |
33 template <class T> | |
34 void SetImplementation(wl_resource* resource, | |
35 const void* implementation, | |
36 scoped_ptr<T> user_data) { | |
37 wl_resource_set_implementation(resource, implementation, user_data.release(), | |
38 DestroyUserData<T>); | |
39 } | |
40 | |
41 //////////////////////////////////////////////////////////////////////////////// | |
42 // wl_buffer_interface: | |
43 | |
44 void buffer_destroy(wl_client* client, wl_resource* resource) { | |
45 wl_resource_destroy(resource); | |
46 } | |
47 | |
48 const struct wl_buffer_interface buffer_implementation = {buffer_destroy}; | |
49 | |
50 //////////////////////////////////////////////////////////////////////////////// | |
51 // wl_surface_interface: | |
52 | |
53 void surface_destroy(wl_client* client, wl_resource* resource) { | |
54 wl_resource_destroy(resource); | |
55 } | |
56 | |
57 void surface_attach(wl_client* client, | |
58 wl_resource* resource, | |
59 wl_resource* buffer, | |
60 int32_t x, | |
61 int32_t y) { | |
62 // TODO(reveman): Implement buffer offset support. | |
63 if (x || y) { | |
64 wl_resource_post_no_memory(resource); | |
65 return; | |
66 } | |
67 | |
68 GetUserDataAs<Surface>(resource) | |
69 ->Attach(buffer ? GetUserDataAs<Buffer>(buffer) : nullptr); | |
70 } | |
71 | |
72 void surface_damage(wl_client* client, | |
73 wl_resource* resource, | |
74 int32_t x, | |
75 int32_t y, | |
76 int32_t width, | |
77 int32_t height) { | |
78 GetUserDataAs<Surface>(resource)->Damage(gfx::Rect(x, y, width, height)); | |
79 } | |
80 | |
81 void handle_surface_frame_callback(wl_resource* resource, | |
82 base::TimeTicks frame_time) { | |
83 if (!frame_time.is_null()) { | |
84 wl_callback_send_done(resource, | |
85 (frame_time - base::TimeTicks()).InMilliseconds()); | |
86 // TODO(reveman): Remove this potentially blocking flush and instead watch | |
87 // the file descriptor to be ready for write without blocking. | |
88 wl_client_flush(wl_resource_get_client(resource)); | |
89 } | |
90 wl_resource_destroy(resource); | |
91 } | |
92 | |
93 void surface_frame(wl_client* client, | |
94 wl_resource* resource, | |
95 uint32_t callback) { | |
96 wl_resource* callback_resource = | |
97 wl_resource_create(client, &wl_callback_interface, 1, callback); | |
98 if (!callback_resource) { | |
99 wl_resource_post_no_memory(resource); | |
100 return; | |
101 } | |
102 | |
103 // base::Unretained is safe as the resource owns the callback. | |
104 scoped_ptr<base::CancelableCallback<void(base::TimeTicks)>> | |
105 cancelable_callback(new base::CancelableCallback<void(base::TimeTicks)>( | |
106 base::Bind(&handle_surface_frame_callback, | |
107 base::Unretained(callback_resource)))); | |
108 | |
109 GetUserDataAs<Surface>(resource) | |
110 ->RequestFrameCallback(cancelable_callback->callback()); | |
111 | |
112 SetImplementation(callback_resource, nullptr, cancelable_callback.Pass()); | |
113 } | |
114 | |
115 void surface_set_opaque_region(wl_client* client, | |
116 wl_resource* resource, | |
117 wl_resource* region_resource) { | |
118 GetUserDataAs<Surface>(resource)->SetOpaqueRegion( | |
119 region_resource ? *GetUserDataAs<cc::Region>(region_resource) | |
120 : cc::Region()); | |
121 } | |
122 | |
123 void surface_set_input_region(wl_client* client, | |
124 wl_resource* resource, | |
125 wl_resource* region_resource) { | |
126 NOTIMPLEMENTED(); | |
127 } | |
128 | |
129 void surface_commit(wl_client* client, wl_resource* resource) { | |
130 GetUserDataAs<Surface>(resource)->Commit(); | |
131 } | |
132 | |
133 void surface_set_buffer_transform(wl_client* client, | |
134 wl_resource* resource, | |
135 int transform) { | |
136 NOTIMPLEMENTED(); | |
137 } | |
138 | |
139 void surface_set_buffer_scale(wl_client* client, | |
140 wl_resource* resource, | |
141 int32_t scale) { | |
142 NOTIMPLEMENTED(); | |
143 } | |
144 | |
145 const struct wl_surface_interface surface_implementation = { | |
146 surface_destroy, | |
147 surface_attach, | |
148 surface_damage, | |
149 surface_frame, | |
150 surface_set_opaque_region, | |
151 surface_set_input_region, | |
152 surface_commit, | |
153 surface_set_buffer_transform, | |
154 surface_set_buffer_scale}; | |
155 | |
156 //////////////////////////////////////////////////////////////////////////////// | |
157 // wl_region_interface: | |
158 | |
159 void region_destroy(wl_client* client, wl_resource* resource) { | |
160 wl_resource_destroy(resource); | |
161 } | |
162 | |
163 void region_add(wl_client* client, | |
164 wl_resource* resource, | |
165 int32_t x, | |
166 int32_t y, | |
167 int32_t width, | |
168 int32_t height) { | |
169 GetUserDataAs<cc::Region>(resource)->Union(gfx::Rect(x, y, width, height)); | |
170 } | |
171 | |
172 static void region_subtract(wl_client* client, | |
173 wl_resource* resource, | |
174 int32_t x, | |
175 int32_t y, | |
176 int32_t width, | |
177 int32_t height) { | |
178 GetUserDataAs<cc::Region>(resource)->Subtract(gfx::Rect(x, y, width, height)); | |
179 } | |
180 | |
181 const struct wl_region_interface region_implementation = { | |
182 region_destroy, region_add, region_subtract}; | |
183 | |
184 //////////////////////////////////////////////////////////////////////////////// | |
185 // wl_compositor_interface: | |
186 | |
187 void compositor_create_surface(wl_client* client, | |
188 wl_resource* resource, | |
189 uint32_t id) { | |
190 scoped_ptr<Surface> surface = | |
191 GetUserDataAs<Display>(resource)->CreateSurface(); | |
192 DCHECK(surface); | |
193 | |
194 wl_resource* surface_resource = wl_resource_create( | |
195 client, &wl_surface_interface, wl_resource_get_version(resource), id); | |
196 if (!surface_resource) { | |
197 wl_resource_post_no_memory(resource); | |
198 return; | |
199 } | |
200 | |
201 SetImplementation(surface_resource, &surface_implementation, surface.Pass()); | |
202 } | |
203 | |
204 void compositor_create_region(wl_client* client, | |
205 wl_resource* resource, | |
206 uint32_t id) { | |
207 scoped_ptr<cc::Region> region(new cc::Region); | |
208 | |
209 wl_resource* region_resource = | |
210 wl_resource_create(client, &wl_region_interface, 1, id); | |
211 if (!region_resource) { | |
212 wl_resource_post_no_memory(resource); | |
213 return; | |
214 } | |
215 | |
216 SetImplementation(region_resource, ®ion_implementation, region.Pass()); | |
217 } | |
218 | |
219 const struct wl_compositor_interface compositor_implementation = { | |
220 compositor_create_surface, compositor_create_region}; | |
221 | |
222 const uint32_t compositor_version = 3; | |
223 | |
224 void bind_compositor(wl_client* client, | |
225 void* data, | |
226 uint32_t version, | |
227 uint32_t id) { | |
228 wl_resource* resource = | |
229 wl_resource_create(client, &wl_compositor_interface, | |
230 std::min(version, compositor_version), id); | |
231 if (!resource) { | |
232 wl_client_post_no_memory(client); | |
233 return; | |
234 } | |
235 | |
236 wl_resource_set_implementation(resource, &compositor_implementation, data, | |
237 nullptr); | |
238 } | |
239 | |
240 //////////////////////////////////////////////////////////////////////////////// | |
241 // wl_shm_pool_interface: | |
242 | |
243 const struct shm_supported_format { | |
244 uint32_t shm_format; | |
245 gfx::BufferFormat buffer_format; | |
246 } shm_supported_formats[] = { | |
247 {WL_SHM_FORMAT_XBGR8888, gfx::BufferFormat::RGBX_8888}, | |
248 {WL_SHM_FORMAT_ABGR8888, gfx::BufferFormat::RGBA_8888}, | |
249 {WL_SHM_FORMAT_XRGB8888, gfx::BufferFormat::BGRX_8888}, | |
250 {WL_SHM_FORMAT_ARGB8888, gfx::BufferFormat::BGRA_8888}}; | |
251 | |
252 void shm_pool_create_buffer(wl_client* client, | |
253 wl_resource* resource, | |
254 uint32_t id, | |
255 int32_t offset, | |
256 int32_t width, | |
257 int32_t height, | |
258 int32_t stride, | |
259 uint32_t format) { | |
260 const auto supported_format = | |
261 std::find_if(shm_supported_formats, | |
262 shm_supported_formats + arraysize(shm_supported_formats), | |
263 [format](const shm_supported_format& supported_format) { | |
264 return supported_format.shm_format == format; | |
265 }); | |
266 if (supported_format == | |
267 (shm_supported_formats + arraysize(shm_supported_formats))) { | |
268 wl_resource_post_error(resource, WL_SHM_ERROR_INVALID_FORMAT, | |
269 "invalid format 0x%x", format); | |
270 return; | |
271 } | |
272 | |
273 if (offset < 0) { | |
274 wl_resource_post_error(resource, WL_SHM_ERROR_INVALID_FORMAT, | |
275 "invalid offset %d", offset); | |
276 return; | |
277 } | |
278 | |
279 scoped_ptr<Buffer> buffer = | |
280 GetUserDataAs<SharedMemory>(resource) | |
281 ->CreateBuffer(gfx::Size(width, height), | |
282 supported_format->buffer_format, offset, stride); | |
283 if (!buffer) { | |
284 wl_resource_post_no_memory(resource); | |
285 return; | |
286 } | |
287 | |
288 wl_resource* buffer_resource = | |
289 wl_resource_create(client, &wl_buffer_interface, 1, id); | |
290 if (!buffer_resource) { | |
291 wl_resource_post_no_memory(resource); | |
292 return; | |
293 } | |
294 | |
295 buffer->set_release_callback( | |
296 base::Bind(&wl_buffer_send_release, base::Unretained(buffer_resource))); | |
297 | |
298 SetImplementation(buffer_resource, &buffer_implementation, buffer.Pass()); | |
299 } | |
300 | |
301 void shm_pool_destroy(wl_client* client, wl_resource* resource) { | |
302 wl_resource_destroy(resource); | |
303 } | |
304 | |
305 void shm_pool_resize(wl_client* client, wl_resource* resource, int32_t size) { | |
306 // Nothing to do here. | |
307 } | |
308 | |
309 const struct wl_shm_pool_interface shm_pool_implementation = { | |
310 shm_pool_create_buffer, shm_pool_destroy, shm_pool_resize}; | |
311 | |
312 //////////////////////////////////////////////////////////////////////////////// | |
313 // wl_shm_interface: | |
314 | |
315 void shm_create_pool(wl_client* client, | |
316 wl_resource* resource, | |
317 uint32_t id, | |
318 int fd, | |
319 int32_t size) { | |
320 scoped_ptr<SharedMemory> shared_memory = | |
321 GetUserDataAs<Display>(resource) | |
322 ->CreateSharedMemory(base::FileDescriptor(fd, true), size); | |
323 if (!shared_memory) { | |
324 wl_resource_post_no_memory(resource); | |
325 return; | |
326 } | |
327 | |
328 wl_resource* shm_pool_resource = | |
329 wl_resource_create(client, &wl_shm_pool_interface, 1, id); | |
330 if (!shm_pool_resource) { | |
331 wl_resource_post_no_memory(resource); | |
332 return; | |
333 } | |
334 | |
335 SetImplementation(shm_pool_resource, &shm_pool_implementation, | |
336 shared_memory.Pass()); | |
337 } | |
338 | |
339 const struct wl_shm_interface shm_implementation = {shm_create_pool}; | |
340 | |
341 void bind_shm(wl_client* client, void* data, uint32_t version, uint32_t id) { | |
342 wl_resource* resource = wl_resource_create(client, &wl_shm_interface, 1, id); | |
343 if (!resource) { | |
344 wl_client_post_no_memory(client); | |
345 return; | |
346 } | |
347 | |
348 wl_resource_set_implementation(resource, &shm_implementation, data, nullptr); | |
349 | |
350 for (const auto& supported_format : shm_supported_formats) | |
351 wl_shm_send_format(resource, supported_format.shm_format); | |
352 } | |
353 | |
354 //////////////////////////////////////////////////////////////////////////////// | |
355 // wl_shell_surface_interface: | |
356 | |
357 void shell_surface_pong(wl_client* client, | |
358 wl_resource* resource, | |
359 uint32_t serial) { | |
360 NOTIMPLEMENTED(); | |
361 } | |
362 | |
363 void shell_surface_move(wl_client* client, | |
364 wl_resource* resource, | |
365 wl_resource* seat_resource, | |
366 uint32_t serial) { | |
367 NOTIMPLEMENTED(); | |
368 } | |
369 | |
370 void shell_surface_resize(wl_client* client, | |
371 wl_resource* resource, | |
372 wl_resource* seat_resource, | |
373 uint32_t serial, | |
374 uint32_t edges) { | |
375 NOTIMPLEMENTED(); | |
376 } | |
377 | |
378 void shell_surface_set_toplevel(wl_client* client, wl_resource* resource) { | |
379 GetUserDataAs<ShellSurface>(resource)->SetToplevel(); | |
380 } | |
381 | |
382 void shell_surface_set_transient(wl_client* client, | |
383 wl_resource* resource, | |
384 wl_resource* parent_resource, | |
385 int x, | |
386 int y, | |
387 uint32_t flags) { | |
388 NOTIMPLEMENTED(); | |
389 } | |
390 | |
391 void shell_surface_set_fullscreen(wl_client* client, | |
392 wl_resource* resource, | |
393 uint32_t method, | |
394 uint32_t framerate, | |
395 wl_resource* output_resource) { | |
396 GetUserDataAs<ShellSurface>(resource)->SetFullscreen(true); | |
397 } | |
398 | |
399 void shell_surface_set_popup(wl_client* client, | |
400 wl_resource* resource, | |
401 wl_resource* seat_resource, | |
402 uint32_t serial, | |
403 wl_resource* parent_resource, | |
404 int32_t x, | |
405 int32_t y, | |
406 uint32_t flags) { | |
407 NOTIMPLEMENTED(); | |
408 } | |
409 | |
410 void shell_surface_set_maximized(wl_client* client, | |
411 wl_resource* resource, | |
412 wl_resource* output_resource) { | |
413 NOTIMPLEMENTED(); | |
414 } | |
415 | |
416 void shell_surface_set_title(wl_client* client, | |
417 wl_resource* resource, | |
418 const char* title) { | |
419 GetUserDataAs<ShellSurface>(resource) | |
420 ->SetTitle(base::string16(base::ASCIIToUTF16(title))); | |
421 } | |
422 | |
423 void shell_surface_set_class(wl_client* client, | |
424 wl_resource* resource, | |
425 const char* clazz) { | |
426 NOTIMPLEMENTED(); | |
427 } | |
428 | |
429 const struct wl_shell_surface_interface shell_surface_implementation = { | |
430 shell_surface_pong, shell_surface_move, | |
431 shell_surface_resize, shell_surface_set_toplevel, | |
432 shell_surface_set_transient, shell_surface_set_fullscreen, | |
433 shell_surface_set_popup, shell_surface_set_maximized, | |
434 shell_surface_set_title, shell_surface_set_class}; | |
435 | |
436 //////////////////////////////////////////////////////////////////////////////// | |
437 // wl_shell_interface: | |
438 | |
439 void shell_get_shell_surface(wl_client* client, | |
440 wl_resource* resource, | |
441 uint32_t id, | |
442 wl_resource* surface) { | |
443 scoped_ptr<ShellSurface> shell_surface = | |
444 GetUserDataAs<Display>(resource) | |
445 ->CreateShellSurface(GetUserDataAs<Surface>(surface)); | |
446 if (!shell_surface) { | |
447 wl_resource_post_no_memory(resource); | |
448 return; | |
449 } | |
450 | |
451 wl_resource* shell_surface_resource = | |
452 wl_resource_create(client, &wl_shell_surface_interface, 1, id); | |
453 if (!shell_surface_resource) { | |
454 wl_resource_post_no_memory(resource); | |
455 return; | |
456 } | |
457 | |
458 SetImplementation(shell_surface_resource, &shell_surface_implementation, | |
459 shell_surface.Pass()); | |
460 } | |
461 | |
462 const struct wl_shell_interface shell_implementation = { | |
463 shell_get_shell_surface}; | |
464 | |
465 void bind_shell(wl_client* client, void* data, uint32_t version, uint32_t id) { | |
466 wl_resource* resource = | |
467 wl_resource_create(client, &wl_shell_interface, 1, id); | |
468 if (!resource) { | |
469 wl_client_post_no_memory(client); | |
470 return; | |
471 } | |
472 wl_resource_set_implementation(resource, &shell_implementation, data, | |
473 nullptr); | |
474 } | |
475 | |
476 #endif // COMPONENTS_EXO_WAYLAND_WAYLAND_BINDINGS_H_ | |
OLD | NEW |