--- /dev/null
+#include "e.h"
+#include "services/e_service_kvm.h"
+
+#include <wayland-server.h>
+#include <tzsh_server.h>
+
+struct _E_Service_Kvm
+{
+ E_Client *ec;
+ Eina_Bool enable;
+ struct wl_resource *res_srv_mc;
+
+ Eina_Bool perform_requested;
+};
+
+/* private data for kvm */
+static E_Service_Kvm *_kvm_service = NULL;
+
+/* event handler */
+static E_Client_Hook *_kvm_del_hook = NULL;
+static Eina_List *_kvm_drag_hook_list = NULL;
+
+static void
+_kvm_client_del(void)
+{
+ 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(_kvm_service);
+}
+
+static void
+_kvm_hook_client_del(void *d EINA_UNUSED, E_Client *ec)
+{
+ if (!ec) return;
+ if (!_kvm_service) return;
+ if (ec != _kvm_service->ec) return;
+
+ ELOGF("KVM","Del Client", ec);
+
+ _kvm_client_del();
+}
+
+static void
+_kvm_hook_drag_start(void *d EINA_UNUSED, E_Drag *drag)
+{
+ if (!drag) return;
+ if (!_kvm_service) return;
+
+ e_service_kvm_send_drag_start();
+}
+
+static void
+_kvm_hook_drag_end(void *d EINA_UNUSED, E_Drag *drag)
+{
+ if (!drag) return;
+ if (!_kvm_service) return;
+
+ e_service_kvm_send_drag_end();
+}
+
+EINTERN Eina_Bool
+e_service_kvm_client_set(E_Client *ec)
+{
+ E_Service_Kvm *esk;
+ E_Drag_Hook *drag_hook;
+
+ if (!ec) return EINA_FALSE;
+ if (e_object_is_del(E_OBJECT(ec))) return EINA_FALSE;
+
+ if (_kvm_service)
+ {
+ ELOGF("KVM", "kvm service client is already registered. registered(%p)", ec, _kvm_service->ec);
+ return EINA_FALSE;
+ }
+
+ esk = E_NEW(E_Service_Kvm, 1);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(esk, EINA_FALSE);
+
+ ELOGF("KVM","Set Client", ec);
+
+ 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);
+
+ return EINA_TRUE;
+}
+
+EINTERN E_Client *
+e_service_kvm_client_get(void)
+{
+ if (!_kvm_service) return NULL;
+ return _kvm_service->ec;
+}
+
+EINTERN E_Service_Kvm *
+e_service_kvm_get(void)
+{
+ if (!_kvm_service) return NULL;
+ return _kvm_service;
+}
+
+EINTERN void
+e_service_kvm_wl_resource_set(E_Service_Kvm *service, struct wl_resource *res)
+{
+ EINA_SAFETY_ON_NULL_RETURN(service);
+ EINA_SAFETY_ON_NULL_RETURN(res);
+
+ service->res_srv_mc = res;
+}
+
+EINTERN Eina_Bool
+e_service_kvm_send_drag_start(void)
+{
+ 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->res_srv_mc, EINA_FALSE);
+
+ ELOGF("KVM", "Drag start send!", _kvm_service->ec);
+ _kvm_service->perform_requested = EINA_FALSE;
+
+ tws_service_kvm_send_drag_start(_kvm_service->res_srv_mc);
+
+ return EINA_TRUE;
+}
+
+EINTERN Eina_Bool
+e_service_kvm_send_drag_end(void)
+{
+ 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->res_srv_mc, EINA_FALSE);
+
+ if (!_kvm_service->perform_requested)
+ {
+ ELOGF("KVM", "Drag end send!", _kvm_service->ec);
+ tws_service_kvm_send_drag_end(_kvm_service->res_srv_mc);
+ }
+
+ return EINA_TRUE;
+}
+
+EINTERN Eina_Bool
+e_service_kvm_drop_perform(E_Client *ec)
+{
+ E_Client *legacy_target_ec;
+ EINA_SAFETY_ON_NULL_RETURN_VAL(ec, EINA_FALSE);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(_kvm_service, EINA_FALSE);
+
+ if (ec != _kvm_service->ec)
+ {
+ ELOGF("KVM", "ERROR... kvm service ec is not matched. regisered(%p)", ec, _kvm_service->ec);
+ return EINA_FALSE;
+ }
+
+ ELOGF("KVM", "Drop perform requested!", ec);
+
+ _kvm_service->perform_requested = EINA_TRUE;
+
+ legacy_target_ec = e_comp_wl->selection.target;
+ if (legacy_target_ec != ec)
+ {
+ e_comp_wl_data_device_send_leave(legacy_target_ec);
+ e_comp_wl_data_device_send_enter(ec);
+ }
+
+ e_comp_wl_data_offer_mimetype_action_accept(e_comp_wl->drag_offer);
+ e_drag_end(e_comp_wl->drag);
+
+ return EINA_TRUE;
+}
+
+EINTERN Eina_Bool
+e_service_kvm_secondary_selection_set(E_Client *ec, Eina_Bool set)
+{
+ EINA_SAFETY_ON_NULL_RETURN_VAL(ec, EINA_FALSE);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(_kvm_service, EINA_FALSE);
+
+ if (ec != _kvm_service->ec)
+ {
+ ELOGF("KVM", "ERROR... kvm service ec is not matched. regisered(%p)", ec, _kvm_service->ec);
+ return EINA_FALSE;
+ }
+
+ ELOGF("KVM", "secondary selection set requested!, set:%d", ec, set);
+
+ //TODO: set as secondary selection
+
+ return EINA_TRUE;
+}