#include <wayland-tbm-server.h>
#include "services/e_service_launcher.h"
-typedef struct _E_Service_Launcher E_Service_Launcher;
-typedef struct _E_Service_Launcher_Handler E_Service_Launcher_Handler;
+typedef struct _E_Service_Launcher E_Service_Launcher;
+typedef struct _E_Service_Launcher_Handler E_Service_Launcher_Handler;
+typedef struct _E_Service_Launcher_Consumer E_Service_Launcher_Consumer;
typedef enum
{
LAUNCHER_STATE_WAIT_RESPONSE_FROM_CALLEE,
} Launcher_State;
+struct _E_Service_Launcher_Consumer
+{
+ E_Service_Launcher *lc;
+ E_Vis_Grab *vis_grab; //grab of client's visibility
+
+ E_Client *ec;
+ E_Object_Delfn *delfn; //del callback of E_Client
+
+ Ecore_Event_Handler *buff_attach; //event handler for BUFFER_CHANGE
+ int buff_attach_count;
+};
+
struct _E_Service_Launcher
{
Launcher_State state; //current state of launcher
Eina_Bool swl_done; //flag indicating done of callee
Eina_Bool block_input; //input is blocked(1) or not(0) while running client side animation
+
+ Eina_List *consumers; //list launcher consumer of launcher ec
};
struct _E_Service_Launcher_Handler
}
static void
+_launcher_consumer_del(E_Service_Launcher_Consumer *consumer)
+{
+ E_Service_Launcher *lc;
+
+ EINA_SAFETY_ON_NULL_RETURN(consumer);
+
+ lc = consumer->lc;
+
+ ELOGF("LAUNCHER_SRV", "Del launcher_consumer ec:%p", lc ? lc->ec : NULL, consumer->ec);
+
+ if (consumer->ec)
+ {
+ e_object_delfn_del(E_OBJECT(consumer->ec), consumer->delfn);
+ consumer->ec = NULL;
+ consumer->delfn = NULL;
+ }
+
+ if (consumer->vis_grab)
+ {
+ e_policy_visibility_client_grab_release(consumer->vis_grab);
+ consumer->vis_grab = NULL;
+ }
+
+ if (consumer->buff_attach)
+ E_FREE_FUNC(consumer->buff_attach, ecore_event_handler_del);
+
+ if (lc)
+ lc->consumers = eina_list_remove(lc->consumers, consumer);
+
+ free(consumer);
+}
+
+static void
+_launcher_cb_consumer_ec_del(void *data, void *obj)
+{
+ E_Service_Launcher_Consumer *consumer;
+ E_Client *ec;
+
+ ec = (E_Client *)obj;
+ EINA_SAFETY_ON_NULL_RETURN(ec);
+
+ consumer= (E_Service_Launcher_Consumer *)data;
+ EINA_SAFETY_ON_NULL_RETURN(consumer);
+ EINA_SAFETY_ON_TRUE_RETURN(consumer->ec != ec);
+
+ consumer->ec = NULL;
+ consumer->delfn = NULL;
+
+ _launcher_consumer_del(consumer);
+}
+
+static E_Service_Launcher_Consumer *
+_launcher_consumer_create(E_Service_Launcher *lc, E_Client *ec)
+{
+ E_Service_Launcher_Consumer *consumer;
+
+ EINA_SAFETY_ON_NULL_RETURN_VAL(lc, NULL);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(ec, NULL);
+
+ consumer = E_NEW(E_Service_Launcher_Consumer, 1);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(consumer, NULL);
+
+ consumer->ec = ec;
+ consumer->delfn = e_object_delfn_add(E_OBJECT(ec),
+ _launcher_cb_consumer_ec_del, consumer);
+
+ consumer->lc = lc;
+ lc->consumers = eina_list_append(lc->consumers, consumer);
+
+ ELOGF("LAUNCHER_SRV", "Create launcher_consumer ec:%p", lc->ec, ec);
+
+ return consumer;
+}
+
+static void
+_launcher_consumers_reset(E_Service_Launcher *lc)
+{
+ E_Service_Launcher_Consumer *consumer;
+ Eina_List *l, *ll;
+
+ EINA_SAFETY_ON_NULL_RETURN(lc);
+
+ EINA_LIST_FOREACH_SAFE(lc->consumers, l, ll, consumer)
+ _launcher_consumer_del(consumer);
+}
+
+static void
_launcher_post_forward(E_Service_Launcher *lc, Eina_Bool success)
{
E_Client *target_ec = NULL;
lc->vis_grab = NULL;
lc->target.vis_grab = NULL;
+ _launcher_consumers_reset(lc);
+
if (!target_ec) return;
if (success)
{
int x, y;
Eina_Bool sent = EINA_FALSE;
+ Eina_List *consumers;
+ Eina_List *l;
+ E_Client *ec;
+ E_Service_Launcher_Consumer *consumer;
EINA_SAFETY_ON_NULL_RETURN_VAL(lc, EINA_FALSE);
EINA_SAFETY_ON_NULL_RETURN_VAL(activity, EINA_FALSE);
e_policy_animatable_lock(target_ec, E_POLICY_ANIMATABLE_CUSTOMIZED, 1);
e_comp_client_override_add(target_ec);
+ if ((lc->ec) && (lc->ec->remote_surface.provider))
+ {
+ consumers = e_comp_wl_remote_surface_consumers_get(lc->ec);
+ EINA_LIST_FOREACH(consumers, l, ec)
+ {
+ if (e_object_is_del(E_OBJECT(ec))) continue;
+ if (!e_policy_visibility_client_is_uniconify_render_running(ec)) continue;
+
+ consumer = _launcher_consumer_create(lc, ec);
+ consumer->vis_grab = e_policy_visibility_client_filtered_grab_get(ec,
+ (E_VIS_JOB_TYPE_UNICONIFY |
+ E_VIS_JOB_TYPE_UNICONIFY_BY_VISIBILITY),
+ __func__);
+ }
+ eina_list_free(consumers);
+ }
+
if (activity == target_ec)
{
lc->vis_grab = e_policy_visibility_client_filtered_grab_get(lc->ec, job_type, __func__);
_launcher_state_set(lc, LAUNCHER_STATE_IDLE);
_launcher_launched_ec_set(lc, NULL);
+ _launcher_consumers_reset(lc);
_launcher_handler_launcher_runner_unset(lc);
_launcher_handler_launcher_pre_runner_unset(lc);
}
static Eina_Bool
+_launcher_cb_launching_consumer_buff_attach(void *data, int type EINA_UNUSED, void *event)
+{
+ E_Service_Launcher *lc;
+ E_Service_Launcher_Consumer *consumer;
+ E_Client *ec;
+ E_Event_Client *ev;
+
+ consumer = (E_Service_Launcher_Consumer*)data;
+ EINA_SAFETY_ON_NULL_RETURN_VAL(consumer, ECORE_CALLBACK_PASS_ON);
+ lc = consumer->lc;
+ EINA_SAFETY_ON_NULL_GOTO(lc, clean);
+ EINA_SAFETY_ON_FALSE_GOTO(lc->direction == TWS_SERVICE_LAUNCHER_DIRECTION_BACKWARD, clean);
+
+ ev = (E_Event_Client *)event;
+ EINA_SAFETY_ON_NULL_RETURN_VAL(ev, ECORE_CALLBACK_PASS_ON);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(ev->ec, ECORE_CALLBACK_PASS_ON);
+
+ ec = ev->ec;
+ if (ec != consumer->ec) return ECORE_CALLBACK_PASS_ON;
+
+ ELOGF("LAUNCHER_SRV", "Event cb(BUFFER_CHANGE) for WAIT_CONSUMER_LAUNCHING count:%d",
+ ec, consumer->buff_attach_count);
+
+ consumer->buff_attach_count++;
+ if (consumer->buff_attach_count < 2) return ECORE_CALLBACK_PASS_ON;
+
+ if (consumer->vis_grab)
+ {
+ e_policy_visibility_client_grab_release(consumer->vis_grab);
+ consumer->vis_grab = NULL;
+ }
+
+clean:
+ _launcher_consumer_del(consumer);
+
+ return ECORE_CALLBACK_PASS_ON;
+}
+
+static void
+_launcher_consumers_buffer_change_wait(E_Service_Launcher *lc)
+{
+ E_Service_Launcher_Consumer *consumer;
+ Eina_List *l;
+
+ EINA_LIST_FOREACH(lc->consumers, l, consumer)
+ consumer->buff_attach = ecore_event_handler_add(E_EVENT_CLIENT_BUFFER_CHANGE,
+ _launcher_cb_launching_consumer_buff_attach,
+ consumer);
+}
+
+static Eina_Bool
_launcher_cb_launching_buff_attach(void *data, int type EINA_UNUSED, void *event)
{
E_Service_Launcher *lc;
ELOGF("LAUNCHER_SRV", "Event cb(BUFFER_CHANGE) for LAUNCHING", ec);
if (lc->state == LAUNCHER_STATE_LAUNCHING_WAIT_BUFFER)
- _launcher_state_set(lc, LAUNCHER_STATE_LAUNCHING);
+ {
+ _launcher_consumers_buffer_change_wait(lc);
+ _launcher_state_set(lc, LAUNCHER_STATE_LAUNCHING);
+ }
if (lc->vis_grab)
{