Chromium Code Reviews| 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 |