}
static void
-_e_hwc_window_cb_blur_set(void *data, E_Blur *blur)
+_e_hwc_window_cb_blur_set(void *data, E_Blur_Hook_Data *hook_data)
{
E_Client *ec;
E_Hwc_Window *hwc_window;
+ E_Blur *blur = hook_data->blur;
ec = e_blur_client_get(blur);
if (!ec) return;
}
static void
-_e_hwc_window_cb_blur_unset(void *data, E_Blur *blur)
+_e_hwc_window_cb_blur_unset(void *data, E_Blur_Hook_Data *hook_data)
{
E_Client *ec;
E_Hwc_Window *hwc_window;
+ E_Blur *blur = hook_data->blur;
ec = e_blur_client_get(blur);
if (!ec) return;
e_hwc_window_changed_set(hwc_window, E_HWC_WINS_CHANGED_WIN_VISIBLE);
}
+static void
+_e_hwc_window_cb_blur_behind_set(void *data, E_Blur_Hook_Data *hook_data)
+{
+ E_Client *ec;
+ E_Hwc_Window *hwc_window;
+ E_Blur_Behind *blur_behind = hook_data->blur_behind;
+
+ ec = e_blur_behind_client_get(blur_behind);
+ if (!ec) return;
+
+ hwc_window = ec->hwc_window;
+ if (!hwc_window) return;
+
+ e_hwc_window_changed_set(hwc_window, E_HWC_WINS_CHANGED_WIN_VISIBLE);
+}
+
+static void
+_e_hwc_window_cb_blur_behind_unset(void *data, E_Blur_Hook_Data *hook_data)
+{
+ E_Client *ec;
+ E_Hwc_Window *hwc_window;
+ E_Blur_Behind *blur_behind = hook_data->blur_behind;
+
+ ec = e_blur_behind_client_get(blur_behind);
+ if (!ec) return;
+
+ hwc_window = ec->hwc_window;
+ if (!hwc_window) return;
+
+ e_hwc_window_changed_set(hwc_window, E_HWC_WINS_CHANGED_WIN_VISIBLE);
+}
+
EINTERN Eina_Bool
e_hwc_window_init(void)
{
_e_hwc_window_cb_blur_set, NULL);
E_BLUR_HOOK_APPEND(hwc_window_blur_hooks, E_BLUR_HOOK_UNSET,
_e_hwc_window_cb_blur_unset, NULL);
-
+ E_BLUR_HOOK_APPEND(hwc_window_blur_hooks, E_BLUR_HOOK_BEHIND_SET,
+ _e_hwc_window_cb_blur_behind_set, NULL);
+ E_BLUR_HOOK_APPEND(hwc_window_blur_hooks, E_BLUR_HOOK_BEHIND_UNSET,
+ _e_hwc_window_cb_blur_behind_unset, NULL);
return EINA_TRUE;
}
struct {
struct wl_listener destroy;
struct wl_listener new_blur;
+ struct wl_listener new_blur_behind;
} listener;
Eina_Bool video_capture_enabled;
Eina_Bool blur_enabled;
+ Eina_Bool blur_behind_enabled;
Eina_List *blurs;
+ Eina_List *blurs_behind;
};
struct _E_Blur
struct ds_tizen_blur *tizen_blur;
struct {
- struct wl_listener surface_commit;
+ struct wl_listener commit;
struct wl_listener destroy;
struct wl_listener new_rectangle;
} listener;
Evas_Object *obj;
};
+struct _E_Blur_Behind
+{
+ struct ds_tizen_blur_behind *tizen_blur_behind;
+
+ struct {
+ struct wl_listener commit;
+ struct wl_listener destroy;
+ } listener;
+
+ E_Client *ec;
+ E_Object_Delfn *ec_delfn;
+
+ uint32_t radius;
+ Evas_Object *obj;
+
+ Eina_Bool enabled;
+};
+
static int _e_blur_hooks_delete = 0;
static int _e_blur_hooks_walking = 0;
[E_BLUR_HOOK_SET] = NULL,
[E_BLUR_HOOK_UNSET] = NULL,
[E_BLUR_HOOK_RECTANGLE_CREATE] = NULL,
+ [E_BLUR_HOOK_BEHIND_CREATE] = NULL,
+ [E_BLUR_HOOK_BEHIND_SET] = NULL,
+ [E_BLUR_HOOK_BEHIND_UNSET] = NULL,
};
static E_Blur_Manager *_blur_manager = NULL;
static Eina_Bool blur_trace = EINA_FALSE;
static void _e_blur_ec_set(E_Blur *blur, E_Client *ec);
+static void _e_blur_behind_ec_set(E_Blur_Behind *blur, E_Client *ec);
static void
_e_blur_hooks_clean(void)
}
static void
-_e_blur_hook_call(E_Blur_Hook_Point hookpoint, E_Blur *blur)
+_e_blur_hook_call(E_Blur_Hook_Point hookpoint, E_Blur_Hook_Data *hook_data)
{
E_Blur_Hook *ch;
EINA_INLIST_FOREACH(_e_blur_hooks[hookpoint], ch)
{
if (ch->delete_me) continue;
- ch->func(ch->data, blur);
+ ch->func(ch->data, hook_data);
}
_e_blur_hooks_walking--;
if ((_e_blur_hooks_walking == 0) && (_e_blur_hooks_delete > 0))
E_Blur *blur;
Eina_List *l;
- if (set)
- {
- if (blur_manager->blur_enabled == set)
- return;
+ if (blur_manager->blur_enabled == set)
+ return;
- if (!blur_manager->video_capture_enabled)
- e_video_debug_display_primary_plane_set(EINA_TRUE);
- }
- else
+ if (!set)
{
EINA_LIST_FOREACH(blur_manager->blurs, l, blur)
{
if (_e_blur_enabled_get(blur))
return;
}
-
- if (blur_manager->blur_enabled == set)
- return;
-
- if (!blur_manager->video_capture_enabled)
- e_video_debug_display_primary_plane_set(EINA_FALSE);
}
blur_manager->blur_enabled = set;
+
+ if (blur_manager->video_capture_enabled)
+ return;
+
+ if (blur_manager->blur_enabled || blur_manager->blur_behind_enabled)
+ e_video_debug_display_primary_plane_set(EINA_TRUE);
+ else
+ e_video_debug_display_primary_plane_set(EINA_FALSE);
}
static void
_e_blur_enabled_set(E_Blur *blur, Eina_Bool set)
{
+ E_Blur_Hook_Data hook_data = { .blur = blur };
+
if (blur->enabled == set) return;
blur->enabled = set;
if (set)
- _e_blur_hook_call(E_BLUR_HOOK_SET, blur);
+ _e_blur_hook_call(E_BLUR_HOOK_SET, &hook_data);
else
- _e_blur_hook_call(E_BLUR_HOOK_UNSET, blur);
+ _e_blur_hook_call(E_BLUR_HOOK_UNSET, &hook_data);
_e_blur_manager_blur_enabled_changed(set);
}
static void
-_e_blur_rectangle_free(E_Blur_Rectangle *blur_rectangle)
+_e_blur_rectangle_add(E_Blur *blur, E_Blur_Rectangle *blur_rectangle)
{
- E_Blur *blur;
+ blur->blur_rectangles = eina_list_append(blur->blur_rectangles, blur_rectangle);
+}
+
+static void
+_e_blur_rectangle_remove(E_Blur *blur, E_Blur_Rectangle *blur_rectangle)
+{
+ blur->blur_rectangles = eina_list_remove(blur->blur_rectangles, blur_rectangle);
+
+ if (!eina_list_count(blur->blur_rectangles))
+ _e_blur_enabled_set(blur, EINA_FALSE);
+}
+static void
+_e_blur_rectangle_free(E_Blur_Rectangle *blur_rectangle)
+{
ELOGF("E_BLUR", "E_Blur_Rectangle:%p Free", NULL, blur_rectangle);
- blur = blur_rectangle->blur;
- blur->blur_rectangles = eina_list_remove(blur->blur_rectangles, blur_rectangle);
+ _e_blur_rectangle_remove(blur_rectangle->blur, blur_rectangle);
evas_object_del(blur_rectangle->obj);
E_Blur *blur;
E_Blur_Rectangle *blur_rectangle;
Eina_List *l;
- struct ds_tizen_blur_state *state;
+ const struct ds_tizen_blur_state *state;
Eina_Bool radius_changed = EINA_FALSE, rectangle_changed = EINA_FALSE;
- blur = container_of(listener, E_Blur, listener.surface_commit);
+ blur = container_of(listener, E_Blur, listener.commit);
if (!blur->ec) return;
state = ds_tizen_blur_get_state(blur->tizen_blur);
{
blur->radius = state->radius;
radius_changed = EINA_TRUE;
+ ELOGF("E_BLUR", "E_Blur:%p Radius:%d changed", NULL, blur, blur->radius);
}
if (state->committed & DS_TIZEN_BLUR_STATE_RECTANGLE)
{
E_Blur_Rectangle *blur_rectangle;
E_Blur *blur;
+ E_Blur_Hook_Data hook_data;
blur_rectangle = wl_container_of(listener, blur_rectangle, listener.destroy);
blur = blur_rectangle->blur;
_e_blur_rectangle_free(blur_rectangle);
if (!eina_list_count(blur->blur_rectangles))
- _e_blur_hook_call(E_BLUR_HOOK_UNSET, blur);
+ {
+ hook_data.blur = blur;
+ _e_blur_hook_call(E_BLUR_HOOK_UNSET, &hook_data);
+ }
}
static void
E_Blur_Rectangle *blur_rectangle;
struct ds_tizen_blur_rectangle *tizen_blur_rectangle = data;
Evas_Object *obj;
+ E_Blur_Hook_Data hook_data;
blur = wl_container_of(listener, blur, listener.new_rectangle);
EINA_SAFETY_ON_NULL_RETURN(blur);
ds_tizen_blur_rectangle_add_destroy_listener(tizen_blur_rectangle, &blur_rectangle->listener.destroy);
blur_rectangle->tizen_blur_rectangle = tizen_blur_rectangle;
- evas_object_image_snapshot_set(obj, EINA_TRUE);
- evas_object_name_set(obj, "blur_obj");
blur_rectangle->obj = obj;
-
+ evas_object_image_snapshot_set(blur_rectangle->obj, EINA_TRUE);
+ evas_object_name_set(blur_rectangle->obj, "blur_obj");
blur_rectangle->blur = blur;
- blur->blur_rectangles = eina_list_append(blur->blur_rectangles, blur_rectangle);
-
+ _e_blur_rectangle_add(blur, blur_rectangle);
_e_blur_rectangle_filter_set(blur_rectangle);
_e_blur_rectangle_geometry_set(blur_rectangle, blur->ec);
evas_object_layer_set(blur_rectangle->obj, evas_object_layer_get(blur->ec->frame));
ELOGF("E_BLUR", "E_Blur_Rectangle:%p Create", blur->ec, blur_rectangle);
- _e_blur_hook_call(E_BLUR_HOOK_RECTANGLE_CREATE, blur);
+ hook_data.blur_rectangle = blur_rectangle;
+ _e_blur_hook_call(E_BLUR_HOOK_RECTANGLE_CREATE, &hook_data);
}
static void
blur->listener.destroy.notify = _e_blur_cb_ds_tizen_blur_destroy;
ds_tizen_blur_add_destroy_listener(tizen_blur, &blur->listener.destroy);
- blur->listener.surface_commit.notify = _e_blur_cb_ds_tizen_blur_commit;
- ds_tizen_blur_add_commit_listener(tizen_blur, &blur->listener.surface_commit);
+ blur->listener.commit.notify = _e_blur_cb_ds_tizen_blur_commit;
+ ds_tizen_blur_add_commit_listener(tizen_blur, &blur->listener.commit);
blur->tizen_blur = tizen_blur;
return;
}
+static Eina_Bool
+_e_blur_behind_enabled_get(E_Blur_Behind *blur_behind)
+{
+ return blur_behind->enabled;
+}
+
+static void
+_e_blur_manager_blur_behind_enabled_changed(Eina_Bool set)
+{
+ E_Blur_Manager *blur_manager = _blur_manager;
+ E_Blur_Behind *blur_behind;
+ Eina_List *l;
+
+ if (blur_manager->blur_behind_enabled == set)
+ return;
+
+ if (!set)
+ {
+ EINA_LIST_FOREACH(blur_manager->blurs_behind, l, blur_behind)
+ {
+ if (_e_blur_behind_enabled_get(blur_behind))
+ return;
+ }
+ }
+
+ blur_manager->blur_behind_enabled = set;
+
+ if (blur_manager->video_capture_enabled)
+ return;
+
+ if (blur_manager->blur_enabled || blur_manager->blur_behind_enabled)
+ e_video_debug_display_primary_plane_set(EINA_TRUE);
+ else
+ e_video_debug_display_primary_plane_set(EINA_FALSE);
+}
+
+static void
+_e_blur_behind_enabled_set(E_Blur_Behind *blur_behind, Eina_Bool set)
+{
+ E_Blur_Hook_Data hook_data = { .blur_behind = blur_behind };
+
+ if (blur_behind->enabled == set) return;
+
+ blur_behind->enabled = set;
+
+ if (set)
+ _e_blur_hook_call(E_BLUR_HOOK_BEHIND_SET, &hook_data);
+ else
+ _e_blur_hook_call(E_BLUR_HOOK_BEHIND_UNSET, &hook_data);
+
+ _e_blur_manager_blur_behind_enabled_changed(set);
+}
+
+static void
+_e_blur_behind_free(E_Blur_Behind *blur_behind)
+{
+ ELOGF("E_BLUR", "E_Blur_Behind:%p Free", blur_behind->ec, blur_behind);
+
+ _e_blur_behind_ec_set(blur_behind, NULL);
+ evas_object_del(blur_behind->obj);
+ _e_blur_behind_enabled_set(blur_behind, EINA_FALSE);
+
+ free(blur_behind);
+}
+
+static void
+_e_blur_behind_cb_ds_tizen_blur_behind_destroy(struct wl_listener *listener, void *data)
+{
+ E_Blur_Behind *blur_behind;
+ E_Blur_Manager *blur_manager = _blur_manager;
+
+ blur_behind = wl_container_of(listener, blur_behind, listener.destroy);
+
+ if (blur_manager)
+ blur_manager->blurs_behind = eina_list_remove(blur_manager->blurs, blur_behind);
+
+ _e_blur_behind_free(blur_behind);
+}
+
+static void
+_e_blur_behind_filter_set(E_Blur_Behind *blur_behind)
+{
+ char program[256];
+
+ snprintf(program, sizeof(program), "blur (%d) padding_set (0)", blur_behind->radius);
+
+ efl_gfx_filter_program_set(blur_behind->obj, program, "image_filter");
+}
+
+static void
+_e_blur_behind_cb_ds_tizen_blur_behind_commit(struct wl_listener *listener, void *data)
+{
+ E_Blur_Behind *blur_behind;
+ const struct ds_tizen_blur_behind_state *state;
+ Eina_Bool radius_changed = EINA_FALSE;
+
+ blur_behind = container_of(listener, E_Blur_Behind, listener.commit);
+ if (!blur_behind->ec) return;
+
+ state = ds_tizen_blur_behind_get_state(blur_behind->tizen_blur_behind);
+ if (!state) return;
+
+ if ((state->committed & DS_TIZEN_BLUR_BEHIND_STATE_RADIUS) &&
+ (blur_behind->radius != state->radius))
+ {
+ blur_behind->radius = state->radius;
+ radius_changed = EINA_TRUE;
+ ELOGF("E_BLUR", "E_Blur_Behind:%p Radius:%d changed", NULL, blur_behind, blur_behind->radius);
+ }
+
+ if (!radius_changed)
+ return;
+
+ if (blur_behind->radius)
+ {
+ _e_blur_behind_filter_set(blur_behind);
+ if (!evas_object_visible_get(blur_behind->ec->frame))
+ evas_object_show(blur_behind->obj);
+
+ _e_blur_behind_enabled_set(blur_behind, EINA_TRUE);
+ }
+ else
+ {
+ evas_object_hide(blur_behind->obj);
+
+ _e_blur_behind_enabled_set(blur_behind, EINA_FALSE);
+ }
+}
+
+static Evas_Object *
+_e_blur_behind_bottom_object_get(Evas_Object *obj)
+{
+ Evas_Object *below_obj, *bottom_obj = obj;
+
+ below_obj = evas_object_below_get(bottom_obj);
+ while (!e_util_strcmp(evas_object_name_get(below_obj), "blur_obj"))
+ {
+ bottom_obj = below_obj;
+ below_obj = evas_object_below_get(bottom_obj);
+ }
+
+ return bottom_obj;
+}
+
+static void
+_e_blur_behind_evas_cb_show(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
+{
+ E_Blur_Behind *blur_behind;
+
+ if (!(blur_behind = data)) return;
+ if (!_e_blur_behind_enabled_get(blur_behind)) return;
+
+ evas_object_show(blur_behind->obj);
+}
+
+static void
+_e_blur_behind_evas_cb_hide(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
+{
+ E_Blur_Behind *blur_behind;
+
+ if (!(blur_behind = data)) return;
+
+ evas_object_hide(blur_behind->obj);
+}
+
+static void
+_e_blur_behind_evas_cb_restack(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
+{
+ E_Blur_Behind *blur_behind;
+
+ if (!(blur_behind = data)) return;
+
+ evas_object_layer_set(blur_behind->obj, evas_object_layer_get(obj));
+ evas_object_stack_below(blur_behind->obj, _e_blur_behind_bottom_object_get(obj));
+}
+
+static void
+_e_blur_behind_cb_ec_free(void *data, void *obj)
+{
+ E_Blur_Behind *blur_behind = data;
+
+ blur_behind->ec_delfn = NULL;
+ _e_blur_behind_ec_set(blur_behind, NULL);
+}
+
+static void
+_e_blur_behind_ec_set(E_Blur_Behind *blur_behind, E_Client *ec)
+{
+ if (blur_behind->ec == ec) return;
+
+ if (blur_behind->ec)
+ {
+ evas_object_event_callback_del(blur_behind->ec->frame, EVAS_CALLBACK_SHOW,
+ _e_blur_behind_evas_cb_show);
+ evas_object_event_callback_del(blur_behind->ec->frame, EVAS_CALLBACK_HIDE,
+ _e_blur_behind_evas_cb_hide);
+ evas_object_event_callback_del(blur_behind->ec->frame, EVAS_CALLBACK_RESTACK,
+ _e_blur_behind_evas_cb_restack);
+
+ if (blur_behind->ec_delfn)
+ {
+ e_object_delfn_del(E_OBJECT(blur_behind->ec), blur_behind->ec_delfn);
+ blur_behind->ec_delfn = NULL;
+ }
+
+ blur_behind->ec = NULL;
+ }
+
+ if (ec)
+ {
+ evas_object_event_callback_add(ec->frame, EVAS_CALLBACK_SHOW,
+ _e_blur_behind_evas_cb_show, blur_behind);
+ evas_object_event_callback_add(ec->frame, EVAS_CALLBACK_HIDE,
+ _e_blur_behind_evas_cb_hide, blur_behind);
+ evas_object_event_callback_add(ec->frame, EVAS_CALLBACK_RESTACK,
+ _e_blur_behind_evas_cb_restack, blur_behind);
+
+ blur_behind->ec_delfn = e_object_delfn_add(E_OBJECT(ec),
+ _e_blur_behind_cb_ec_free,
+ blur_behind);
+ blur_behind->ec = ec;
+ }
+}
+
+static void
+_e_blur_manager_cb_new_blur_behind(struct wl_listener *listener, void *data)
+{
+ E_Blur_Behind *blur_behind;
+ E_Blur_Manager *blur_manager = _blur_manager;
+ struct ds_tizen_blur_behind *tizen_blur_behind = data;
+ struct ds_surface *surface;
+ struct wl_resource *surface_resource;
+ E_Client *ec;
+ Evas_Object *obj;
+ E_Blur_Hook_Data hook_data;
+
+ if (!blur_manager)
+ {
+ ERR("blur is not initialized");
+ return;
+ }
+
+ surface = ds_tizen_blur_behind_get_surface(tizen_blur_behind);
+ 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);
+
+ obj = evas_object_image_filled_add(e_comp->evas);
+ EINA_SAFETY_ON_NULL_RETURN(obj);
+
+ blur_behind = E_NEW(E_Blur_Behind, 1);
+ EINA_SAFETY_ON_NULL_RETURN(blur_behind);
+
+ blur_behind->listener.destroy.notify = _e_blur_behind_cb_ds_tizen_blur_behind_destroy;
+ ds_tizen_blur_behind_add_destroy_listener(tizen_blur_behind, &blur_behind->listener.destroy);
+
+ blur_behind->listener.commit.notify = _e_blur_behind_cb_ds_tizen_blur_behind_commit;
+ ds_tizen_blur_behind_add_commit_listener(tizen_blur_behind, &blur_behind->listener.commit);
+
+ blur_behind->tizen_blur_behind = tizen_blur_behind;
+
+ _e_blur_behind_ec_set(blur_behind, ec);
+
+ blur_behind->obj = obj;
+ evas_object_image_snapshot_set(blur_behind->obj, EINA_TRUE);
+ evas_object_name_set(blur_behind->obj, "blur_obj");
+ evas_object_geometry_set(blur_behind->obj, 0, 0, e_comp->w, e_comp->h);
+ evas_object_layer_set(blur_behind->obj, evas_object_layer_get(ec->frame));
+ evas_object_stack_below(blur_behind->obj, _e_blur_behind_bottom_object_get(ec->frame));
+
+ blur_manager->blurs_behind = eina_list_append(blur_manager->blurs_behind, blur_behind);
+
+ ELOGF("E_BLUR", "E_Blur_Behind:%p Create", ec, blur_behind);
+
+ hook_data.blur_behind = blur_behind;
+ _e_blur_hook_call(E_BLUR_HOOK_BEHIND_CREATE, &hook_data);
+}
+
static void
_e_blur_manager_cb_destroy(struct wl_listener *listener, void *data)
{
ds_tizen_blur_manager_add_new_blur_listener(blur_manager->tizen_blur_manager,
&blur_manager->listener.new_blur);
+ blur_manager->listener.new_blur_behind.notify = _e_blur_manager_cb_new_blur_behind;
+ ds_tizen_blur_manager_add_new_blur_behind_listener(blur_manager->tizen_blur_manager,
+ &blur_manager->listener.new_blur_behind);
+
if (conf->blur_video_capture)
{
e_blur_video_capture_init();
return blur_manager->blurs;
}
+EINTERN Eina_List *
+e_blur_manager_blurs_behind_get(void)
+{
+ E_Blur_Manager *blur_manager = _blur_manager;
+
+ if (!_blur_manager) return NULL;
+
+ return blur_manager->blurs_behind;
+}
+
EINTERN Evas_Object *
e_blur_rectangle_object_get(E_Blur_Rectangle *blur_rectangle)
{
if (ry) *ry = blur_rectangle->ry;
}
+EINTERN E_Client *
+e_blur_behind_client_get(E_Blur_Behind *blur_behind)
+{
+ EINA_SAFETY_ON_NULL_RETURN_VAL(blur_behind, NULL);
+
+ return blur_behind->ec;
+}
+
+EINTERN Evas_Object *
+e_blur_behind_object_get(E_Blur_Behind *blur_behind)
+{
+ EINA_SAFETY_ON_NULL_RETURN_VAL(blur_behind, NULL);
+
+ return blur_behind->obj;
+}
+
EINTERN void
e_blur_trace_debug(Eina_Bool onoff)
{
typedef struct _E_Blur E_Blur;
typedef struct _E_Blur_Rectangle E_Blur_Rectangle;
typedef struct _E_Blur_Hook E_Blur_Hook;
-typedef void (*E_Blur_Hook_Cb) (void *data, E_Blur *blur);
+typedef struct _E_Blur_Behind E_Blur_Behind;
+typedef struct _E_Blur_Hook_Data E_Blur_Hook_Data;
+
+typedef void (*E_Blur_Hook_Cb) (void *data, E_Blur_Hook_Data *hook_data);
typedef enum _E_Blur_Hook_Point
{
E_BLUR_HOOK_SET,
E_BLUR_HOOK_UNSET,
E_BLUR_HOOK_RECTANGLE_CREATE,
+ E_BLUR_HOOK_BEHIND_CREATE,
+ E_BLUR_HOOK_BEHIND_SET,
+ E_BLUR_HOOK_BEHIND_UNSET,
E_BLUR_HOOK_LAST
} E_Blur_Hook_Point;
unsigned char delete_me : 1;
};
+struct _E_Blur_Hook_Data
+{
+ E_Blur *blur;
+ E_Blur_Rectangle *blur_rectangle;
+
+ E_Blur_Behind *blur_behind;
+};
+
EINTERN Eina_Bool e_blur_manager_init(void);
EINTERN void e_blur_manager_shutdown(void);
EINTERN Eina_List *e_blur_manager_blurs_get(void);
+EINTERN Eina_List *e_blur_manager_blurs_behind_get(void);
EINTERN E_Client *e_blur_client_get(E_Blur *blur);
EINTERN Eina_List *e_blur_rectangles_get(E_Blur *blur);
EINTERN Evas_Object *e_blur_rectangle_object_get(E_Blur_Rectangle *blur_rectangle);
+EINTERN void e_blur_rectangle_corner_radius_get(E_Blur_Rectangle *blur_rectangle, int *rx, int *ry);
+EINTERN E_Client *e_blur_behind_client_get(E_Blur_Behind *blur_behind);
+EINTERN Evas_Object *e_blur_behind_object_get(E_Blur_Behind *blur_behind);
+EINTERN void e_blur_trace_debug(Eina_Bool onoff);
EINTERN E_Blur_Hook *e_blur_hook_add(E_Blur_Hook_Point hookpoint, E_Blur_Hook_Cb func, const void *data);
EINTERN void e_blur_hook_del(E_Blur_Hook *ch);
-EINTERN void e_blur_trace_debug(Eina_Bool onoff);
-EINTERN void e_blur_rectangle_corner_radius_get(E_Blur_Rectangle *blur_rectangle, int *rx, int *ry);
#endif // E_BLUR_INTERN_H
typedef struct _E_Blur_Video_Capture_Client E_Blur_Video_Capture_Client;
typedef struct _E_Blur_Video_Capture_Object E_Blur_Video_Capture_Object;
+typedef enum
+{
+ E_BLUR_VIDEO_CAPTURE_OBJECT_TYPE_NONE = 0,
+ E_BLUR_VIDEO_CAPTURE_OBJECT_TYPE_RECTANGLE = 1,
+ E_BLUR_VIDEO_CAPTURE_OBJECT_TYPE_BEHIND = 2,
+} E_Blur_Video_Capture_Object_Type;
+
struct _E_Blur_Video_Capture
{
int width, height, fps;
struct _E_Blur_Video_Capture_Object
{
E_Blur_Video_Capture_Client *client;
- E_Blur_Rectangle *blur_rectangle;
- Evas_Object *blur_rectangle_obj;
+ Evas_Object *blur_obj;
Evas_Object *blur_clip_obj;
Evas_Object *source_clip_obj;
Evas_Object *source_obj;
Eina_Bool visible;
+
+ E_Blur_Video_Capture_Object_Type type;
};
typedef struct {
}
static void
-_e_blur_video_capture_object_evas_cb_restack(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
+_e_blur_video_capture_object_evas_cb_del(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
{
E_Blur_Video_Capture_Object *object;
if (!(object = data)) return;
- /* TODO:restack capture object */
+ _e_blur_video_capture_object_destroy(object);
+ _e_blur_video_capture_stop();
}
-static void
-_e_blur_video_capture_object_evas_cb_del(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
+static Evas_Object *
+_e_blur_video_capture_topmost_object_get(Evas_Object *obj)
{
- E_Blur_Video_Capture_Object *object;
+ Evas_Object *above_obj, *topmost_obj = obj;
+ const char *name;
- if (!(object = data)) return;
+ above_obj = evas_object_above_get(topmost_obj);
+ name = evas_object_name_get(above_obj);
+ while (name && strstr(name, "blur_video_capture"))
+ {
+ topmost_obj = above_obj;
+ above_obj = evas_object_above_get(topmost_obj);
+ name = evas_object_name_get(above_obj);
+ }
- _e_blur_video_capture_object_destroy(object);
- _e_blur_video_capture_stop();
+ return topmost_obj;
}
static E_Blur_Video_Capture_Object *
-_e_blur_video_capture_object_get(E_Blur_Video_Capture_Client *client, E_Blur_Rectangle *blur_rectangle)
+_e_blur_video_capture_object_create(E_Blur_Video_Capture_Client *client, Evas_Object *blur_obj,
+ E_Blur_Video_Capture_Object_Type type)
{
E_Blur_Video_Capture *video_capture = _video_capture;
- Evas_Object *obj;
E_Blur_Video_Capture_Object *object;
int x, y, w, h;
- Eina_List *l;
unsigned int *pixels;
- char program[256];
- int rx = 0, ry = 0;
- if (!blur_rectangle) return NULL;
-
- EINA_LIST_FOREACH(client->capture_objs, l, object)
- {
- if (object->blur_rectangle == blur_rectangle)
- return object;
- }
-
- obj = e_blur_rectangle_object_get(blur_rectangle);
- if (!obj) return NULL;;
+ if (!blur_obj) return NULL;
object = E_NEW(E_Blur_Video_Capture_Object, 1);
EINA_SAFETY_ON_NULL_RETURN_VAL(object, NULL);
*pixels = 0xffffffff;
evas_object_image_data_set(object->blur_clip_obj, pixels);
evas_object_image_data_update_add(object->blur_clip_obj, 0, 0, 1, 1);
- e_blur_rectangle_corner_radius_get(blur_rectangle, &rx, &ry);
- if ((rx != 0) && (ry != 0))
- {
- snprintf(program, sizeof(program), "rounded_corner { rx = %d, ry = %d}", rx, ry);
- efl_gfx_filter_program_set(object->blur_clip_obj, program, "rounded_corner");
- }
evas_object_name_set(object->blur_clip_obj, "blur_video_capture_blur_clip_obj");
evas_object_pass_events_set(object->blur_clip_obj, EINA_TRUE);
if (_e_blur_video_capture_source_object_visible_get())
evas_object_image_source_set(object->source_obj, video_capture->source_obj);
- object->blur_rectangle_obj = obj;
-
- evas_object_event_callback_add(object->blur_rectangle_obj, EVAS_CALLBACK_SHOW,
- _e_blur_video_capture_object_evas_cb_show, object);
- evas_object_event_callback_add(object->blur_rectangle_obj, EVAS_CALLBACK_HIDE,
- _e_blur_video_capture_object_evas_cb_hide, object);
- evas_object_event_callback_add(object->blur_rectangle_obj, EVAS_CALLBACK_RESIZE,
- _e_blur_video_capture_object_evas_cb_resize, object);
- evas_object_event_callback_add(object->blur_rectangle_obj, EVAS_CALLBACK_MOVE,
- _e_blur_video_capture_object_evas_cb_move, object);
- evas_object_event_callback_add(object->blur_rectangle_obj, EVAS_CALLBACK_RESTACK,
- _e_blur_video_capture_object_evas_cb_restack, object);
- evas_object_event_callback_add(object->blur_rectangle_obj, EVAS_CALLBACK_DEL,
- _e_blur_video_capture_object_evas_cb_del, object);
+ object->blur_obj = blur_obj;
+
+ evas_object_event_callback_add(object->blur_obj, EVAS_CALLBACK_SHOW,
+ _e_blur_video_capture_object_evas_cb_show, object);
+ evas_object_event_callback_add(object->blur_obj, EVAS_CALLBACK_HIDE,
+ _e_blur_video_capture_object_evas_cb_hide, object);
+ evas_object_event_callback_add(object->blur_obj, EVAS_CALLBACK_RESIZE,
+ _e_blur_video_capture_object_evas_cb_resize, object);
+ evas_object_event_callback_add(object->blur_obj, EVAS_CALLBACK_MOVE,
+ _e_blur_video_capture_object_evas_cb_move, object);
+ evas_object_event_callback_add(object->blur_obj, EVAS_CALLBACK_DEL,
+ _e_blur_video_capture_object_evas_cb_del, object);
evas_object_layer_set(object->blur_clip_obj, evas_object_layer_get(client->ec->frame));
- evas_object_stack_above(object->blur_clip_obj, client->ec->frame);
+ if (type == E_BLUR_VIDEO_CAPTURE_OBJECT_TYPE_BEHIND)
+ evas_object_stack_above(object->blur_clip_obj,
+ _e_blur_video_capture_topmost_object_get(client->ec->frame));
+ else
+ evas_object_stack_above(object->blur_clip_obj, client->ec->frame);
evas_object_layer_set(object->source_clip_obj, evas_object_layer_get(client->ec->frame));
evas_object_stack_below(object->source_clip_obj, object->blur_clip_obj);
evas_object_layer_set(object->source_obj, evas_object_layer_get(client->ec->frame));
evas_object_stack_below(object->source_obj, object->source_clip_obj);
- evas_object_geometry_get(object->blur_rectangle_obj, &x, &y, &w, &h);
+ evas_object_geometry_get(object->blur_obj, &x, &y, &w, &h);
evas_object_geometry_set(object->blur_clip_obj, x, y, w, h);
e_client_geometry_get(client->ec, &x, &y, &w, &h);
evas_object_clip_set(object->source_obj, object->source_clip_obj);
evas_object_clip_set(object->source_clip_obj, object->blur_clip_obj);
- object->blur_rectangle = blur_rectangle;
+ object->type = type;
object->client = client;
client->capture_objs = eina_list_append(client->capture_objs, object);
- ELOGF("E_BLUR", "Create Video_Capture_Object:%p", client->ec, object);
+ ELOGF("E_BLUR", "Create Video_Capture_Object:%p type:%d", client->ec, object, object->type);
return object;
EINA_LIST_FOREACH(client->capture_objs, l2, object)
{
- if (!evas_object_visible_get(object->blur_rectangle_obj)) continue;
+ if (!evas_object_visible_get(object->blur_obj)) continue;
_e_blur_video_capture_object_show(object);
}
EINA_LIST_FOREACH(client->capture_objs, l2, object)
{
- if (evas_object_visible_get(object->blur_rectangle_obj))
+ if (evas_object_visible_get(object->blur_obj))
return EINA_TRUE;
}
}
return EINA_TRUE;
}
+static E_Blur_Video_Capture_Object *
+_e_blur_video_capture_client_object_find(E_Blur_Video_Capture_Client *client, Evas_Object *blur_obj)
+{
+ E_Blur_Video_Capture_Object *object;
+ Eina_List *l;
+
+ EINA_LIST_FOREACH(client->capture_objs, l, object)
+ {
+ if (object->blur_obj == blur_obj)
+ return object;
+ }
+
+ return NULL;
+}
+
+static void
+_e_blur_video_capture_client_object_rectangle_init(E_Blur_Video_Capture_Client *client, E_Blur_Rectangle *blur_rectangle)
+{
+ E_Blur_Video_Capture_Object *object;
+ Evas_Object *blur_obj;
+ int rx = 0, ry = 0;
+ char program[256];
+
+ blur_obj = e_blur_rectangle_object_get(blur_rectangle);
+ EINA_SAFETY_ON_NULL_RETURN(blur_obj);
+
+ object = _e_blur_video_capture_client_object_find(client, blur_obj);
+ if (!object)
+ {
+ object = _e_blur_video_capture_object_create(client, blur_obj,
+ E_BLUR_VIDEO_CAPTURE_OBJECT_TYPE_RECTANGLE);
+ EINA_SAFETY_ON_NULL_RETURN(object);
+
+ e_blur_rectangle_corner_radius_get(blur_rectangle, &rx, &ry);
+ if ((rx != 0) && (ry != 0))
+ {
+ snprintf(program, sizeof(program), "rounded_corner { rx = %d, ry = %d}", rx, ry);
+ efl_gfx_filter_program_set(object->blur_clip_obj, program, "rounded_corner");
+ }
+ }
+
+ if (!client->presentation_visible) return;
+ if (!evas_object_visible_get(object->blur_obj)) return;
+ if (_e_blur_video_capture_source_object_visible_get()) return;
+
+ _e_blur_video_capture_object_show(object);
+}
+
+static void
+_e_blur_video_capture_client_object_behind_init(E_Blur_Video_Capture_Client *client, E_Blur_Behind *blur_behind)
+{
+ E_Blur_Video_Capture_Object *object;
+ Evas_Object *blur_obj;
+
+ blur_obj = e_blur_behind_object_get(blur_behind);
+ EINA_SAFETY_ON_NULL_RETURN(blur_obj);
+
+ object = _e_blur_video_capture_client_object_find(client, blur_obj);
+ if (!object)
+ {
+ object = _e_blur_video_capture_object_create(client, blur_obj,
+ E_BLUR_VIDEO_CAPTURE_OBJECT_TYPE_BEHIND);
+ EINA_SAFETY_ON_NULL_RETURN(object);
+ }
+
+ if (!client->presentation_visible) return;
+ if (!evas_object_visible_get(object->blur_obj)) return;
+ if (_e_blur_video_capture_source_object_visible_get()) return;
+
+ _e_blur_video_capture_object_show(object);
+}
+
static void
-_e_blur_video_capture_cb_rectangle_create(void *data, E_Blur *blur)
+_e_blur_video_capture_cb_blur_rectangle_create(void *data, E_Blur_Hook_Data *hook_data)
{
E_Blur_Video_Capture *video_capture = _video_capture;
E_Blur_Video_Capture_Client *client;
- E_Blur_Video_Capture_Object *object;
- E_Blur_Rectangle *blur_rectangle;
- Eina_List *blur_rectangles;
- Eina_List *l, *l2;
+ E_Blur_Rectangle *blur_rectangle = hook_data->blur_rectangle;
+ Eina_List *l;
EINA_SAFETY_ON_NULL_RETURN(video_capture->funcs);
- blur_rectangles = e_blur_rectangles_get(blur);
- if (!blur_rectangles) return;
if (!video_capture->clients) return;
- EINA_LIST_FOREACH(blur_rectangles, l, blur_rectangle)
- {
- EINA_LIST_FOREACH(video_capture->clients, l2, client)
- {
- object = _e_blur_video_capture_object_get(client, blur_rectangle);
+ EINA_LIST_FOREACH(video_capture->clients, l, client)
+ _e_blur_video_capture_client_object_rectangle_init(client, blur_rectangle);
- if (!client->presentation_visible) continue;
- if (!evas_object_visible_get(object->blur_rectangle_obj)) continue;
- if (!_e_blur_video_capture_source_object_visible_get()) continue;
+ _e_blur_video_capture_start();
+}
- _e_blur_video_capture_object_show(object);
- }
- }
+static void
+_e_blur_video_capture_cb_blur_behind_create(void *data, E_Blur_Hook_Data *hook_data)
+{
+ E_Blur_Video_Capture *video_capture = _video_capture;
+ E_Blur_Video_Capture_Client *client;
+ E_Blur_Behind *blur_behind = hook_data->blur_behind;
+ Eina_List *l;
+
+ EINA_SAFETY_ON_NULL_RETURN(video_capture->funcs);
+
+ if (!video_capture->clients) return;
+
+ EINA_LIST_FOREACH(video_capture->clients, l, client)
+ _e_blur_video_capture_client_object_behind_init(client, blur_behind);
_e_blur_video_capture_start();
}
{
EINA_LIST_FOREACH(client->capture_objs, l, object)
{
- if (!evas_object_visible_get(object->blur_rectangle_obj))
+ if (!evas_object_visible_get(object->blur_obj))
continue;
_e_blur_video_capture_object_show(object);
{
EINA_LIST_FOREACH(client->capture_objs, l, object)
{
- if (!evas_object_visible_get(object->blur_rectangle_obj))
+ if (!evas_object_visible_get(object->blur_obj))
continue;
_e_blur_video_capture_object_show(object);
layer = evas_object_layer_get(obj);
+
+ EINA_LIST_FOREACH(client->capture_objs, l, object)
+ {
+ if (object->type != E_BLUR_VIDEO_CAPTURE_OBJECT_TYPE_BEHIND)
+ continue;
+
+ evas_object_layer_set(object->blur_clip_obj, layer);
+ evas_object_stack_above(object->blur_clip_obj, obj);
+ evas_object_layer_set(object->source_clip_obj, layer);
+ evas_object_stack_below(object->source_clip_obj, object->blur_clip_obj);
+ evas_object_layer_set(object->source_obj, layer);
+ evas_object_stack_below(object->source_obj, object->source_clip_obj);
+ }
+
EINA_LIST_FOREACH(client->capture_objs, l, object)
{
+ if (object->type != E_BLUR_VIDEO_CAPTURE_OBJECT_TYPE_RECTANGLE)
+ continue;
+
evas_object_layer_set(object->blur_clip_obj, layer);
evas_object_stack_above(object->blur_clip_obj, obj);
evas_object_layer_set(object->source_clip_obj, layer);
EINA_LIST_FOREACH_SAFE(client->capture_objs, l, ll, object)
{
- evas_object_event_callback_del(object->blur_rectangle_obj, EVAS_CALLBACK_SHOW,
+ evas_object_event_callback_del(object->blur_obj, EVAS_CALLBACK_SHOW,
_e_blur_video_capture_object_evas_cb_show);
- evas_object_event_callback_del(object->blur_rectangle_obj, EVAS_CALLBACK_HIDE,
+ evas_object_event_callback_del(object->blur_obj, EVAS_CALLBACK_HIDE,
_e_blur_video_capture_object_evas_cb_hide);
- evas_object_event_callback_del(object->blur_rectangle_obj, EVAS_CALLBACK_RESIZE,
+ evas_object_event_callback_del(object->blur_obj, EVAS_CALLBACK_RESIZE,
_e_blur_video_capture_object_evas_cb_resize);
- evas_object_event_callback_del(object->blur_rectangle_obj, EVAS_CALLBACK_MOVE,
+ evas_object_event_callback_del(object->blur_obj, EVAS_CALLBACK_MOVE,
_e_blur_video_capture_object_evas_cb_move);
- evas_object_event_callback_del(object->blur_rectangle_obj, EVAS_CALLBACK_RESTACK,
- _e_blur_video_capture_object_evas_cb_restack);
- evas_object_event_callback_del(object->blur_rectangle_obj, EVAS_CALLBACK_DEL,
+ evas_object_event_callback_del(object->blur_obj, EVAS_CALLBACK_DEL,
_e_blur_video_capture_object_evas_cb_del);
_e_blur_video_capture_object_destroy(object);
}
static void
+_e_blur_video_capture_client_blurs_init(E_Blur_Video_Capture_Client *client)
+{
+ E_Blur *blur;
+ E_Blur_Rectangle *blur_rectangle;
+ Eina_List *blurs, *blur_rectangles, *l, *l2;
+
+ blurs = e_blur_manager_blurs_get();
+ if (!blurs) return;
+
+ EINA_LIST_FOREACH(blurs, l, blur)
+ {
+ blur_rectangles = e_blur_rectangles_get(blur);
+ if (!blur_rectangles) continue;
+
+ EINA_LIST_FOREACH(blur_rectangles, l2, blur_rectangle)
+ _e_blur_video_capture_client_object_rectangle_init(client, blur_rectangle);
+ }
+}
+
+static void
+_e_blur_video_capture_client_blurs_behind_init(E_Blur_Video_Capture_Client *client)
+{
+ E_Blur_Behind *blur_behind;
+ Eina_List *blurs_behind, *l;
+
+ blurs_behind = e_blur_manager_blurs_behind_get();
+ if (!blurs_behind) return;
+
+ EINA_LIST_FOREACH(blurs_behind, l, blur_behind)
+ _e_blur_video_capture_client_object_behind_init(client, blur_behind);
+}
+
+static void
_e_blur_video_capture_cb_hwc_window_video_set(void *data, E_Hwc_Window *hwc_window)
{
E_Blur_Video_Capture_Client *client;
E_Blur_Video_Capture *video_capture = _video_capture;
- E_Blur_Video_Capture_Object *object;
- Eina_List *blurs, *blur_rectangles, *l, *l2;
- E_Blur *blur;
- E_Blur_Rectangle *blur_rectangle;
EINA_SAFETY_ON_NULL_RETURN(video_capture->funcs);
ELOGF("E_BLUR", "Create Video_Capture_Client:%p", client->ec, client);
- blurs = e_blur_manager_blurs_get();
- if (!blurs) return;
-
- EINA_LIST_FOREACH(blurs, l, blur)
- {
- blur_rectangles = e_blur_rectangles_get(blur);
- if (!blur_rectangles) return;
-
- EINA_LIST_FOREACH(blur_rectangles, l2, blur_rectangle)
- {
- object = _e_blur_video_capture_object_get(client, blur_rectangle);
-
- if (!client->presentation_visible) continue;
- if (!evas_object_visible_get(object->blur_rectangle_obj)) continue;
- if (_e_blur_video_capture_source_object_visible_get()) continue;
-
- _e_blur_video_capture_object_show(object);
- }
- }
+ _e_blur_video_capture_client_blurs_init(client);
+ _e_blur_video_capture_client_blurs_behind_init(client);
_e_blur_video_capture_start();
}
E_HWC_WINDOW_HOOK_APPEND(_e_blur_video_capture_hwc_window_hooks, E_HWC_WINDOW_HOOK_VIDEO_SET,
_e_blur_video_capture_cb_hwc_window_video_set, NULL);
E_BLUR_HOOK_APPEND(_e_blur_video_capture_blur_hooks, E_BLUR_HOOK_RECTANGLE_CREATE,
- _e_blur_video_capture_cb_rectangle_create, NULL);
+ _e_blur_video_capture_cb_blur_rectangle_create, NULL);
+ E_BLUR_HOOK_APPEND(_e_blur_video_capture_blur_hooks, E_BLUR_HOOK_BEHIND_CREATE,
+ _e_blur_video_capture_cb_blur_behind_create, NULL);
_video_capture = video_capture;