--- /dev/null
+#include "e.h"
+#include <pixman.h>
+#include <libds-tizen/blur.h>
+
+typedef struct _E_Blur_Manager E_Blur_Manager;
+typedef struct _E_Blur E_Blur;
+typedef struct _E_Blur_Object E_Blur_Object;
+
+struct _E_Blur_Manager
+{
+ struct ds_tizen_blur_manager *tizen_blur_manager;
+
+ struct wl_listener destroy_listener;
+ struct wl_listener new_blur_listener;
+};
+
+struct _E_Blur
+{
+ struct ds_tizen_blur *tizen_blur;
+ struct wl_listener commit_listener;
+ struct wl_listener destroy_listener;
+
+ E_Client *ec;
+ E_Object_Delfn *ec_delfn;
+
+ pixman_region32_t region;
+ uint32_t radius;
+
+ Eina_List *blur_objs;
+};
+
+struct _E_Blur_Object
+{
+ int x, y, w, h;
+
+ Evas_Object *obj;
+};
+
+static E_Blur_Manager *_blur_manager = NULL;
+
+static void _e_blur_ec_set(E_Blur *blur, E_Client *ec);
+
+static E_Blur_Object *
+_e_blur_object_create(int x, int y, int w, int h)
+{
+ E_Blur_Object *blur_obj;
+ Evas_Object *obj;
+
+ blur_obj = E_NEW(E_Blur_Object, 1);
+ EINA_SAFETY_ON_FALSE_RETURN_VAL(blur_obj, NULL);
+
+ blur_obj->x = x;
+ blur_obj->y = y;
+ blur_obj->w = w;
+ blur_obj->h = h;
+
+ obj = evas_object_image_filled_add(e_comp->evas);
+ EINA_SAFETY_ON_NULL_GOTO(obj, fail);
+
+ evas_object_image_snapshot_set(obj, EINA_TRUE);
+ evas_object_name_set(obj, "blur_obj");
+
+ blur_obj->obj = obj;
+
+ return blur_obj;
+
+fail:
+ free(blur_obj);
+
+ return NULL;
+}
+
+static void
+_e_blur_object_destroy(E_Blur_Object *blur_obj)
+{
+ evas_object_del(blur_obj->obj);
+ free(blur_obj);
+}
+
+static void
+_e_blur_free(E_Blur *blur)
+{
+ E_Blur_Object *blur_obj;
+
+ ELOGF("E_BLUR", "E_Blur:%p Free", blur->ec, blur);
+
+ _e_blur_ec_set(blur, NULL);
+
+ EINA_LIST_FREE(blur->blur_objs, blur_obj)
+ _e_blur_object_destroy(blur_obj);
+
+ pixman_region32_fini(&blur->region);
+ free(blur);
+}
+
+static void
+_e_blur_object_geometry_set(E_Blur_Object *blur_obj, E_Client *ec)
+{
+ int ec_x, ec_y, ec_w, ec_h;
+ int evas_x, evas_y, evas_w, evas_h;
+ double scale_w, scale_h;
+
+ evas_object_geometry_get(ec->frame, &evas_x, &evas_y, &evas_w, &evas_h);
+
+ if (e_client_transform_core_enable_get(ec))
+ {
+ e_client_geometry_get(ec, &ec_x, &ec_y, &ec_w, &ec_h);
+
+ scale_w = (double)ec_w / (double)evas_w;
+ scale_h = (double)ec_h / (double)evas_h;
+
+ evas_object_geometry_set(blur_obj->obj,
+ ec_x + blur_obj->x,
+ ec_y + blur_obj->y,
+ (int)((double)blur_obj->w * scale_w),
+ (int)((double)blur_obj->h * scale_h));
+ }
+ else
+ {
+ evas_object_geometry_set(blur_obj->obj,
+ evas_x + blur_obj->x,
+ evas_y + blur_obj->y,
+ blur_obj->w,
+ blur_obj->h);
+ }
+}
+
+static void
+_e_blur_cb_ds_tizen_blur_commit(struct wl_listener *listener, void *data)
+{
+ E_Blur *blur;
+ E_Blur_Object *blur_obj;
+ pixman_box32_t *rects;
+ int rects_count, i;
+ char program[1024];
+ Eina_List *l;
+ struct ds_tizen_blur_state *state;
+
+ blur = container_of(listener, E_Blur, commit_listener);
+ if (!blur) return;
+ if (!blur->ec) return;
+
+ state = ds_tizen_blur_get_state(blur->tizen_blur);
+ if (!state) return;
+
+ blur->radius = state->radius;
+ pixman_region32_copy(&blur->region, &state->region);
+
+ if (blur->radius)
+ {
+ snprintf(program, sizeof(program), "blur (%d) padding_set (0)", blur->radius);
+
+ if (state->committed & DS_TIZEN_BLUR_STATE_REGION)
+ {
+ EINA_LIST_FREE(blur->blur_objs, blur_obj)
+ _e_blur_object_destroy(blur_obj);
+
+ rects = pixman_region32_rectangles(&blur->region, &rects_count);
+ for (i = 0; i < rects_count; i++)
+ {
+ blur_obj = _e_blur_object_create(rects[i].x1,
+ rects[i].y1,
+ rects[i].x2 - rects[i].x1,
+ rects[i].y2 - rects[i].y1);
+ EINA_SAFETY_ON_NULL_RETURN(blur_obj);
+
+ _e_blur_object_geometry_set(blur_obj, blur->ec);
+
+ efl_gfx_filter_program_set(blur_obj->obj, program, "image_filter");
+ evas_object_layer_set(blur_obj->obj, blur->ec->layer);
+ evas_object_stack_below(blur_obj->obj, blur->ec->frame);
+
+ if (evas_object_visible_get(blur->ec->frame))
+ evas_object_show(blur_obj->obj);
+
+ blur->blur_objs = eina_list_append(blur->blur_objs, blur_obj);
+
+ ELOGF("E_BLUR", "E_Blur:%p set blur_obj:%p %dx%d+%d+%d radius:%d",
+ blur->ec, blur, blur_obj,
+ blur_obj->w, blur_obj->h, blur_obj->x, blur_obj->y,
+ blur->radius);
+ }
+ }
+ else if (state->committed & DS_TIZEN_BLUR_STATE_RADIUS)
+ {
+ EINA_LIST_FOREACH(blur->blur_objs, l, blur_obj)
+ {
+ efl_gfx_filter_program_set(blur_obj->obj, program, "image_filter");
+
+ ELOGF("E_BLUR", "E_Blur:%p set blur_obj:%p radius:%d",
+ blur->ec, blur, blur_obj, blur->radius);
+ }
+ }
+ }
+ else
+ {
+ EINA_LIST_FREE(blur->blur_objs, blur_obj)
+ _e_blur_object_destroy(blur_obj);
+ }
+}
+
+static void
+_e_blur_evas_cb_show(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
+{
+ E_Blur *blur;
+ Eina_List *l;
+ E_Blur_Object *blur_obj;
+
+ if (!(blur = data)) return;
+
+ EINA_LIST_FOREACH(blur->blur_objs, l, blur_obj)
+ evas_object_show(blur_obj->obj);
+}
+
+static void
+_e_blur_evas_cb_hide(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
+{
+ E_Blur *blur;
+ Eina_List *l;
+ E_Blur_Object *blur_obj;
+
+ if (!(blur = data)) return;
+
+ EINA_LIST_FOREACH(blur->blur_objs, l, blur_obj)
+ evas_object_hide(blur_obj->obj);
+}
+
+static void
+_e_blur_evas_cb_resize(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
+{
+ E_Blur *blur;
+ Eina_List *l;
+ E_Blur_Object *blur_obj;
+
+ if (!(blur = data)) return;
+
+ EINA_LIST_FOREACH(blur->blur_objs, l, blur_obj)
+ _e_blur_object_geometry_set(blur_obj, blur->ec);
+}
+
+static void
+_e_blur_evas_cb_move(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
+{
+ E_Blur *blur;
+ Eina_List *l;
+ E_Blur_Object *blur_obj;
+
+ if (!(blur = data)) return;
+
+ EINA_LIST_FOREACH(blur->blur_objs, l, blur_obj)
+ _e_blur_object_geometry_set(blur_obj, blur->ec);
+}
+
+static void
+_e_blur_evas_cb_restack(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
+{
+ E_Blur *blur;
+ Eina_List *l;
+ E_Blur_Object *blur_obj;
+
+ if (!(blur = data)) return;
+
+ EINA_LIST_FOREACH(blur->blur_objs, l, blur_obj)
+ evas_object_stack_below(blur_obj->obj, obj);
+}
+
+static void
+_e_blur_cb_ec_free(void *data, void *obj)
+{
+ E_Blur *blur = data;
+
+ blur->ec_delfn = NULL;
+ _e_blur_ec_set(blur, NULL);
+}
+
+static void
+_e_blur_ec_set(E_Blur *blur, E_Client *ec)
+{
+ if (blur->ec == ec) return;
+
+ if (blur->ec)
+ {
+ evas_object_event_callback_del(blur->ec->frame, EVAS_CALLBACK_SHOW,
+ _e_blur_evas_cb_show);
+ evas_object_event_callback_del(blur->ec->frame, EVAS_CALLBACK_HIDE,
+ _e_blur_evas_cb_hide);
+ evas_object_event_callback_del(blur->ec->frame, EVAS_CALLBACK_RESIZE,
+ _e_blur_evas_cb_resize);
+ evas_object_event_callback_del(blur->ec->frame, EVAS_CALLBACK_MOVE,
+ _e_blur_evas_cb_move);
+ evas_object_event_callback_del(blur->ec->frame, EVAS_CALLBACK_RESTACK,
+ _e_blur_evas_cb_restack);
+
+ if (blur->ec_delfn)
+ {
+ e_object_delfn_del(E_OBJECT(blur->ec), blur->ec_delfn);
+ blur->ec_delfn = NULL;
+ }
+
+ blur->ec = NULL;
+ }
+
+ if (ec)
+ {
+ evas_object_event_callback_add(ec->frame, EVAS_CALLBACK_SHOW,
+ _e_blur_evas_cb_show, blur);
+ evas_object_event_callback_add(ec->frame, EVAS_CALLBACK_HIDE,
+ _e_blur_evas_cb_hide, blur);
+ evas_object_event_callback_add(ec->frame, EVAS_CALLBACK_RESIZE,
+ _e_blur_evas_cb_resize, blur);
+ evas_object_event_callback_add(ec->frame, EVAS_CALLBACK_MOVE,
+ _e_blur_evas_cb_move, blur);
+ evas_object_event_callback_add(ec->frame, EVAS_CALLBACK_RESTACK,
+ _e_blur_evas_cb_restack, blur);
+
+ blur->ec_delfn = e_object_delfn_add(E_OBJECT(ec),
+ _e_blur_cb_ec_free,
+ blur);
+ blur->ec = ec;
+ }
+}
+
+static void
+_e_blur_cb_ds_tizen_blur_destroy(struct wl_listener *listener, void *data)
+{
+ E_Blur *blur;
+
+ blur = wl_container_of(listener, blur, destroy_listener);
+ if (!blur) return;
+
+ _e_blur_free(blur);
+}
+
+static void
+_e_blur_manager_cb_new_blur(struct wl_listener *listener, void *data)
+{
+ E_Blur *blur = NULL;
+ E_Blur_Manager *blur_manager = _blur_manager;
+ struct ds_tizen_blur *tizen_blur = data;
+ struct ds_surface *surface;
+ struct wl_resource *surface_resource;
+ E_Client *ec;
+
+ if (!blur_manager)
+ {
+ ERR("blur is not initialized");
+ return;
+ }
+
+ surface = ds_tizen_blur_get_surface(tizen_blur);
+ EINA_SAFETY_ON_NULL_RETURN(surface);
+
+ surface_resource = ds_surface_get_wl_resource(surface);
+ EINA_SAFETY_ON_NULL_RETURN(surface_resource);
+
+ ec = e_client_from_surface_resource(surface_resource);
+ EINA_SAFETY_ON_NULL_RETURN(ec);
+
+ blur = E_NEW(E_Blur, 1);
+ EINA_SAFETY_ON_NULL_RETURN(blur);
+
+ blur->destroy_listener.notify = _e_blur_cb_ds_tizen_blur_destroy;
+ ds_tizen_blur_add_destroy_listener(tizen_blur, &blur->destroy_listener);
+
+ blur->commit_listener.notify = _e_blur_cb_ds_tizen_blur_commit;
+ ds_tizen_blur_add_commit_listener(tizen_blur, &blur->commit_listener);
+
+ blur->tizen_blur = tizen_blur;
+
+ pixman_region32_init_rect(&blur->region, 0, 0, ec->w, ec->h);
+
+ _e_blur_ec_set(blur, ec);
+
+ ELOGF("E_BLUR", "E_Blur:%p Create", ec, blur);
+
+ return;
+}
+
+static void
+_e_blur_manager_cb_destroy(struct wl_listener *listener, void *data)
+{
+ E_Blur_Manager *blur_manager;
+
+ blur_manager = container_of(listener, E_Blur_Manager, destroy_listener);
+
+ free(blur_manager);
+
+ _blur_manager = NULL;
+}
+
+EINTERN Eina_Bool
+e_blur_manager_init(void)
+{
+ E_Blur_Manager *blur_manager;
+
+ EINA_SAFETY_ON_NULL_RETURN_VAL(e_comp_wl, EINA_FALSE);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(e_comp_wl->wl.disp, EINA_FALSE);
+
+ if (_blur_manager) return EINA_TRUE;
+
+ blur_manager = E_NEW(E_Blur_Manager, 1);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(blur_manager, EINA_FALSE);
+
+ blur_manager->tizen_blur_manager = ds_tizen_blur_manager_create(e_comp_wl->wl.disp);
+ EINA_SAFETY_ON_NULL_GOTO(blur_manager, fail);
+
+ blur_manager->destroy_listener.notify = _e_blur_manager_cb_destroy;
+ ds_tizen_blur_manager_add_destroy_listener(blur_manager->tizen_blur_manager,
+ &blur_manager->destroy_listener);
+
+ blur_manager->new_blur_listener.notify = _e_blur_manager_cb_new_blur;
+ ds_tizen_blur_manager_add_new_blur_listener(blur_manager->tizen_blur_manager,
+ &blur_manager->new_blur_listener);
+
+ _blur_manager = blur_manager;
+
+ return EINA_TRUE;
+
+fail:
+ free(blur_manager);
+
+ return EINA_FALSE;
+}