set_state(PART:"clipper", "default", 0.0);
set_state(PART:"shower", "default", 0.0);
set_state(PART:"e.swallow.content", "default", 0.0);
+ set_state(PART:"under", "default", 0.0);
}
else if (st == 1)
{
set_state(PART:"clipper", "visible", 0.0);
set_state(PART:"shower", "visible", 0.0);
set_state(PART:"e.swallow.content", "visible", 0.0);
+ set_state(PART:"under", "visible", 0.0);
}
else if (st == 2)
{
set_state(PART:"clipper", "restack_hidden", 0.0);
set_state(PART:"shower", "restack_hidden", 0.0);
set_state(PART:"e.swallow.content", "restack_hidden", 0.0);
+ set_state(PART:"under", "restack_hidden", 0.0);
}
else if (st == 3)
{
set_state(PART:"clipper", "restack_visible", 0.0);
set_state(PART:"shower", "restack_visible", 0.0);
set_state(PART:"e.swallow.content", "restack_visible", 0.0);
+ set_state(PART:"under", "restack_visible", 0.0);
}
else if (st == 4)
{
set_state(PART:"clipper", "restack_done", 0.0);
set_state(PART:"shower", "restack_done", 0.0);
set_state(PART:"e.swallow.content", "restack_done", 0.0);
+ set_state(PART:"under", "restack_done", 0.0);
}
} else if ((type == MSG_INT_SET) && (id == 1))
{
inherit: "visible" 0.0;
}
}
+ part { name: "under";
+ type: SWALLOW;
+ clip_to: "clipper";
+ description { state: "default" 0.0;
+ rel1.to: "shower";
+ rel2.to: "shower";
+ map {
+ on: 1;
+ smooth: 1;
+ zoom.x: 0.9;
+ zoom.y: 0.9;
+ }
+ }
+ description { state: "visible" 0.0;
+ rel1.to: "shower";
+ rel2.to: "shower";
+ map {
+ on: 1;
+ smooth: 1;
+ zoom.x: 1;
+ zoom.y: 1;
+ }
+ }
+ description { state: "visible_default" 0.0;
+ rel1.to: "shower";
+ rel2.to: "shower";
+ rel1.relative: 0 0;
+ rel2.relative: 1 1;
+ map.on : 0;
+ }
+ description { state: "hide" 0.0;
+ inherit: "default" 0.0;
+ }
+ description { state: "restack_visible" 0.0;
+ inherit: "visible" 0.0;
+ }
+ description { state: "restack_hidden" 0.0;
+ inherit: "default" 0.0;
+ }
+ description { state: "restack_done" 0.0;
+ inherit: "visible" 0.0;
+ }
+ }
}
programs {
program { name: "show1";
target: "shower";
target: "clipper";
target: "e.swallow.content";
+ target: "under";
after: "show2";
}
program { name: "show2";
target: "shower";
target: "clipper";
target: "e.swallow.content";
+ target: "under";
after: "show3";
}
program { name: "show3";
action: STATE_SET "visible_default" 0.0;
+ target: "under";
target: "e.swallow.content";
after: "done";
}
target: "shower";
target: "clipper";
target: "e.swallow.content";
+ target: "under";
after: "hide2";
}
program { name: "hide2";
target: "shower";
target: "clipper";
target: "e.swallow.content";
+ target: "under";
after: "hide3";
}
program { name: "hide3";
target: "shower";
target: "clipper";
target: "e.swallow.content";
+ target: "under";
after: "done";
}
program { name: "restack,show1";
target: "shower";
target: "clipper";
target: "e.swallow.content";
+ target: "under";
after: "restack,show2";
}
program { name: "restack,show2";
target: "shower";
target: "clipper";
target: "e.swallow.content";
+ target: "under";
after: "restack,show3";
}
program { name: "restack,show3";
action: STATE_SET "visible_default" 0.0;
target: "e.swallow.content";
+ target: "under";
after: "done";
}
program { name: "restack,hide1";
target: "shower";
target: "clipper";
target: "e.swallow.content";
+ target: "under";
after: "restack,hide2";
}
program { name: "restack,hide2";
target: "shower";
target: "clipper";
target: "e.swallow.content";
+ target: "under";
after: "done";
}
program { name: "restack,finish";
target: "shower";
target: "clipper";
target: "e.swallow.content";
+ target: "under";
after: "done";
}
program { name: "done";
#include "e_mod_effect.h"
+#include <tdm.h>
static E_Effect *_eff = NULL;
E_Comp_Wl_Buffer_Ref buffer_ref;
E_Pixmap *ep;
E_Client *reverse_ec;
+
+ Evas_Object *under;
+ unsigned int under_ref;
} E_Effect_Client;
+typedef struct
+{
+ tdm_layer *tlayer;
+ int zpos;
+} Under_Layer;
+
+static int
+_eff_object_underlayer_sort(const void *data1, const void *data2)
+{
+ const Under_Layer *layer1, *layer2;
+
+ layer1 = data1;
+ layer2 = data2;
+
+ if (layer1->zpos < layer2->zpos)
+ return -1;
+ else if (layer1->zpos > layer2->zpos)
+ return 1;
+ else
+ return 0;
+}
+
+static Evas_Object *
+_eff_object_underlayer_get(E_Client *ec)
+{
+ Evas_Object *underlay = NULL;
+ E_Comp_Screen *e_comp_screen;
+ Eina_List *l;
+ tdm_layer *layer;
+ Under_Layer *ulayer;
+
+ e_comp_screen = e_comp->e_comp_screen;
+ if (!e_comp_screen)
+ return NULL;
+
+ if (e_client_video_client_has(ec))
+ {
+ if ((!_eff->under_layers) && (!_eff->under_checked))
+ {
+ int i, count;
+ int primary_index, primary_zpos;
+ tdm_layer *primary_layer;
+ tdm_output *output;
+ tdm_layer_capability capabilities;
+
+ output = tdm_display_get_output(e_comp_screen->tdisplay, 0, NULL);
+ if (!output) return NULL;
+
+ tdm_output_get_primary_index(output, &primary_index);
+ primary_layer = tdm_output_get_layer(output, primary_index, NULL);
+ if (!primary_layer) return NULL;
+
+ tdm_layer_get_zpos(primary_layer, &primary_zpos);
+ tdm_output_get_layer_count(output, &count);
+
+ for (i = 0; i < count; i++)
+ {
+ int zpos;
+
+ if (i == primary_index) continue;
+
+ layer = tdm_output_get_layer(output, i, NULL);
+ if (!layer) continue;
+
+ tdm_layer_get_capabilities(layer, &capabilities);
+ if (!(capabilities & TDM_LAYER_CAPABILITY_GRAPHIC)) continue;
+
+ tdm_layer_get_zpos(layer, &zpos);
+ if (zpos >= primary_zpos) continue;
+
+ ulayer = E_NEW(Under_Layer, 1);
+ ulayer->zpos = zpos;
+ ulayer->tlayer = layer;
+
+ _eff->under_layers = eina_list_append(_eff->under_layers,
+ ulayer);
+ }
+
+ _eff->under_checked = EINA_TRUE;
+
+ if (!_eff->under_layers)
+ return NULL;
+
+ _eff->under_layers = eina_list_sort(_eff->under_layers,
+ eina_list_count(_eff->under_layers),
+ _eff_object_underlayer_sort);
+ }
+
+ if (!_eff->under_layers) return NULL;
+
+ EINA_LIST_FOREACH(_eff->under_layers, l, ulayer)
+ {
+ tdm_layer *layer;
+ Evas_Object *img;
+ tbm_surface_h buffer;
+ Evas_Native_Surface ns;
+ tdm_info_layer info;
+
+ layer = ulayer->tlayer;
+
+ buffer = tdm_layer_get_displaying_buffer(layer, NULL);
+ if (!buffer) continue;
+
+ img = evas_object_image_filled_add(e_comp->evas);
+ if (!img) continue;
+
+ tdm_layer_get_info(layer, &info);
+
+ if (info.dst_pos.w <= 0 || info.dst_pos.h <= 0)
+
+ memset(&ns, 0, sizeof(Evas_Native_Surface));
+ ns.version = EVAS_NATIVE_SURFACE_VERSION;
+ ns.type = EVAS_NATIVE_SURFACE_TBM;
+ ns.data.tbm.buffer = buffer;
+
+ evas_object_image_size_set(img, info.dst_pos.w, info.dst_pos.h);
+ evas_object_image_native_surface_set(img, &ns);
+ evas_object_image_pixels_dirty_set(img, EINA_TRUE);
+
+ if (!underlay)
+ {
+ Evas_Object *bg;
+
+ underlay = e_layout_add(e_comp->evas);
+ if (!underlay)
+ {
+ evas_object_del(img);
+ return NULL;
+ }
+
+ evas_object_name_set(underlay, "effect-under-layout");
+ e_layout_virtual_size_set(underlay, ec->zone->w, ec->zone->h);
+ evas_object_move(underlay, ec->zone->x, ec->zone->y);
+
+ bg = evas_object_rectangle_add(e_comp->evas);
+ evas_object_color_set(bg, 0, 0, 0, 255);
+ e_layout_pack(underlay, bg);
+ e_layout_child_move(bg, 0, 0);
+ e_layout_child_resize(bg, ec->zone->w, ec->zone->h);
+ evas_object_show(bg);
+ }
+
+ e_layout_pack(underlay, img);
+ e_layout_child_move(img, info.dst_pos.x, info.dst_pos.y);
+ e_layout_child_resize(img, info.dst_pos.w, info.dst_pos.h);
+ e_layout_child_raise(img);
+ evas_object_show(img);
+
+ EFFDBG("Video Object Created img(%p) %d,%d %dx%d underlay(%p)",
+ ec->pixmap, ec,
+ img, info.dst_pos.x, info.dst_pos.y, info.dst_pos.w, info.dst_pos.h,
+ underlay);
+ }
+ }
+
+ return underlay;
+}
+
static void
_eff_event_send(E_Client *ec, Eina_Bool start, E_Effect_Type type)
{
efc->animating = 0;
efc->delay_del_ref = 0;
efc->ep = NULL;
+ efc->under_ref = 0;
+ efc->under = NULL;
return efc;
}
return ec->e.state.rot.ang.curr;
}
-static Eina_Bool
-_eff_ref(E_Client *ec)
-{
- E_Effect_Client *efc;
-
- if (!_eff) return EINA_FALSE;
-
- efc = _eff_client_get(ec);
- if (!efc) return EINA_FALSE;
-
- if (e_object_is_del(E_OBJECT(ec)))
- {
- if (!e_object_delay_del_ref_get(E_OBJECT(ec)))
- {
- ERR("Client is deleted already! ec(%p)", ec);
- eina_hash_del_by_key(_eff->clients, &ec);
- return EINA_FALSE;
- }
- }
-
- if (!ec->pixmap) return EINA_FALSE;
- if ((e_comp_object_content_type_get(ec->frame) == E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE) &&
- (!e_pixmap_usable_get(ec->pixmap)))
- return EINA_FALSE;
-
- if (e_object_is_del(E_OBJECT(ec)))
- {
- e_object_delay_del_ref(E_OBJECT(ec));
- efc->delay_del_ref ++;
- }
-
- efc->animating++;
- e_object_ref(E_OBJECT(ec));
- efc->ep = e_pixmap_ref(ec->pixmap);
-
- EFFINF("effect ref efc(%p) animating:%d",
- efc->ep, efc->ec, efc, efc->animating);
-
- return EINA_TRUE;
-}
-
-static E_Client *
-_eff_unref(E_Client *ec)
-{
- E_Effect_Client *efc;
- int do_unref = 1;
-
- if (!_eff) return NULL;
- if (!ec) return NULL;
-
- efc = _eff_client_get(ec);
- if (!efc) return NULL;
-
- while (efc->delay_del_ref)
- {
- e_object_delay_del_unref(E_OBJECT(ec));
- efc->delay_del_ref--;
- }
-
- if (e_object_is_del(E_OBJECT(ec)))
- do_unref = efc->animating;
-
- efc->animating -= do_unref;
- while (do_unref)
- {
- e_pixmap_free(efc->ep);
- if (!e_object_unref(E_OBJECT(ec)))
- {
- EFFINF("eff unref ec(%p) ep(%p) efc(%p) Client free'd",
- NULL, NULL, ec, efc->ep, efc);
-
- efc->ec = NULL;
- efc = NULL;
- eina_hash_del_by_key(_eff->clients, &ec);
- return NULL;
- }
- do_unref --;
- }
-
- EFFINF("eff Unref efc(%p) animating:%d",
- ec->pixmap, ec, efc, efc->animating);
-
- /* The reference count of wl_buffer will get decremented
- * immediately after window effect.
- */
- if ((efc) && (efc->buffer_ref.buffer))
- e_comp_wl_buffer_reference(&efc->buffer_ref, NULL);
-
- return ec;
-}
-
static void
_eff_object_setup(E_Client *ec, E_Effect_Group group)
{
}
static void
+_eff_object_under_cb_del(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
+{
+ E_Effect_Client *efc = (E_Effect_Client *)data;
+ Eina_List *children;
+ Evas_Object *child;
+
+ if (efc->under != obj) return;
+
+ children = e_layout_children_get(obj);
+ EINA_LIST_FREE(children, child)
+ {
+ e_layout_unpack(child);
+ evas_object_del(child);
+ }
+
+ efc->under = NULL;
+ efc->under_ref = 0;
+}
+
+static void
+_eff_object_under_setup(E_Client *ec)
+{
+ E_Effect_Client *efc = NULL;
+ Evas_Object *underlay = NULL;
+
+ efc = _eff_client_get(ec);
+ if (!efc) return;
+
+ if (efc->under)
+ {
+ efc->under_ref ++;
+ }
+ else if ((underlay = _eff_object_underlayer_get(ec)))
+ {
+ Eina_List *children;
+ Evas_Object *child;
+
+ if (e_comp_object_effect_object_part_swallow(ec->frame, "under", underlay))
+ {
+ evas_object_event_callback_add(underlay,
+ EVAS_CALLBACK_DEL,
+ _eff_object_under_cb_del,
+ efc);
+ evas_object_show(underlay);
+ efc->under = underlay;
+ efc->under_ref ++;
+ }
+ else
+ {
+ children = e_layout_children_get(underlay);
+ EINA_LIST_FREE(children, child)
+ {
+ e_layout_unpack(child);
+ evas_object_del(child);
+ }
+
+ evas_object_del(underlay);
+ }
+ }
+}
+
+static void
+_eff_object_under_del(E_Client *ec)
+{
+ E_Effect_Client *efc = NULL;
+ Eina_List *children;
+ Evas_Object *child;
+
+ efc = _eff_client_get(ec);
+ if (!efc) return;
+ if (!efc->under) return;
+ if (efc->under_ref <= 0)
+ {
+ efc->under_ref = 0;
+ return;
+ }
+
+ efc->under_ref --;
+ if (efc->under_ref > 0) return;
+
+ evas_object_event_callback_del_full(efc->under,
+ EVAS_CALLBACK_DEL,
+ _eff_object_under_cb_del,
+ efc);
+
+ children = e_layout_children_get(efc->under);
+ EINA_LIST_FREE(children, child)
+ {
+ e_layout_unpack(child);
+ evas_object_del(child);
+ }
+
+ evas_object_del(efc->under);
+ efc->under = NULL;
+}
+
+static void
_eff_object_layer_up(E_Client *ec)
{
int map_ly;
return emission;
}
+static Eina_Bool
+_eff_ref(E_Client *ec)
+{
+ E_Effect_Client *efc;
+
+ if (!_eff) return EINA_FALSE;
+
+ efc = _eff_client_get(ec);
+ if (!efc) return EINA_FALSE;
+
+ if (e_object_is_del(E_OBJECT(ec)))
+ {
+ if (!e_object_delay_del_ref_get(E_OBJECT(ec)))
+ {
+ ERR("Client is deleted already! ec(%p)", ec);
+ eina_hash_del_by_key(_eff->clients, &ec);
+ return EINA_FALSE;
+ }
+ }
+
+ if (!ec->pixmap) return EINA_FALSE;
+ if ((e_comp_object_content_type_get(ec->frame) == E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE) &&
+ (!e_pixmap_usable_get(ec->pixmap)))
+ return EINA_FALSE;
+
+ if (e_object_is_del(E_OBJECT(ec)))
+ {
+ e_object_delay_del_ref(E_OBJECT(ec));
+ efc->delay_del_ref ++;
+ }
+
+ efc->animating++;
+ e_object_ref(E_OBJECT(ec));
+ efc->ep = e_pixmap_ref(ec->pixmap);
+
+ EFFINF("effect ref efc(%p) animating:%d",
+ efc->ep, efc->ec, efc, efc->animating);
+
+ return EINA_TRUE;
+}
+
+static E_Client *
+_eff_unref(E_Client *ec)
+{
+ E_Effect_Client *efc;
+ int do_unref = 1;
+
+ if (!_eff) return NULL;
+ if (!ec) return NULL;
+
+ efc = _eff_client_get(ec);
+ if (!efc) return NULL;
+
+ while (efc->delay_del_ref)
+ {
+ e_object_delay_del_unref(E_OBJECT(ec));
+ efc->delay_del_ref--;
+ }
+
+ if (e_object_is_del(E_OBJECT(ec)))
+ do_unref = efc->animating;
+
+ efc->animating -= do_unref;
+ while (do_unref)
+ {
+ e_pixmap_free(efc->ep);
+ if (efc->under)
+ _eff_object_under_del(ec);
+ if (!e_object_unref(E_OBJECT(ec)))
+ {
+ EFFINF("eff unref ec(%p) ep(%p) efc(%p) Client free'd",
+ NULL, NULL, ec, efc->ep, efc);
+
+ efc->ec = NULL;
+ efc = NULL;
+ eina_hash_del_by_key(_eff->clients, &ec);
+ return NULL;
+ }
+ do_unref --;
+ }
+
+ EFFINF("eff Unref efc(%p) animating:%d",
+ ec->pixmap, ec, efc, efc->animating);
+
+ /* The reference count of wl_buffer will get decremented
+ * immediately after window effect.
+ */
+ if ((efc) && (efc->buffer_ref.buffer))
+ e_comp_wl_buffer_reference(&efc->buffer_ref, NULL);
+
+ return ec;
+}
+
+
static void
_eff_cb_visible_done(void *data, Evas_Object *obj EINA_UNUSED, const char *sig EINA_UNUSED, const char *src EINA_UNUSED)
{
ec->extra_animating = EINA_TRUE;
_eff_object_setup(ec, group);
+ _eff_object_under_setup(ec);
+
ang = _eff_group_angle_get(ec, group);
e_comp_object_effect_params_set(ec->frame, 0, (int[]){0, ang}, 2);
if (e_comp->nocomp)
_eff_object_layer_up(ec);
_eff_object_setup(ec, group);
+ _eff_object_under_setup(ec);
+
ang = _eff_group_angle_get(ec, group);
e_comp_object_effect_params_set(ec->frame, 0, (int[]){1, ang}, 2);
e_comp_override_add();
_eff_object_setup(ec, group);
+ _eff_object_under_setup(ec);
+
ang = _eff_group_angle_get(ec, group);
e_comp_object_effect_params_set(ec->frame, 0, (int[]){0, ang}, 2);
e_comp_override_add();
_eff_object_setup(ec, group);
+ _eff_object_under_setup(ec);
+
ang = _eff_group_angle_get(ec, group);
e_comp_object_effect_params_set(ec->frame, 0, (int[]){1, ang}, 2);
e_comp_override_add();
_eff_object_setup(ec, group);
+ _eff_object_under_setup(ec);
+
ang = _eff_group_angle_get(ec, group);
e_comp_object_effect_params_set(ec->frame, 0, (int[]){2, ang}, 2);
_eff_object_layer_up(ec);
_eff_object_setup(ec, group);
+ _eff_object_under_setup(ec);
+
ang = _eff_group_angle_get(ec, group);
e_comp_object_effect_params_set(ec->frame, 0, (int[]){3, ang}, 2);
e_comp_override_add();
_eff_object_setup(ec, group);
+ _eff_object_under_setup(ec);
+
ang = _eff_group_angle_get(ec, group);
e_comp_object_effect_params_set(ec->frame, 0, (int[]){4, ang}, 2);
if ((efc = _eff_client_get(ec)))
{
if (!efc->animating)
- eina_hash_del_by_key(_eff->clients, &ec);
+ {
+ _eff_object_under_del(ec);
+ eina_hash_del_by_key(_eff->clients, &ec);
+ }
}
}
E_FREE_FUNC(_eff->stack.old, eina_list_free);
E_FREE_FUNC(_eff->stack.cur, eina_list_free);
+ E_FREE_LIST(_eff->under_layers, free);
E_FREE_LIST(_eff->providers, e_comp_object_effect_mover_del);
E_FREE_LIST(_eff->event_hdlrs, ecore_event_handler_del);
E_FREE_LIST(_eff->hooks_ec, e_client_hook_del);