blur: Support wtz_blur_behind protocol 40/316740/1 accepted/tizen/unified/20240828.164010 accepted/tizen/unified/dev/20240829.043847 accepted/tizen/unified/x/20240829.020405
authorChangyeon Lee <cyeon.lee@samsung.com>
Thu, 22 Aug 2024 02:52:04 +0000 (11:52 +0900)
committerTizen Window System <tizen.windowsystem@gmail.com>
Tue, 27 Aug 2024 12:14:24 +0000 (21:14 +0900)
Change-Id: I8d05b48842718f28af03c7d5191fa095eab4901e

include/libds-tizen/blur.h
src/blur/blur.c

index 811290853ec389d1aba31f44b54e30eeeeeb6ec2..e66dcbda72d143f938529514158a1c1caf40c622 100644 (file)
@@ -12,6 +12,7 @@ extern "C" {
 struct ds_tizen_blur_manager;
 struct ds_tizen_blur;
 struct ds_tizen_blur_rectangle;
+struct ds_tizen_blur_behind;
 
 enum ds_tizen_blur_state_field {
     DS_TIZEN_BLUR_STATE_NONE = 0,
@@ -28,19 +29,27 @@ struct ds_tizen_blur_state
     uint32_t radius;
 };
 
+enum ds_tizen_blur_behind_state_field {
+    DS_TIZEN_BLUR_BEHIND_STATE_NONE = 0,
+    DS_TIZEN_BLUR_BEHIND_STATE_RADIUS = (1 << 0),
+};
+
+struct ds_tizen_blur_behind_state
+{
+    enum ds_tizen_blur_behind_state_field committed;
+
+    uint32_t radius;
+};
+
 struct ds_tizen_blur_manager *
 ds_tizen_blur_manager_create(struct wl_display *display);
 
 void
-ds_tizen_blur_manager_add_destroy_listener(struct ds_tizen_blur_manager *blur,
+ds_tizen_blur_manager_add_destroy_listener(struct ds_tizen_blur_manager *blur_manager,
         struct wl_listener *listener);
 
 void
-ds_tizen_blur_manager_add_destroy_listener(struct ds_tizen_blur_manager *blur,
-        struct wl_listener *listener);
-
-void
-ds_tizen_blur_manager_add_new_blur_listener(struct ds_tizen_blur_manager *blur,
+ds_tizen_blur_manager_add_new_blur_listener(struct ds_tizen_blur_manager *blur_manager,
         struct wl_listener *listener);
 
 void
@@ -73,6 +82,24 @@ void
 ds_tizen_blur_rectangle_get_corner_radius(struct ds_tizen_blur_rectangle *blur_rectangle,
         int *rx, int *ry);
 
+void
+ds_tizen_blur_manager_add_new_blur_behind_listener(struct ds_tizen_blur_manager *blur,
+        struct wl_listener *listener);
+
+void
+ds_tizen_blur_behind_add_destroy_listener(struct ds_tizen_blur_behind *blur_behind,
+        struct wl_listener *listener);
+
+void
+ds_tizen_blur_behind_add_commit_listener(struct ds_tizen_blur_behind *blur_behind,
+        struct wl_listener *listener);
+
+struct ds_surface *
+ds_tizen_blur_behind_get_surface(struct ds_tizen_blur_behind *blur_behind);
+
+struct ds_tizen_blur_behind_state *
+ds_tizen_blur_behind_get_state(struct ds_tizen_blur_behind *blur_behind);
+
 #ifdef __cplusplus
 }
 #endif
index 4cd388633b0fbb37c95ea50e7d263739a05c7a8d..36e1d4c98465d11778de2a647d40e3f583fa93f8 100644 (file)
@@ -26,6 +26,7 @@ struct ds_tizen_blur_manager
     struct {
         struct wl_signal destroy;
         struct wl_signal new_blur;
+        struct wl_signal new_blur_behind;
     } events;
 };
 
@@ -93,6 +94,26 @@ struct ds_tizen_blur_rectangle
     } events;
 };
 
+struct ds_tizen_blur_behind
+{
+    struct wl_resource *resource;
+    struct wl_client *wl_client;
+
+    struct ds_tizen_blur_behind_state current, pending;
+
+    struct ds_surface *surface;
+    struct ds_addon surface_addon;
+
+    struct {
+        struct wl_listener surface_commit;
+    } listener;
+
+    struct {
+        struct wl_signal commit;
+        struct wl_signal destroy;
+    } events;
+};
+
 static void
 blur_manager_handle_display_destroy(struct wl_listener *listener, void *data);
 static void
@@ -125,6 +146,7 @@ ds_tizen_blur_manager_create(struct wl_display *display)
 
     wl_signal_init(&blur_manager->events.destroy);
     wl_signal_init(&blur_manager->events.new_blur);
