E_Comp_Wl_Subsurf_Data base;
E_Client *ec;
+
+ struct
+ {
+ E_Comp_Wl_Hook *ec_del;
+ E_Comp_Wl_Hook *parent_del;
+ } comp_hook;
};
static struct wl_global *global = NULL;
static void _e_comp_wl_subsurface_destroy(E_Subsurface *sub);
static void _e_comp_wl_subsurface_ec_link(E_Subsurface *sub, E_Client *ec);
static void _e_comp_wl_subsurface_parent_link(E_Subsurface *sub, E_Client *parent);
+static void _e_comp_wl_subsurface_parent_unlink(E_Subsurface *sub);
static void
_e_comp_wl_subsurface_restack_bg_rectangle(E_Client *ec)
evas_object_resize(ec->comp_data->sub.below_obj, ec->w, ec->h);
}
+static void
+_e_comp_wl_subsurface_bg_evas_cb_del(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj, void *event EINA_UNUSED)
+{
+ Evas_Object *below_obj;
+ E_Client *ec;
+
+ below_obj = data;
+ evas_object_del(below_obj);
+
+ ec = e_comp_object_client_get(obj);
+ if ((ec) && (ec->comp_data))
+ ec->comp_data->sub.below_obj = NULL;
+
+ evas_object_event_callback_del(obj, EVAS_CALLBACK_DEL,
+ _e_comp_wl_subsurface_bg_evas_cb_del);
+}
+
static Eina_Bool
_e_comp_wl_subsurface_video_has(E_Client *ec)
{
evas_object_event_callback_add(ec->frame, EVAS_CALLBACK_RESIZE,
_e_comp_wl_subsurface_bg_evas_cb_resize, ec);
+ evas_object_event_callback_add(ec->frame, EVAS_CALLBACK_DEL,
+ _e_comp_wl_subsurface_bg_evas_cb_del, below_obj);
/* set alpha only if SW path */
e_comp_object_alpha_set(ec->frame, EINA_TRUE);
_e_comp_wl_subsurface_below_obj_destroy(E_Client *ec)
{
ELOGF("COMP", " |bg_rectangle(%p) delete", ec, ec->comp_data->sub.below_obj);
+ evas_object_event_callback_del(ec->frame, EVAS_CALLBACK_DEL,
+ _e_comp_wl_subsurface_bg_evas_cb_del);
E_FREE_FUNC(ec->comp_data->sub.below_obj, evas_object_del);
}
_e_comp_wl_subsurface_show(ec);
}
-static void
-_e_comp_wl_surface_sub_list_free(Eina_List *sub_list)
-{
- E_Client *subc;
-
- EINA_LIST_FREE(sub_list, subc)
- {
- if (!subc->comp_data || !subc->comp_data->sub.data) continue;
-
- subc->comp_data->sub.data->parent = NULL;
-
- if (subc->comp_data->sub.watcher)
- tizen_subsurface_watcher_send_message(subc->comp_data->sub.watcher, TIZEN_SUBSURFACE_WATCHER_MSG_PARENT_ID_DESTROYED);
- }
-}
-
-static void
-_e_comp_wl_subsurface_cb_ec_del(void *data EINA_UNUSED, E_Client *ec)
-{
- /* make sure this is a wayland client */
- if (e_pixmap_type_get(ec->pixmap) != E_PIXMAP_TYPE_WL) return;
-
- if (!ec->comp_data)
- return;
-
- if (ec->comp_data->sub.data)
- {
- if (ec->comp_data->sub.data->parent)
- _e_comp_wl_subsurface_remove_from_parent(ec->comp_data->sub.data->parent, ec);
- _e_comp_wl_subsurface_destroy((E_Subsurface *)ec->comp_data->sub.data);
- ec->comp_data->sub.data = NULL;
- }
-
- if (ec->comp_data->sub.below_obj)
- {
- ELOGF("COMP", "ec deleted", ec);
- _e_comp_wl_subsurface_below_obj_destroy(ec);
- }
-
- /* remove sub list */
- /* TODO: if parent is set by onscreen_parent of remote surface? */
- _e_comp_wl_surface_sub_list_free(ec->comp_data->sub.list);
- ec->comp_data->sub.list = NULL;
- _e_comp_wl_surface_sub_list_free(ec->comp_data->sub.list_pending);
- ec->comp_data->sub.list_pending = NULL;
- _e_comp_wl_surface_sub_list_free(ec->comp_data->sub.below_list);
- ec->comp_data->sub.below_list = NULL;
- _e_comp_wl_surface_sub_list_free(ec->comp_data->sub.below_list_pending);
- ec->comp_data->sub.below_list_pending = NULL;
-}
-
static void
_e_comp_wl_subsurface_cb_resource_destroy(struct wl_resource *resource)
{
if (!e_object_unref(E_OBJECT(ec))) return;
if (e_object_is_del(E_OBJECT(ec))) return;
- if ((ec->comp_data) && (ec->comp_data->sub.data))
- {
- if (ec->comp_data->sub.data->parent)
- _e_comp_wl_subsurface_remove_from_parent(ec->comp_data->sub.data->parent, ec);
- _e_comp_wl_subsurface_destroy((E_Subsurface *)ec->comp_data->sub.data);
- ec->comp_data->sub.data = NULL;
- }
+ if (!ec->comp_data->sub.data)
+ return;
+
+ _e_comp_wl_subsurface_destroy((E_Subsurface *)ec->comp_data->sub.data);
}
static Eina_Bool
return EINA_FALSE;
}
- E_LIST_HOOK_APPEND(hooks, E_CLIENT_HOOK_DEL, _e_comp_wl_subsurface_cb_ec_del, NULL);
E_LIST_HOOK_APPEND(hooks, E_CLIENT_HOOK_ICONIFY, _e_comp_wl_subsurface_cb_ec_iconify, NULL);
E_LIST_HOOK_APPEND(hooks, E_CLIENT_HOOK_UNICONIFY, _e_comp_wl_subsurface_cb_ec_uniconify, NULL);
static void
_e_comp_wl_subsurface_destroy(E_Subsurface *sub)
{
+ sub->ec->comp_data->sub.data = NULL;
+
+ if (sub->base.parent)
+ _e_comp_wl_subsurface_parent_unlink(sub);
+
+ E_FREE_FUNC(sub->comp_hook.ec_del, e_comp_wl_hook_del);
+
e_comp_wl_surface_state_finish(&sub->base.cached);
e_comp_wl_buffer_reference(&sub->base.cached_buffer_ref, NULL);
free(sub);
}
+static void
+_e_comp_wl_subsurface_cb_comp_data_del(void *data, E_Client *ec)
+{
+ E_Subsurface *sub;
+
+ sub = data;
+ if (sub->ec != ec)
+ return;
+
+ ELOGF("SUBSURFACE", "The comp_data of E_Client is deleted", ec);
+
+ _e_comp_wl_subsurface_destroy(sub);
+}
+
static void
_e_comp_wl_subsurface_ec_link(E_Subsurface *sub, E_Client *ec)
{
sub->ec = ec;
+ sub->comp_hook.ec_del =
+ e_comp_wl_hook_add(E_COMP_WL_HOOK_DEL,
+ _e_comp_wl_subsurface_cb_comp_data_del,
+ sub);
ec->comp_data->surface = ec->comp_data->wl_surface;
ec->comp_data->sub.data = &sub->base;
e_client_unignore(ec);
}
+static void
+_e_comp_wl_subsurface_cb_parent_comp_data_del(void *data, E_Client *ec)
+{
+ E_Subsurface *sub;
+
+ sub = data;
+ if (sub->base.parent != ec)
+ return;
+
+ ELOGF("SUBSURFACE", "The comp_data of parent E_Client is deleted", ec);
+
+ if ((sub->ec) &&
+ (sub->ec->comp_data->sub.watcher))
+ tizen_subsurface_watcher_send_message(sub->ec->comp_data->sub.watcher,
+ TIZEN_SUBSURFACE_WATCHER_MSG_PARENT_ID_DESTROYED);
+
+ _e_comp_wl_subsurface_parent_unlink(sub);
+}
+
static void
_e_comp_wl_subsurface_parent_link(E_Subsurface *sub, E_Client *parent)
{
/* set subsurface data properties */
sub->base.parent = parent;
+ sub->comp_hook.parent_del =
+ e_comp_wl_hook_add(E_COMP_WL_HOOK_DEL,
+ _e_comp_wl_subsurface_cb_parent_comp_data_del,
+ sub);
if (parent->frame)
{
parent->comp_data->sub.list_changed = EINA_TRUE;
}
}
+
+static void
+_e_comp_wl_subsurface_parent_unlink(E_Subsurface *sub)
+{
+ _e_comp_wl_subsurface_remove_from_parent(sub->base.parent, sub->ec);
+ E_FREE_FUNC(sub->comp_hook.parent_del, e_comp_wl_hook_del);
+ sub->base.parent = NULL;
+}