123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308 |
- // Copyright 2021 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/surface_augmenter.h"
- #include <surface-augmenter-server-protocol.h>
- #include <memory>
- #include "components/exo/buffer.h"
- #include "components/exo/sub_surface.h"
- #include "components/exo/sub_surface_observer.h"
- #include "components/exo/surface.h"
- #include "components/exo/surface_observer.h"
- #include "components/exo/wayland/server_util.h"
- #include "ui/gfx/geometry/rounded_corners_f.h"
- #include "ui/gfx/geometry/rrect_f.h"
- #include "ui/gfx/geometry/size.h"
- namespace exo {
- namespace wayland {
- namespace {
- // A property key containing a boolean set to true if a surface augmenter is
- // associated with with surface object.
- DEFINE_UI_CLASS_PROPERTY_KEY(bool, kSurfaceHasAugmentedSurfaceKey, false)
- DEFINE_UI_CLASS_PROPERTY_KEY(bool, kSubSurfaceHasAugmentedSubSurfaceKey, false)
- ////////////////////////////////////////////////////////////////////////////////
- // augmented_surface_interface:
- // Implements the augmenter interface to a Surface. The "augmented"-state is set
- // to null upon destruction. A window property will be set during the lifetime
- // of this class to prevent multiple instances from being created for the same
- // Surface.
- class AugmentedSurface : public SurfaceObserver {
- public:
- explicit AugmentedSurface(Surface* surface) : surface_(surface) {
- surface_->AddSurfaceObserver(this);
- surface_->SetProperty(kSurfaceHasAugmentedSurfaceKey, true);
- }
- AugmentedSurface(const AugmentedSurface&) = delete;
- AugmentedSurface& operator=(const AugmentedSurface&) = delete;
- ~AugmentedSurface() override {
- if (surface_) {
- surface_->RemoveSurfaceObserver(this);
- surface_->SetProperty(kSurfaceHasAugmentedSurfaceKey, false);
- }
- }
- void SetCorners(int32_t x,
- int32_t y,
- int32_t width,
- int32_t height,
- double top_left,
- double top_right,
- double bottom_right,
- double bottom_left) {
- surface_->SetRoundedCorners(gfx::RRectF(
- gfx::RectF(x, y, width, height),
- gfx::RoundedCornersF(top_left, top_right, bottom_right, bottom_left)));
- }
- void SetDestination(float width, float height) {
- surface_->SetViewport(gfx::SizeF(width, height));
- }
- void SetBackgroundColor(absl::optional<SkColor4f> background_color) {
- surface_->SetBackgroundColor(background_color);
- }
- // SurfaceObserver:
- void OnSurfaceDestroying(Surface* surface) override {
- surface->RemoveSurfaceObserver(this);
- surface_ = nullptr;
- }
- private:
- Surface* surface_;
- };
- void augmented_surface_destroy(wl_client* client, wl_resource* resource) {
- wl_resource_destroy(resource);
- }
- void augmented_surface_set_corners_DEPRECATED(wl_client* client,
- wl_resource* resource,
- wl_fixed_t top_left,
- wl_fixed_t top_right,
- wl_fixed_t bottom_right,
- wl_fixed_t bottom_left) {
- LOG(WARNING) << "Deprecated. The server doesn't support this request.";
- }
- void augmented_surface_set_destination_size(wl_client* client,
- wl_resource* resource,
- wl_fixed_t width,
- wl_fixed_t height) {
- if (width < 0 || height < 0) {
- wl_resource_post_error(resource, AUGMENTED_SURFACE_ERROR_BAD_VALUE,
- "Dimension can't be negative (%d, %d)", width,
- height);
- return;
- }
- GetUserDataAs<AugmentedSurface>(resource)->SetDestination(
- wl_fixed_to_double(width), wl_fixed_to_double(height));
- }
- void augmented_surface_set_rounded_corners_bounds(wl_client* client,
- wl_resource* resource,
- int32_t x,
- int32_t y,
- int32_t width,
- int32_t height,
- wl_fixed_t top_left,
- wl_fixed_t top_right,
- wl_fixed_t bottom_right,
- wl_fixed_t bottom_left) {
- if (width < 0 || height < 0 || top_left < 0 || bottom_left < 0 ||
- bottom_right < 0 || top_right < 0) {
- wl_resource_post_error(resource, AUGMENTED_SURFACE_ERROR_BAD_VALUE,
- "The size and corners must have positive values "
- "(%d, %d, %d, %d, %d, %d)",
- width, height, top_left, top_right, bottom_right,
- bottom_left);
- return;
- }
- GetUserDataAs<AugmentedSurface>(resource)->SetCorners(
- x, y, width, height, wl_fixed_to_double(top_left),
- wl_fixed_to_double(top_right), wl_fixed_to_double(bottom_right),
- wl_fixed_to_double(bottom_left));
- }
- void augmented_surface_set_background_color(wl_client* client,
- wl_resource* resource,
- wl_array* color_data) {
- absl::optional<SkColor4f> sk_color;
- // Empty data means no color.
- if (color_data->size) {
- float* data = reinterpret_cast<float*>(color_data->data);
- sk_color = {data[0], data[1], data[2], data[3]};
- }
- GetUserDataAs<AugmentedSurface>(resource)->SetBackgroundColor(sk_color);
- }
- const struct augmented_surface_interface augmented_implementation = {
- augmented_surface_destroy, augmented_surface_set_corners_DEPRECATED,
- augmented_surface_set_destination_size,
- augmented_surface_set_rounded_corners_bounds,
- augmented_surface_set_background_color};
- ////////////////////////////////////////////////////////////////////////////////
- // augmented_sub_surface_interface:
- // Implements the augmenter interface to a Surface. The "augmented"-state is set
- // to null upon destruction. A window property will be set during the lifetime
- // of this class to prevent multiple instances from being created for the same
- // Surface.
- class AugmentedSubSurface : public SubSurfaceObserver {
- public:
- explicit AugmentedSubSurface(SubSurface* sub_surface)
- : sub_surface_(sub_surface) {
- sub_surface_->AddSubSurfaceObserver(this);
- sub_surface_->SetProperty(kSubSurfaceHasAugmentedSubSurfaceKey, true);
- }
- AugmentedSubSurface(const AugmentedSubSurface&) = delete;
- AugmentedSubSurface& operator=(const AugmentedSubSurface&) = delete;
- ~AugmentedSubSurface() override {
- if (sub_surface_) {
- sub_surface_->SetProperty(kSubSurfaceHasAugmentedSubSurfaceKey, false);
- sub_surface_->RemoveSubSurfaceObserver(this);
- }
- }
- void SetPosition(float x, float y) {
- sub_surface_->SetPosition(gfx::PointF(x, y));
- }
- // SurfaceObserver:
- void OnSubSurfaceDestroying(SubSurface* sub_surface) override {
- sub_surface->RemoveSubSurfaceObserver(this);
- sub_surface_ = nullptr;
- }
- private:
- SubSurface* sub_surface_;
- };
- void augmented_sub_surface_destroy(wl_client* client, wl_resource* resource) {
- wl_resource_destroy(resource);
- }
- void augmented_sub_surface_set_position(wl_client* client,
- wl_resource* resource,
- wl_fixed_t x,
- wl_fixed_t y) {
- GetUserDataAs<AugmentedSubSurface>(resource)->SetPosition(
- wl_fixed_to_double(x), wl_fixed_to_double(y));
- }
- const struct augmented_sub_surface_interface
- augmented_sub_surface_implementation = {augmented_sub_surface_destroy,
- augmented_sub_surface_set_position};
- ////////////////////////////////////////////////////////////////////////////////
- // wl_buffer_interface:
- void buffer_destroy(wl_client* client, wl_resource* resource) {
- wl_resource_destroy(resource);
- }
- const struct wl_buffer_interface buffer_implementation = {buffer_destroy};
- ////////////////////////////////////////////////////////////////////////////////
- // surface_augmenter_interface:
- void augmenter_destroy(wl_client* client, wl_resource* resource) {
- wl_resource_destroy(resource);
- }
- void HandleBufferReleaseCallback(wl_resource* resource) {
- wl_buffer_send_release(resource);
- wl_client_flush(wl_resource_get_client(resource));
- }
- void augmenter_create_solid_color_buffer(wl_client* client,
- wl_resource* resource,
- uint32_t id,
- wl_array* color_data,
- int width,
- int height) {
- float* data = reinterpret_cast<float*>(color_data->data);
- SkColor4f color = {data[0], data[1], data[2], data[3]};
- std::unique_ptr<SolidColorBuffer> buffer =
- std::make_unique<SolidColorBuffer>(color, gfx::Size(width, height));
- wl_resource* buffer_resource = wl_resource_create(
- client, &wl_buffer_interface, wl_resource_get_version(resource), id);
- buffer->set_release_callback(base::BindRepeating(
- &HandleBufferReleaseCallback, base::Unretained(buffer_resource)));
- SetImplementation(buffer_resource, &buffer_implementation, std::move(buffer));
- }
- void augmenter_get_augmented_surface(wl_client* client,
- wl_resource* resource,
- uint32_t id,
- wl_resource* surface_resource) {
- Surface* surface = GetUserDataAs<Surface>(surface_resource);
- if (surface->GetProperty(kSurfaceHasAugmentedSurfaceKey)) {
- wl_resource_post_error(resource,
- SURFACE_AUGMENTER_ERROR_AUGMENTED_SURFACE_EXISTS,
- "an augmenter for that surface already exists");
- return;
- }
- wl_resource* augmented_resource =
- wl_resource_create(client, &augmented_surface_interface,
- wl_resource_get_version(resource), id);
- SetImplementation(augmented_resource, &augmented_implementation,
- std::make_unique<AugmentedSurface>(surface));
- }
- void augmenter_get_augmented_sub_surface(wl_client* client,
- wl_resource* resource,
- uint32_t id,
- wl_resource* sub_surface_resource) {
- SubSurface* sub_surface = GetUserDataAs<SubSurface>(sub_surface_resource);
- if (sub_surface->GetProperty(kSubSurfaceHasAugmentedSubSurfaceKey)) {
- wl_resource_post_error(resource,
- SURFACE_AUGMENTER_ERROR_AUGMENTED_SURFACE_EXISTS,
- "an augmenter for that sub-surface already exists");
- return;
- }
- wl_resource* augmented_resource =
- wl_resource_create(client, &augmented_sub_surface_interface,
- wl_resource_get_version(resource), id);
- SetImplementation(augmented_resource, &augmented_sub_surface_implementation,
- std::make_unique<AugmentedSubSurface>(sub_surface));
- }
- const struct surface_augmenter_interface augmenter_implementation = {
- augmenter_destroy, augmenter_create_solid_color_buffer,
- augmenter_get_augmented_surface, augmenter_get_augmented_sub_surface};
- } // namespace
- void bind_surface_augmenter(wl_client* client,
- void* data,
- uint32_t version,
- uint32_t id) {
- wl_resource* resource =
- wl_resource_create(client, &surface_augmenter_interface,
- std::min(version, kSurfaceAugmenterVersion), id);
- wl_resource_set_implementation(resource, &augmenter_implementation, data,
- nullptr);
- }
- } // namespace wayland
- } // namespace exo
|