};
/* private data for kvm */
-static E_Service_Kvm *_kvm_service = NULL;
+static Eina_Hash *_kvm_service_hash = NULL;
/* event handler */
static E_Client_Hook *_kvm_del_hook = NULL;
static Eina_List *_kvm_drag_hook_list = NULL;
-static Eina_List *_kvm_ecore_event_handlers = NULL;
static void _e_service_kvm_send_client_enter(E_Client *ec);
static void _e_service_kvm_send_client_leave(E_Client *ec);
static void
-_kvm_client_del(void)
+_kvm_service_del(E_Service_Kvm *esk)
{
- E_Drag_Hook *drag_hook;
- EINA_LIST_FREE(_kvm_drag_hook_list, drag_hook)
- {
- e_drag_hook_del(drag_hook);
- }
- E_FREE_FUNC(_kvm_del_hook, e_client_hook_del);
- E_FREE_LIST(_kvm_ecore_event_handlers, ecore_event_handler_del);
- E_FREE(_kvm_service);
+ EINA_SAFETY_ON_NULL_RETURN(esk);
+
+ eina_hash_del(_kvm_service_hash, &esk->ec, esk);
+
+ E_FREE(esk);
e_comp_wl->selection.secondary = NULL;
+
+ if (eina_hash_population(_kvm_service_hash) == 0)
+ {
+ ELOGF("KVM", "kvm service hash is empty. shutdown kvm service.", NULL);
+ e_service_kvm_shutdown();
+ _kvm_service_hash = NULL;
+ }
}
static void
_kvm_hook_client_del(void *d EINA_UNUSED, E_Client *ec)
{
+ E_Service_Kvm *esk;
+
if (!ec) return;
- if (!_kvm_service) return;
- if (ec != _kvm_service->ec) return;
- ELOGF("KVM","Del Client", ec);
+ esk = eina_hash_find(_kvm_service_hash, &ec);
+ if (!esk) return;
+
+ ELOGF("KVM","Del service of Client", ec);
- _kvm_client_del();
+ _kvm_service_del(esk);
}
static void
_kvm_hook_drag_start(void *d EINA_UNUSED, E_Drag *drag)
{
E_Comp_Wl_Data_Source *source;
+ E_Service_Kvm *esk;
+ Eina_Iterator *it;
struct wl_client *source_client, *kvm_client;
if (!drag) return;
- if (!_kvm_service) return;
-
- // Workaround: Feed mouse out/in to make sure that the mouse in to correct client.
- // The evas event mouse in/out is not emit during dragging(mouse move with mouse button pressed).
- // It makes the pointer still locked after mouse out from kvm window When the drag started.
- source = e_comp_wl->drag_source;
- source_client = wl_resource_get_client(source->resource);
- kvm_client = wl_resource_get_client(_kvm_service->srv_kvm_res);
- if (source_client == kvm_client)
+ if (!_kvm_service_hash) return;
+
+ it = eina_hash_iterator_data_new(_kvm_service_hash);
+
+ EINA_ITERATOR_FOREACH(it, esk)
{
- e_comp_ungrab_input(1, 1);
+ // Workaround: Feed mouse out/in to make sure that the mouse in to correct client.
+ // The evas event mouse in/out is not emit during dragging(mouse move with mouse button pressed).
+ // It makes the pointer still locked after mouse out from kvm window When the drag started.
+ source = e_comp_wl->drag_source;
+ source_client = wl_resource_get_client(source->resource);
+ kvm_client = wl_resource_get_client(esk->srv_kvm_res);
+ if (source_client == kvm_client)
+ {
+ e_comp_ungrab_input(1, 1);
+ }
+
+ e_service_kvm_send_drag_start(esk);
}
-
- e_service_kvm_send_drag_start();
+ eina_iterator_free(it);
}
static void
_kvm_hook_drag_end(void *d EINA_UNUSED, E_Drag *drag)
{
+ E_Service_Kvm *esk;
+ Eina_Iterator *it;
+
if (!drag) return;
- if (!_kvm_service) return;
+ if (!_kvm_service_hash) return;
+
+ it = eina_hash_iterator_data_new(_kvm_service_hash);
- e_service_kvm_send_drag_end();
- if (_kvm_service->force_entered)
- _e_service_kvm_send_client_leave(_kvm_service->ec);
+ EINA_ITERATOR_FOREACH(it, esk)
+ {
+ e_service_kvm_send_drag_end(esk);
+ if (esk->force_entered)
+ _e_service_kvm_send_client_leave(esk->ec);
+ }
+ eina_iterator_free(it);
}
EINTERN Eina_Bool
e_service_kvm_client_set(E_Client *ec)
{
E_Service_Kvm *esk;
- E_Drag_Hook *drag_hook;
+ Eina_Bool res = EINA_FALSE;
if (!ec) return EINA_FALSE;
if (e_object_is_del(E_OBJECT(ec))) return EINA_FALSE;
- if (_kvm_service)
+ if (!_kvm_service_hash)
+ {
+ res = e_service_kvm_init();
+ if (!res)
+ {
+ ELOGF("KVM", "kvm service init failed.", NULL);
+ return EINA_FALSE;
+ }
+ }
+
+ esk = eina_hash_find(_kvm_service_hash, &ec);
+ if (esk)
{
- ELOGF("KVM", "kvm service client is already registered. registered(%p)", ec, _kvm_service->ec);
+ ELOGF("KVM", "kvm service client is already registered. kvm service(%p)", ec, esk);
return EINA_FALSE;
}
esk = E_NEW(E_Service_Kvm, 1);
EINA_SAFETY_ON_NULL_RETURN_VAL(esk, EINA_FALSE);
- ELOGF("KVM","Set Client", ec);
+ ELOGF("KVM","kvm service: %p Set Client", ec, esk);
esk->ec = ec;
esk->enable = EINA_FALSE;
- _kvm_service = esk;
-
- _kvm_del_hook =
- e_client_hook_add(E_CLIENT_HOOK_DEL, _kvm_hook_client_del, NULL);
-
- drag_hook = e_drag_hook_add(E_DRAG_HOOK_DRAG_START, _kvm_hook_drag_start, NULL);
- if (drag_hook)
- _kvm_drag_hook_list = eina_list_append(_kvm_drag_hook_list, drag_hook);
-
- drag_hook = e_drag_hook_add(E_DRAG_HOOK_DRAG_END, _kvm_hook_drag_end, NULL);
- if (drag_hook)
- _kvm_drag_hook_list = eina_list_append(_kvm_drag_hook_list, drag_hook);
+ eina_hash_add(_kvm_service_hash, &ec, esk);
// SET LAYER
if (ec->layer != E_POLICY_KVM_LAYER)
}
EINTERN E_Client *
-e_service_kvm_client_get(void)
+e_service_kvm_client_get(E_Service_Kvm *esk)
{
- if (!_kvm_service) return NULL;
- return _kvm_service->ec;
+ if (!esk) return NULL;
+ return esk->ec;
}
EINTERN E_Service_Kvm *
-e_service_kvm_get(void)
+e_service_kvm_service_get(E_Client *ec)
{
- if (!_kvm_service) return NULL;
- return _kvm_service;
+ if (!ec) return NULL;
+ if (!_kvm_service_hash) return NULL;
+
+ return eina_hash_find(_kvm_service_hash, &ec);
}
EINTERN void
-e_service_kvm_wl_resource_set(E_Service_Kvm *service, struct wl_resource *res)
+e_service_kvm_wl_resource_set(E_Service_Kvm *esk, struct wl_resource *res)
{
- EINA_SAFETY_ON_NULL_RETURN(service);
+ EINA_SAFETY_ON_NULL_RETURN(esk);
EINA_SAFETY_ON_NULL_RETURN(res);
- service->srv_kvm_res = res;
+ esk->srv_kvm_res = res;
}
EINTERN Eina_Bool
-e_service_kvm_send_drag_start(void)
+e_service_kvm_send_drag_start(E_Service_Kvm *esk)
{
- EINA_SAFETY_ON_NULL_RETURN_VAL(_kvm_service, EINA_FALSE);
- EINA_SAFETY_ON_NULL_RETURN_VAL(_kvm_service->ec, EINA_FALSE);
- EINA_SAFETY_ON_NULL_RETURN_VAL(_kvm_service->srv_kvm_res, EINA_FALSE);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(esk, EINA_FALSE);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(esk->ec, EINA_FALSE);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(esk->srv_kvm_res, EINA_FALSE);
- ELOGF("KVM", "Drag start send!", _kvm_service->ec);
- _kvm_service->perform_requested = EINA_FALSE;
+ ELOGF("KVM", "Drag start send!", esk->ec);
+ esk->perform_requested = EINA_FALSE;
- tws_service_kvm_send_drag_start(_kvm_service->srv_kvm_res);
+ tws_service_kvm_send_drag_start(esk->srv_kvm_res);
return EINA_TRUE;
}
EINTERN Eina_Bool
-e_service_kvm_send_drag_end(void)
+e_service_kvm_send_drag_end(E_Service_Kvm *esk)
{
- EINA_SAFETY_ON_NULL_RETURN_VAL(_kvm_service, EINA_FALSE);
- EINA_SAFETY_ON_NULL_RETURN_VAL(_kvm_service->ec, EINA_FALSE);
- EINA_SAFETY_ON_NULL_RETURN_VAL(_kvm_service->srv_kvm_res, EINA_FALSE);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(esk, EINA_FALSE);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(esk->ec, EINA_FALSE);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(esk->srv_kvm_res, EINA_FALSE);
- if (!_kvm_service->perform_requested)
+ if (!esk->perform_requested)
{
- ELOGF("KVM", "Drag end send!", _kvm_service->ec);
- tws_service_kvm_send_drag_end(_kvm_service->srv_kvm_res);
+ ELOGF("KVM", "Drag end send!", esk->ec);
+ tws_service_kvm_send_drag_end(esk->srv_kvm_res);
}
return EINA_TRUE;
EINTERN Eina_Bool
e_service_kvm_drop_perform(E_Client *ec)
{
+ E_Service_Kvm *esk;
E_Client *legacy_target_ec;
+
EINA_SAFETY_ON_NULL_RETURN_VAL(ec, EINA_FALSE);
- EINA_SAFETY_ON_NULL_RETURN_VAL(_kvm_service, EINA_FALSE);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(_kvm_service_hash, EINA_FALSE);
- if (ec != _kvm_service->ec)
+ esk = eina_hash_find(_kvm_service_hash, &ec);
+
+ if (!esk)
{
- ELOGF("KVM", "ERROR... kvm service ec is not matched. regisered(%p)", ec, _kvm_service->ec);
+ ELOGF("KVM", "ERROR... kvm service for ec doesn't exist.", ec);
return EINA_FALSE;
}
- ELOGF("KVM", "Drop perform requested!", ec);
+ ELOGF("KVM", "Drop perform requested! service:%p", ec, esk);
- _kvm_service->perform_requested = EINA_TRUE;
+ esk->perform_requested = EINA_TRUE;
legacy_target_ec = e_comp_wl->selection.target;
if (legacy_target_ec != ec)
EINTERN Eina_Bool
e_service_kvm_drag_cancel(E_Client *ec)
{
+ E_Service_Kvm *esk;
+
EINA_SAFETY_ON_NULL_RETURN_VAL(ec, EINA_FALSE);
- EINA_SAFETY_ON_NULL_RETURN_VAL(_kvm_service, EINA_FALSE);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(_kvm_service_hash, EINA_FALSE);
+
+ esk = eina_hash_find(_kvm_service_hash, &ec);
- if (ec != _kvm_service->ec)
+ if (!esk)
{
- ELOGF("KVM", "ERROR... kvm service ec is not matched. regisered(%p)", ec, _kvm_service->ec);
+ ELOGF("KVM", "ERROR... kvm service for ec doesn't exist.", ec);
return EINA_FALSE;
}
- ELOGF("KVM", "Cancel drag by kvm_service request!", ec);
+ ELOGF("KVM", "Cancel drag by kvm_service request! service:%p", ec, esk);
e_drag_end(e_comp_wl->drag, E_DND_DRAG_TYPE_CANCELLED);
EINTERN Eina_Bool
e_service_kvm_perform_drag_enter(E_Client *ec)
{
+ E_Service_Kvm *esk;
+
EINA_SAFETY_ON_NULL_RETURN_VAL(ec, EINA_FALSE);
- EINA_SAFETY_ON_NULL_RETURN_VAL(_kvm_service, EINA_FALSE);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(_kvm_service_hash, EINA_FALSE);
+
+ esk = eina_hash_find(_kvm_service_hash, &ec);
- if (ec != _kvm_service->ec)
+ if (!esk)
{
- ELOGF("KVM", "ERROR... kvm service ec is not matched. regisered(%p)", ec, _kvm_service->ec);
+ ELOGF("KVM", "ERROR... kvm service for ec doesn't exist.", ec);
return EINA_FALSE;
}
- ELOGF("KVM", "Send force drag enter by kvm_service request!", ec);
+ ELOGF("KVM", "Send force drag enter by kvm_service request! service:%p", ec, esk);
- _e_service_kvm_send_client_enter(_kvm_service->ec);
- _kvm_service->force_entered = EINA_TRUE;
+ _e_service_kvm_send_client_enter(esk->ec);
+ esk->force_entered = EINA_TRUE;
return EINA_TRUE;
}
EINTERN Eina_Bool
e_service_kvm_perform_drag_leave(E_Client *ec)
{
+ E_Service_Kvm *esk;
+
EINA_SAFETY_ON_NULL_RETURN_VAL(ec, EINA_FALSE);
- EINA_SAFETY_ON_NULL_RETURN_VAL(_kvm_service, EINA_FALSE);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(_kvm_service_hash, EINA_FALSE);
+
+ esk = eina_hash_find(_kvm_service_hash, &ec);
- if (ec != _kvm_service->ec)
+ if (!esk)
{
- ELOGF("KVM", "ERROR... kvm service ec is not matched. regisered(%p)", ec, _kvm_service->ec);
+ ELOGF("KVM", "ERROR... kvm service for ec doesn't exist.", ec);
return EINA_FALSE;
}
- ELOGF("KVM", "Send force drag leave by kvm_service request!", ec);
+ ELOGF("KVM", "Send force drag leave by kvm_service request! service:%p", ec, esk);
- _e_service_kvm_send_client_leave(_kvm_service->ec);
- _kvm_service->force_entered = EINA_FALSE;
+ _e_service_kvm_send_client_leave(esk->ec);
+ esk->force_entered = EINA_FALSE;
return EINA_TRUE;
}
e_service_kvm_secondary_selection_set(E_Client *ec, Eina_Bool set)
{
E_Comp_Wl_Client_Data *cdata;
+ E_Service_Kvm *esk;
+
EINA_SAFETY_ON_NULL_RETURN_VAL(ec, EINA_FALSE);
- EINA_SAFETY_ON_NULL_RETURN_VAL(_kvm_service, EINA_FALSE);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(_kvm_service_hash, EINA_FALSE);
+
+ esk = eina_hash_find(_kvm_service_hash, &ec);
- if (ec != _kvm_service->ec)
+ if (!esk)
{
- ELOGF("KVM", "ERROR... kvm service ec is not matched. regisered(%p)", ec, _kvm_service->ec);
+ ELOGF("KVM", "ERROR... kvm service for ec doesn't exist.", ec);
return EINA_FALSE;
}
- ELOGF("KVM", "secondary selection set requested!, set:%d", ec, set);
+ ELOGF("KVM", "secondary selection set requested! service:%p, set:%d", ec, esk, set);
cdata = e_client_cdata_get(ec);
if (set)
EINTERN Eina_Bool
e_service_kvm_transparent_set(E_Client *ec, Eina_Bool set)
{
+ E_Service_Kvm *esk;
+
EINA_SAFETY_ON_NULL_RETURN_VAL(ec, EINA_FALSE);
- EINA_SAFETY_ON_NULL_RETURN_VAL(_kvm_service, EINA_FALSE);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(_kvm_service_hash, EINA_FALSE);
- if (ec != _kvm_service->ec)
+ esk = eina_hash_find(_kvm_service_hash, &ec);
+
+ if (!esk)
{
- ELOGF("KVM", "ERROR... kvm service ec is not matched. regisered(%p)", ec, _kvm_service->ec);
+ ELOGF("KVM", "ERROR... kvm service for ec doesn't exist.", ec);
return EINA_FALSE;
}
- ELOGF("KVM", "set KVM service client to %s", ec, set? "transparent" : "opaque");
+ ELOGF("KVM", "set KVM service(%p) client to %s", ec, esk, set? "transparent" : "opaque");
if (set)
evas_object_color_set(ec->frame, 0, 0, 0, 0);
return EINA_TRUE;
}
+EINTERN Eina_Bool
+e_service_kvm_all_kvm_service_transparent_set(Eina_Bool set)
+{
+ E_Service_Kvm *esk;
+ Eina_Iterator *it;
+
+ EINA_SAFETY_ON_NULL_RETURN_VAL(_kvm_service_hash, EINA_FALSE);
+
+ it = eina_hash_iterator_data_new(_kvm_service_hash);
+
+ EINA_ITERATOR_FOREACH(it, esk)
+ {
+ e_service_kvm_transparent_set(esk->ec, set);
+ }
+ eina_iterator_free(it);
+
+ return EINA_TRUE;
+}
+
+EINTERN Eina_Bool
+e_service_kvm_init()
+{
+ E_Drag_Hook *drag_hook;
+
+ if (_kvm_service_hash)
+ {
+ ELOGF("KVM", "kvm service is already initialized.", NULL);
+ return EINA_FALSE;
+ }
+
+ _kvm_service_hash = eina_hash_pointer_new(NULL);
+ if (!_kvm_service_hash)
+ {
+ ELOGF("KVM", "kvm service hash create failed.", NULL);
+ return EINA_FALSE;
+ }
+
+ _kvm_del_hook = e_client_hook_add(E_CLIENT_HOOK_DEL, _kvm_hook_client_del, NULL);
+
+ drag_hook = e_drag_hook_add(E_DRAG_HOOK_DRAG_START, _kvm_hook_drag_start, NULL);
+ if (drag_hook)
+ _kvm_drag_hook_list = eina_list_append(_kvm_drag_hook_list, drag_hook);
+
+ drag_hook = e_drag_hook_add(E_DRAG_HOOK_DRAG_END, _kvm_hook_drag_end, NULL);
+ if (drag_hook)
+ _kvm_drag_hook_list = eina_list_append(_kvm_drag_hook_list, drag_hook);
+
+ return EINA_TRUE;
+}
+
+EINTERN void
+e_service_kvm_shutdown()
+{
+ E_Service_Kvm *esk;
+ E_Drag_Hook *drag_hook;
+ Eina_Iterator *it;
+
+ if (_kvm_service_hash)
+ {
+ it = eina_hash_iterator_data_new(_kvm_service_hash);
+ EINA_ITERATOR_FOREACH(it, esk)
+ {
+ _kvm_service_del(esk);
+ }
+ eina_iterator_free(it);
+ _kvm_service_hash = NULL;
+ }
+
+ EINA_LIST_FREE(_kvm_drag_hook_list, drag_hook)
+ {
+ e_drag_hook_del(drag_hook);
+ }
+
+ E_FREE_FUNC(_kvm_del_hook, e_client_hook_del);
+
+ return;
+}
+
static void
_e_service_kvm_send_client_enter(E_Client *ec)
{