+    wl_signal_init(&blur_manager->events.new_blur_behind);
 
     ds_inf("Global created: tizen_blur_manager(%p)", blur_manager);
 
@@ -132,17 +154,17 @@ ds_tizen_blur_manager_create(struct wl_display *display)
 }
 
 WL_EXPORT void
-ds_tizen_blur_manager_add_destroy_listener(struct ds_tizen_blur_manager *blur,
+ds_tizen_blur_manager_add_destroy_listener(struct ds_tizen_blur_manager *blur_manager,
         struct wl_listener *listener)
 {
-    wl_signal_add(&blur->events.destroy, listener);
+    wl_signal_add(&blur_manager->events.destroy, listener);
 }
 
 WL_EXPORT void
-ds_tizen_blur_manager_add_new_blur_listener(struct ds_tizen_blur_manager *blur,
+ds_tizen_blur_manager_add_new_blur_listener(struct ds_tizen_blur_manager *blur_manager,
         struct wl_listener *listener)
 {
-    wl_signal_add(&blur->events.new_blur, listener);
+    wl_signal_add(&blur_manager->events.new_blur, listener);
 }
 
 WL_EXPORT void
@@ -203,6 +225,39 @@ ds_tizen_blur_rectangle_get_corner_radius(struct ds_tizen_blur_rectangle *blur_r
     if (ry) *ry = blur_rectangle->ry;
 }
 
+WL_EXPORT void
+ds_tizen_blur_manager_add_new_blur_behind_listener(struct ds_tizen_blur_manager *blur_manager,
+        struct wl_listener *listener)
+{
+    wl_signal_add(&blur_manager->events.new_blur_behind, listener);
+}
+
+WL_EXPORT void
+ds_tizen_blur_behind_add_destroy_listener(struct ds_tizen_blur_behind *blur_behind,
+        struct wl_listener *listener)
+{
+    wl_signal_add(&blur_behind->events.destroy, listener);
+}
+
+WL_EXPORT void
+ds_tizen_blur_behind_add_commit_listener(struct ds_tizen_blur_behind *blur_behind,
+        struct wl_listener *listener)
+{
+    wl_signal_add(&blur_behind->events.commit, listener);
+}
+
+WL_EXPORT struct ds_surface *
+ds_tizen_blur_behind_get_surface(struct ds_tizen_blur_behind *blur_behind)
+{
+    return blur_behind->surface;
+}
+
+WL_EXPORT struct ds_tizen_blur_behind_state *
+ds_tizen_blur_behind_get_state(struct ds_tizen_blur_behind *blur_behind)
+{
+    return &blur_behind->current;
+}
+
 static void
 blur_manager_handle_display_destroy(struct wl_listener *listener, void *data)
 {
@@ -561,6 +616,180 @@ blur_manager_handle_get_blur(struct wl_client *wl_client,
     wl_signal_emit(&client->blur_manager->events.new_blur, blur);
 }
 
+static void
+blur_behind_destroy(struct ds_tizen_blur_behind *blur_behind)
+{
+    ds_inf("blur_behind_destroy (blur_behind:%p)", blur_behind);
+
+    wl_signal_emit(&blur_behind->events.destroy, blur_behind);
+
+    if (blur_behind->surface) {
+        wl_list_remove(&blur_behind->listener.surface_commit.link);
+        ds_addon_finish(&blur_behind->surface_addon);
+    }
+
+    free(blur_behind);
+}
+
+static void
+blur_behind_handle_resource_destroy(struct wl_resource *resource)
+{
+    struct ds_tizen_blur_behind *blur_behind;
+
+    blur_behind = wl_resource_get_user_data(resource);
+
+    ds_inf("blur_behind_handle_resource_destroy (blur_behind:%p)", blur_behind);
+
+    if (blur_behind->surface) {
+        blur_behind->resource = NULL;
+        return;
+    }
+
+    blur_behind_destroy(blur_behind);
+}
+
+static void
+blur_behind_handle_surface_commit(struct wl_listener *listener, void *data)
+{
+    struct ds_tizen_blur_behind *blur_behind;
+
+    blur_behind = wl_container_of(listener, blur_behind, listener.surface_commit);
+
+    if (!blur_behind->resource) {
+        blur_behind_destroy(blur_behind);
+        return;
+    }
+
+    if (blur_behind->pending.committed == DS_TIZEN_BLUR_BEHIND_STATE_NONE) {
+        blur_behind->current.committed = DS_TIZEN_BLUR_BEHIND_STATE_NONE;
+        return;
+    }
+
+    if (blur_behind->pending.committed & DS_TIZEN_BLUR_BEHIND_STATE_RADIUS)
+        blur_behind->current.radius = blur_behind->pending.radius;
+
+    blur_behind->current.committed = blur_behind->pending.committed;
+    blur_behind->pending.committed = DS_TIZEN_BLUR_BEHIND_STATE_NONE;
+
+    wl_signal_emit(&blur_behind->events.commit, blur_behind);
+}
+
+static void
+blur_behind_handle_surface_destroy(struct ds_addon *addon)
+{
+    struct ds_tizen_blur_behind *blur_behind;
+
+    blur_behind = wl_container_of(addon, blur_behind, surface_addon);
+
+    wl_list_remove(&blur_behind->listener.surface_commit.link);
+
+    ds_addon_finish(&blur_behind->surface_addon);
+    blur_behind->surface = NULL;
+
+    if (!blur_behind->resource)
+        blur_behind_destroy(blur_behind);
+}
+
+static struct ds_addon_interface blur_behind_addon_impl = {
+       .name = "ds_tizen_blur_behind",
+       .destroy = blur_behind_handle_surface_destroy,
+};
+
+static struct ds_tizen_blur_behind *
+blur_behind_client_get_from_surface(struct ds_tizen_blur_client *client, struct ds_surface *surface)
+{
+   struct ds_addon *addon;
+   struct ds_tizen_blur_behind *blur_behind;
+
+    addon = ds_addon_find(&surface->addons, client, &blur_behind_addon_impl);
+    if (!addon) return NULL;
+
+    return wl_container_of(addon, blur_behind, surface_addon);
+}
+
+static void
+blur_behind_handle_destroy(struct wl_client *client, struct wl_resource *resource)
+{
+    wl_resource_destroy(resource);
+}
+
+static void
+blur_behind_handle_set_radius(struct wl_client *client, struct wl_resource *resource,
+        uint32_t radius)
+{
+    struct ds_tizen_blur_behind *blur_behind;
+
+    blur_behind = wl_resource_get_user_data(resource);
+
+    blur_behind->pending.radius = radius;
+    blur_behind->pending.committed |= DS_TIZEN_BLUR_BEHIND_STATE_RADIUS;
+}
+
+static const struct wtz_blur_behind_interface blur_behind_impl = {
+   blur_behind_handle_destroy,
+   blur_behind_handle_set_radius,
+};
+
+static void
+blur_manager_handle_get_blur_behind(struct wl_client *wl_client,
+        struct wl_resource *resource,
+        uint32_t id, struct wl_resource *surface_resource)
+{
+    struct ds_tizen_blur_client *client;
+    struct ds_surface *surface;
+    struct ds_tizen_blur_behind *blur_behind;
+
+    ds_inf("tizen_blur: get_blur");
+
+    client = wl_resource_get_user_data(resource);
+
+    surface = ds_surface_from_resource(surface_resource);
+    if (!surface) {
+        wl_resource_post_error(resource, WL_DISPLAY_ERROR_INVALID_OBJECT,
+                "invalid wl_surface resource:%u",
+                (unsigned int)wl_resource_get_id(surface_resource));
+        return;
+    }
+
+    blur_behind = blur_behind_client_get_from_surface(client, surface);
+    if (blur_behind) {
+        wl_resource_post_error(resource, WTZ_BLUR_MANAGER_ERROR_BLUR_EXISTS,
+                "blend object already exists");
+        return;
+    }
+
+    blur_behind = calloc(1, sizeof *blur_behind);
+    if (blur_behind == NULL) {
+        ds_err("calloc() failed. tizen_blur");
+        wl_client_post_no_memory(wl_client);
+        return;
+    }
+
+    blur_behind->resource = wl_resource_create(wl_client, &wtz_blur_behind_interface,
+           wl_resource_get_version(resource), id);
+    if (blur_behind->resource == NULL) {
+        ds_err("tizen_blur : wl_resource_create() failed.");
+        free(blur_behind);
+        wl_client_post_no_memory(wl_client);
+        return;
+    }
+
+    wl_resource_set_implementation(blur_behind->resource, &blur_behind_impl, blur_behind,
+        blur_behind_handle_resource_destroy);
+
+    ds_addon_init(&blur_behind->surface_addon, &surface->addons, client, &blur_behind_addon_impl);
+
+    blur_behind->listener.surface_commit.notify = blur_behind_handle_surface_commit;
+    ds_surface_add_commit_listener(surface, &blur_behind->listener.surface_commit);
+
+    blur_behind->surface = surface;
+
+    wl_signal_init(&blur_behind->events.destroy);
+    wl_signal_init(&blur_behind->events.commit);
+
+    wl_signal_emit(&client->blur_manager->events.new_blur_behind, blur_behind);
+}
+
 static void
 blur_manager_handle_destroy(struct wl_client *wl_client,
         struct wl_resource *resource)
@@ -572,6 +801,7 @@ static const struct wtz_blur_manager_interface blur_manager_impl =
 {
     blur_manager_handle_destroy,
     blur_manager_handle_get_blur,
+    blur_manager_handle_get_blur_behind,
 };
 
 static void