2015-08-04 15:56:18 -07:00
|
|
|
#define EXECUTIVE_MODE_ENABLED
|
2014-08-04 09:58:49 -07:00
|
|
|
#define E_COMP_WL
|
2014-05-09 02:28:47 -07:00
|
|
|
#include "e.h"
|
|
|
|
|
2015-08-12 14:39:15 -07:00
|
|
|
static void
|
|
|
|
_mime_types_free(E_Comp_Wl_Data_Source *source)
|
|
|
|
{
|
|
|
|
if (!source->mime_types) return;
|
|
|
|
while (eina_array_count(source->mime_types))
|
|
|
|
eina_stringshare_del(eina_array_pop(source->mime_types));
|
|
|
|
eina_array_free(source->mime_types);
|
|
|
|
}
|
|
|
|
|
2014-05-09 02:28:47 -07:00
|
|
|
static void
|
2014-07-01 04:03:07 -07:00
|
|
|
_e_comp_wl_data_offer_cb_accept(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, uint32_t serial, const char *mime_type)
|
|
|
|
{
|
|
|
|
E_Comp_Wl_Data_Offer *offer;
|
|
|
|
|
2014-08-26 11:11:28 -07:00
|
|
|
DBG("Data Offer Accept");
|
2014-07-01 04:03:07 -07:00
|
|
|
if (!(offer = wl_resource_get_user_data(resource)))
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (offer->source)
|
|
|
|
offer->source->target(offer->source, serial, mime_type);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_e_comp_wl_data_offer_cb_receive(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, const char *mime_type, int32_t fd)
|
|
|
|
{
|
|
|
|
E_Comp_Wl_Data_Offer *offer;
|
|
|
|
|
2014-08-26 11:11:28 -07:00
|
|
|
DBG("Data Offer Receive");
|
|
|
|
|
2014-07-01 04:03:07 -07:00
|
|
|
if (!(offer = wl_resource_get_user_data(resource)))
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (offer->source)
|
|
|
|
offer->source->send(offer->source, mime_type, fd);
|
|
|
|
else
|
|
|
|
close(fd);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* called by wl_data_offer_destroy */
|
|
|
|
static void
|
|
|
|
_e_comp_wl_data_offer_cb_destroy(struct wl_client *client EINA_UNUSED, struct wl_resource *resource)
|
|
|
|
{
|
2014-08-26 11:11:28 -07:00
|
|
|
DBG("Data Offer Destroy");
|
2014-07-01 04:03:07 -07:00
|
|
|
wl_resource_destroy(resource);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* called by wl_resource_destroy */
|
|
|
|
static void
|
|
|
|
_e_comp_wl_data_offer_cb_resource_destroy(struct wl_resource *resource)
|
|
|
|
{
|
|
|
|
E_Comp_Wl_Data_Offer *offer;
|
|
|
|
|
|
|
|
if (!(offer = wl_resource_get_user_data(resource)))
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (offer->source)
|
|
|
|
wl_list_remove(&offer->source_destroy_listener.link);
|
|
|
|
|
|
|
|
free(offer);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* called by emission of source->destroy_signal */
|
|
|
|
static void
|
|
|
|
_e_comp_wl_data_offer_cb_source_destroy(struct wl_listener *listener, void *data EINA_UNUSED)
|
|
|
|
{
|
|
|
|
E_Comp_Wl_Data_Offer *offer;
|
|
|
|
|
2014-08-26 11:11:28 -07:00
|
|
|
DBG("Data Offer Source Destroy");
|
2014-07-01 04:08:05 -07:00
|
|
|
offer = container_of(listener, E_Comp_Wl_Data_Offer,
|
|
|
|
source_destroy_listener);
|
|
|
|
if (!offer) return;
|
|
|
|
|
2014-07-01 04:03:07 -07:00
|
|
|
offer->source = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
static const struct wl_data_offer_interface _e_data_offer_interface =
|
|
|
|
{
|
|
|
|
_e_comp_wl_data_offer_cb_accept,
|
|
|
|
_e_comp_wl_data_offer_cb_receive,
|
|
|
|
_e_comp_wl_data_offer_cb_destroy,
|
|
|
|
};
|
|
|
|
|
|
|
|
static void
|
|
|
|
_e_comp_wl_data_source_cb_offer(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, const char *mime_type)
|
|
|
|
{
|
|
|
|
E_Comp_Wl_Data_Source *source;
|
|
|
|
|
2014-08-26 11:11:28 -07:00
|
|
|
DBG("Data Source Offer");
|
2014-07-01 04:03:07 -07:00
|
|
|
if (!(source = wl_resource_get_user_data(resource)))
|
|
|
|
return;
|
|
|
|
|
2015-08-12 15:42:42 -07:00
|
|
|
if (!source->mime_types)
|
|
|
|
source->mime_types = eina_array_new(1);
|
2015-08-12 14:39:15 -07:00
|
|
|
eina_array_push(source->mime_types, eina_stringshare_add(mime_type));
|
2014-07-01 04:03:07 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
/* called by wl_data_source_destroy */
|
|
|
|
static void
|
|
|
|
_e_comp_wl_data_source_cb_destroy(struct wl_client *client EINA_UNUSED, struct wl_resource *resource)
|
|
|
|
{
|
2014-08-26 11:11:28 -07:00
|
|
|
DBG("Data Source Destroy");
|
2014-07-01 04:03:07 -07:00
|
|
|
wl_resource_destroy(resource);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* called by wl_resource_destroy */
|
|
|
|
static void
|
|
|
|
_e_comp_wl_data_source_cb_resource_destroy(struct wl_resource *resource)
|
|
|
|
{
|
|
|
|
E_Comp_Wl_Data_Source *source;
|
|
|
|
|
|
|
|
if (!(source = wl_resource_get_user_data(resource)))
|
|
|
|
return;
|
|
|
|
|
|
|
|
wl_signal_emit(&source->destroy_signal, source);
|
|
|
|
|
2015-08-12 14:39:15 -07:00
|
|
|
_mime_types_free(source);
|
2014-07-01 04:03:07 -07:00
|
|
|
free(source);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_e_comp_wl_data_source_target_send(E_Comp_Wl_Data_Source *source, uint32_t serial EINA_UNUSED, const char* mime_type)
|
|
|
|
{
|
2014-08-26 11:11:28 -07:00
|
|
|
DBG("Data Source Target Send");
|
2014-07-01 04:03:07 -07:00
|
|
|
wl_data_source_send_target(source->resource, mime_type);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_e_comp_wl_data_source_send_send(E_Comp_Wl_Data_Source *source, const char* mime_type, int32_t fd)
|
|
|
|
{
|
2014-08-26 11:11:28 -07:00
|
|
|
DBG("Data Source Source Send");
|
2014-07-01 04:03:07 -07:00
|
|
|
wl_data_source_send_send(source->resource, mime_type, fd);
|
|
|
|
close(fd);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_e_comp_wl_data_source_cancelled_send(E_Comp_Wl_Data_Source *source)
|
|
|
|
{
|
2014-08-26 11:11:28 -07:00
|
|
|
DBG("Data Source Cancelled Send");
|
2014-07-01 04:03:07 -07:00
|
|
|
wl_data_source_send_cancelled(source->resource);
|
|
|
|
}
|
|
|
|
|
|
|
|
static const struct wl_data_source_interface _e_data_source_interface =
|
|
|
|
{
|
|
|
|
_e_comp_wl_data_source_cb_offer,
|
|
|
|
_e_comp_wl_data_source_cb_destroy,
|
|
|
|
};
|
|
|
|
|
|
|
|
static void
|
2015-05-18 06:22:39 -07:00
|
|
|
_e_comp_wl_data_device_destroy_selection_data_source(struct wl_listener *listener EINA_UNUSED, void *data)
|
2014-07-01 04:03:07 -07:00
|
|
|
{
|
|
|
|
E_Comp_Wl_Data_Source *source;
|
2015-08-10 15:49:04 -07:00
|
|
|
struct wl_resource *data_device_res = NULL, *focus = NULL;
|
2014-07-01 04:03:07 -07:00
|
|
|
|
2015-08-04 15:51:41 -07:00
|
|
|
DBG("Data Device Destroy Selection Source");
|
2014-07-01 04:03:07 -07:00
|
|
|
if (!(source = (E_Comp_Wl_Data_Source*)data))
|
|
|
|
return;
|
|
|
|
|
2015-08-13 13:05:57 -07:00
|
|
|
e_comp_wl->selection.data_source = NULL;
|
2014-07-01 04:03:07 -07:00
|
|
|
|
2015-08-13 13:05:57 -07:00
|
|
|
if (e_comp_wl->kbd.enabled)
|
|
|
|
focus = e_comp_wl->kbd.focus;
|
2014-07-01 04:03:07 -07:00
|
|
|
|
2014-07-09 08:06:25 -07:00
|
|
|
if (focus)
|
|
|
|
{
|
2015-08-10 15:49:04 -07:00
|
|
|
if (source->resource)
|
|
|
|
data_device_res =
|
|
|
|
e_comp_wl_data_find_for_client(wl_resource_get_client(source->resource));
|
2014-07-09 08:06:25 -07:00
|
|
|
|
|
|
|
if (data_device_res)
|
|
|
|
wl_data_device_send_selection(data_device_res, NULL);
|
|
|
|
}
|
2014-07-01 04:03:07 -07:00
|
|
|
|
2015-08-13 13:05:57 -07:00
|
|
|
wl_signal_emit(&e_comp_wl->selection.signal, e_comp->wl_comp_data);
|
2014-07-01 04:03:07 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static struct wl_resource*
|
|
|
|
_e_comp_wl_data_device_data_offer_create(E_Comp_Wl_Data_Source *source, struct wl_resource *data_device_res)
|
|
|
|
{
|
|
|
|
E_Comp_Wl_Data_Offer *offer;
|
2015-08-12 14:39:15 -07:00
|
|
|
Eina_Iterator *it;
|
2014-07-01 04:03:07 -07:00
|
|
|
char *t;
|
|
|
|
|
2014-08-26 11:11:28 -07:00
|
|
|
DBG("Data Offer Create");
|
|
|
|
|
2014-07-01 04:03:07 -07:00
|
|
|
offer = E_NEW(E_Comp_Wl_Data_Offer, 1);
|
|
|
|
if (!offer) return NULL;
|
|
|
|
|
2014-08-26 11:11:28 -07:00
|
|
|
offer->resource =
|
|
|
|
wl_resource_create(wl_resource_get_client(data_device_res),
|
|
|
|
&wl_data_offer_interface, 1, 0);
|
2014-07-01 04:03:07 -07:00
|
|
|
if (!offer->resource)
|
|
|
|
{
|
|
|
|
free(offer);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2014-07-01 04:08:05 -07:00
|
|
|
wl_resource_set_implementation(offer->resource,
|
|
|
|
&_e_data_offer_interface, offer,
|
|
|
|
_e_comp_wl_data_offer_cb_resource_destroy);
|
2014-07-01 04:03:07 -07:00
|
|
|
offer->source = source;
|
2014-07-01 04:08:05 -07:00
|
|
|
offer->source_destroy_listener.notify =
|
|
|
|
_e_comp_wl_data_offer_cb_source_destroy;
|
2014-07-01 04:03:07 -07:00
|
|
|
wl_signal_add(&source->destroy_signal, &offer->source_destroy_listener);
|
|
|
|
|
|
|
|
wl_data_device_send_data_offer(data_device_res, offer->resource);
|
|
|
|
|
2015-08-12 14:39:15 -07:00
|
|
|
it = eina_array_iterator_new(source->mime_types);
|
|
|
|
EINA_ITERATOR_FOREACH(it, t)
|
|
|
|
wl_data_offer_send_offer(offer->resource, t);
|
|
|
|
eina_iterator_free(it);
|
2014-07-01 04:03:07 -07:00
|
|
|
|
|
|
|
return offer->resource;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2015-05-18 06:08:52 -07:00
|
|
|
_e_comp_wl_data_device_selection_set(void *data EINA_UNUSED, E_Comp_Wl_Data_Source *source, uint32_t serial)
|
2014-05-09 02:28:47 -07:00
|
|
|
{
|
2014-07-16 08:48:14 -07:00
|
|
|
E_Comp_Wl_Data_Source *sel_source;
|
2014-07-09 08:06:25 -07:00
|
|
|
struct wl_resource *offer_res, *data_device_res, *focus = NULL;
|
2014-07-01 04:03:07 -07:00
|
|
|
|
2015-08-13 13:05:57 -07:00
|
|
|
sel_source = (E_Comp_Wl_Data_Source*)e_comp_wl->selection.data_source;
|
2014-07-01 04:03:07 -07:00
|
|
|
|
|
|
|
if ((sel_source) &&
|
2015-08-13 13:05:57 -07:00
|
|
|
(e_comp_wl->selection.serial - serial < UINT32_MAX / 2))
|
2014-07-16 08:48:14 -07:00
|
|
|
{
|
|
|
|
/* TODO: elm_entry is sending too many request on now,
|
|
|
|
* for those requests, selection.signal is being emitted also a lot.
|
|
|
|
* when it completes to optimize the entry, it should be checked more.
|
|
|
|
*/
|
2015-08-13 13:05:57 -07:00
|
|
|
if (e_comp_wl->clipboard.source)
|
|
|
|
wl_signal_emit(&e_comp_wl->selection.signal, e_comp->wl_comp_data);
|
2014-07-16 08:48:14 -07:00
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
2014-07-01 04:03:07 -07:00
|
|
|
|
|
|
|
if (sel_source)
|
|
|
|
{
|
|
|
|
if (sel_source->cancelled)
|
|
|
|
sel_source->cancelled(sel_source);
|
2015-08-13 13:05:57 -07:00
|
|
|
if (!e_comp_wl->clipboard.xwl_owner)
|
|
|
|
wl_list_remove(&e_comp_wl->selection.data_source_listener.link);
|
|
|
|
e_comp_wl->selection.data_source = NULL;
|
2014-07-01 04:03:07 -07:00
|
|
|
}
|
2014-05-09 02:28:47 -07:00
|
|
|
|
2015-08-13 13:05:57 -07:00
|
|
|
e_comp_wl->selection.data_source = sel_source = source;
|
|
|
|
e_comp_wl->clipboard.xwl_owner = NULL;
|
|
|
|
e_comp_wl->selection.serial = serial;
|
2014-07-01 04:03:07 -07:00
|
|
|
|
2015-08-13 13:05:57 -07:00
|
|
|
if (e_comp_wl->kbd.enabled)
|
|
|
|
focus = e_comp_wl->kbd.focus;
|
2014-07-01 04:03:07 -07:00
|
|
|
|
2014-07-09 08:06:25 -07:00
|
|
|
if (focus)
|
2014-07-01 04:03:07 -07:00
|
|
|
{
|
2014-07-09 08:06:25 -07:00
|
|
|
data_device_res =
|
2015-08-04 15:54:17 -07:00
|
|
|
e_comp_wl_data_find_for_client(wl_resource_get_client(focus));
|
2014-07-09 08:06:25 -07:00
|
|
|
if ((data_device_res) && (source))
|
|
|
|
{
|
|
|
|
offer_res =
|
|
|
|
_e_comp_wl_data_device_data_offer_create(source,
|
|
|
|
data_device_res);
|
|
|
|
wl_data_device_send_selection(data_device_res, offer_res);
|
|
|
|
|
|
|
|
}
|
|
|
|
else if (data_device_res)
|
2014-08-26 11:11:28 -07:00
|
|
|
wl_data_device_send_selection(data_device_res, NULL);
|
2014-07-01 04:03:07 -07:00
|
|
|
}
|
|
|
|
|
2015-08-13 13:05:57 -07:00
|
|
|
wl_signal_emit(&e_comp_wl->selection.signal, e_comp->wl_comp_data);
|
2014-07-01 04:03:07 -07:00
|
|
|
|
|
|
|
if (source)
|
|
|
|
{
|
2015-08-13 13:05:57 -07:00
|
|
|
e_comp_wl->selection.data_source_listener.notify =
|
2014-07-01 04:08:05 -07:00
|
|
|
_e_comp_wl_data_device_destroy_selection_data_source;
|
|
|
|
wl_signal_add(&source->destroy_signal,
|
2015-08-13 13:05:57 -07:00
|
|
|
&e_comp_wl->selection.data_source_listener);
|
2014-07-01 04:03:07 -07:00
|
|
|
}
|
2014-05-09 02:28:47 -07:00
|
|
|
}
|
|
|
|
|
2015-08-04 15:56:18 -07:00
|
|
|
static void
|
|
|
|
_e_comp_wl_data_device_drag_finished(E_Drag *drag, int dropped)
|
|
|
|
{
|
|
|
|
Evas_Object *o;
|
|
|
|
|
|
|
|
o = edje_object_part_swallow_get(drag->comp_object, "e.swallow.content");
|
|
|
|
if (eina_streq(evas_object_type_get(o), "e_comp_object"))
|
|
|
|
edje_object_part_unswallow(drag->comp_object, o);
|
|
|
|
else
|
|
|
|
e_zoomap_child_set(o, NULL);
|
|
|
|
evas_object_hide(o);
|
|
|
|
evas_object_pass_events_set(o, 1);
|
2015-08-13 13:05:57 -07:00
|
|
|
if (e_comp_wl->drag != drag) return;
|
|
|
|
e_comp_wl->drag = NULL;
|
|
|
|
e_comp_wl->drag_client = NULL;
|
2015-08-07 18:06:47 -07:00
|
|
|
e_screensaver_inhibit_toggle(0);
|
2015-08-13 13:05:57 -07:00
|
|
|
if (e_comp_wl->selection.target && (!dropped))
|
2015-08-04 15:56:18 -07:00
|
|
|
{
|
2015-08-07 18:06:47 -07:00
|
|
|
#ifndef HAVE_WAYLAND_ONLY
|
2015-08-13 13:05:57 -07:00
|
|
|
if (e_client_has_xwindow(e_comp_wl->selection.target))
|
2015-08-04 15:56:18 -07:00
|
|
|
{
|
2015-08-13 13:05:57 -07:00
|
|
|
ecore_x_client_message32_send(e_client_util_win_get(e_comp_wl->selection.target),
|
2015-08-07 18:06:47 -07:00
|
|
|
ECORE_X_ATOM_XDND_DROP, ECORE_X_EVENT_MASK_NONE,
|
|
|
|
e_comp->cm_selection, 0, ecore_x_current_time_get(), 0, 0);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
#endif
|
|
|
|
{
|
|
|
|
struct wl_resource *res;
|
|
|
|
|
2015-08-13 13:05:57 -07:00
|
|
|
res = e_comp_wl_data_find_for_client(wl_resource_get_client(e_comp_wl->selection.target->comp_data->surface));
|
2015-08-07 18:06:47 -07:00
|
|
|
if (res)
|
|
|
|
{
|
|
|
|
wl_data_device_send_drop(res);
|
|
|
|
wl_data_device_send_leave(res);
|
|
|
|
}
|
|
|
|
#ifndef HAVE_WAYLAND_ONLY
|
2015-08-13 07:31:54 -07:00
|
|
|
if (e_comp_util_has_xwayland())
|
2015-08-07 18:06:47 -07:00
|
|
|
{
|
2015-08-10 13:25:04 -07:00
|
|
|
ecore_x_selection_owner_set(0, ECORE_X_ATOM_SELECTION_XDND, ecore_x_current_time_get());
|
2015-08-07 18:06:47 -07:00
|
|
|
ecore_x_window_hide(e_comp->cm_selection);
|
|
|
|
}
|
|
|
|
#endif
|
2015-08-13 13:05:57 -07:00
|
|
|
e_comp_wl->selection.target = NULL;
|
|
|
|
e_comp_wl->drag_source = NULL;
|
2015-08-04 15:56:18 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-07-16 08:48:14 -07:00
|
|
|
static void
|
2015-05-18 06:08:52 -07:00
|
|
|
_e_comp_wl_data_device_cb_drag_start(struct wl_client *client, struct wl_resource *resource EINA_UNUSED, struct wl_resource *source_resource, struct wl_resource *origin_resource, struct wl_resource *icon_resource, uint32_t serial)
|
2014-07-16 08:48:14 -07:00
|
|
|
{
|
2014-08-26 11:11:28 -07:00
|
|
|
E_Comp_Wl_Data_Source *source;
|
|
|
|
Eina_List *l;
|
|
|
|
struct wl_resource *res;
|
2015-08-04 15:56:18 -07:00
|
|
|
E_Client *ec = NULL;
|
|
|
|
int x, y;
|
2014-08-26 11:11:28 -07:00
|
|
|
|
|
|
|
DBG("Data Device Drag Start");
|
|
|
|
|
2015-08-13 13:05:57 -07:00
|
|
|
if ((e_comp_wl->kbd.focus) && (e_comp_wl->kbd.focus != origin_resource)) return;
|
2014-07-16 08:48:14 -07:00
|
|
|
|
2014-08-26 11:11:28 -07:00
|
|
|
if (!(source = wl_resource_get_user_data(source_resource))) return;
|
2015-08-13 13:05:57 -07:00
|
|
|
e_comp_wl->drag_source = source;
|
2014-08-26 11:11:28 -07:00
|
|
|
|
|
|
|
if (icon_resource)
|
|
|
|
{
|
|
|
|
DBG("\tHave Icon Resource: %p", icon_resource);
|
2015-08-04 15:56:18 -07:00
|
|
|
ec = wl_resource_get_user_data(icon_resource);
|
|
|
|
if (!ec->re_manage)
|
|
|
|
{
|
|
|
|
ec->re_manage = 1;
|
|
|
|
|
|
|
|
ec->lock_focus_out = ec->override = 1;
|
|
|
|
ec->icccm.title = eina_stringshare_add("noshadow");
|
|
|
|
ec->layer = E_LAYER_CLIENT_DRAG;
|
|
|
|
evas_object_layer_set(ec->frame, E_LAYER_CLIENT_DRAG);
|
|
|
|
e_client_focus_stack_set(eina_list_remove(e_client_focus_stack_get(), ec));
|
|
|
|
EC_CHANGED(ec);
|
2015-08-13 13:05:57 -07:00
|
|
|
e_comp_wl->drag_client = ec;
|
2015-08-04 15:56:18 -07:00
|
|
|
}
|
2014-08-26 11:11:28 -07:00
|
|
|
}
|
|
|
|
|
2015-08-13 13:05:57 -07:00
|
|
|
EINA_LIST_FOREACH(e_comp_wl->ptr.resources, l, res)
|
2014-08-26 11:11:28 -07:00
|
|
|
{
|
|
|
|
if (!e_comp_wl_input_pointer_check(res)) continue;
|
|
|
|
if (wl_resource_get_client(res) != client) continue;
|
2015-08-13 13:05:57 -07:00
|
|
|
wl_pointer_send_leave(res, serial, e_comp_wl->kbd.focus);
|
2014-08-26 11:11:28 -07:00
|
|
|
}
|
|
|
|
|
2015-08-04 15:56:18 -07:00
|
|
|
evas_pointer_canvas_xy_get(e_comp->evas, &x, &y);
|
2015-08-13 13:05:57 -07:00
|
|
|
e_comp_wl->drag = e_drag_new(x, y,
|
2015-08-04 15:56:18 -07:00
|
|
|
NULL, 0, NULL, 0, NULL, _e_comp_wl_data_device_drag_finished);
|
2015-08-13 13:05:57 -07:00
|
|
|
e_comp_wl->drag->button_mask = evas_pointer_button_down_mask_get(e_comp->evas);
|
2015-08-04 15:56:18 -07:00
|
|
|
if (ec)
|
2015-08-13 13:05:57 -07:00
|
|
|
e_drag_object_set(e_comp_wl->drag, ec->frame);
|
|
|
|
e_drag_start(e_comp_wl->drag, x, y);
|
2015-08-07 18:06:47 -07:00
|
|
|
#ifndef HAVE_WAYLAND_ONLY
|
2015-08-13 07:31:54 -07:00
|
|
|
if (e_comp_util_has_xwayland())
|
2015-08-07 18:06:47 -07:00
|
|
|
{
|
|
|
|
ecore_x_window_show(e_comp->cm_selection);
|
2015-08-10 13:25:04 -07:00
|
|
|
ecore_x_selection_owner_set(e_comp->cm_selection, ECORE_X_ATOM_SELECTION_XDND, ecore_x_current_time_get());
|
2015-08-07 18:06:47 -07:00
|
|
|
}
|
|
|
|
#endif
|
2015-08-13 13:05:57 -07:00
|
|
|
if (e_comp_wl->ptr.ec)
|
|
|
|
e_comp_wl_data_device_send_enter(e_comp_wl->ptr.ec);
|
2015-08-04 16:10:25 -07:00
|
|
|
e_screensaver_inhibit_toggle(1);
|
2015-08-05 14:30:03 -07:00
|
|
|
e_comp_canvas_feed_mouse_up(0);
|
2014-07-16 08:48:14 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_e_comp_wl_data_device_cb_selection_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource EINA_UNUSED, struct wl_resource *source_resource, uint32_t serial)
|
|
|
|
{
|
|
|
|
E_Comp_Wl_Data_Source *source;
|
|
|
|
|
2015-08-04 15:51:41 -07:00
|
|
|
DBG("Data Device Selection Set");
|
2014-07-16 08:48:14 -07:00
|
|
|
if (!source_resource) return;
|
2014-08-26 11:11:28 -07:00
|
|
|
if (!(source = wl_resource_get_user_data(source_resource))) return;
|
2014-07-16 08:48:14 -07:00
|
|
|
|
2015-05-18 06:08:52 -07:00
|
|
|
_e_comp_wl_data_device_selection_set(e_comp->wl_comp_data, source, serial);
|
2014-07-16 08:48:14 -07:00
|
|
|
}
|
|
|
|
|
2015-03-03 08:59:52 -08:00
|
|
|
static void
|
|
|
|
_e_comp_wl_data_device_cb_release(struct wl_client *client EINA_UNUSED, struct wl_resource *resource)
|
|
|
|
{
|
2015-08-04 15:51:41 -07:00
|
|
|
DBG("Data Device Release");
|
2015-03-03 08:59:52 -08:00
|
|
|
wl_resource_destroy(resource);
|
|
|
|
}
|
|
|
|
|
2014-07-16 08:48:14 -07:00
|
|
|
static const struct wl_data_device_interface _e_data_device_interface =
|
2014-05-09 02:28:47 -07:00
|
|
|
{
|
|
|
|
_e_comp_wl_data_device_cb_drag_start,
|
|
|
|
_e_comp_wl_data_device_cb_selection_set,
|
2015-03-03 08:59:52 -08:00
|
|
|
_e_comp_wl_data_device_cb_release
|
2014-05-09 02:28:47 -07:00
|
|
|
};
|
|
|
|
|
2014-07-01 04:03:07 -07:00
|
|
|
static void
|
|
|
|
_e_comp_wl_data_device_cb_unbind(struct wl_resource *resource)
|
2014-05-09 02:28:47 -07:00
|
|
|
{
|
2015-08-13 10:55:16 -07:00
|
|
|
struct wl_client *wc = wl_resource_get_client(resource);
|
2015-08-13 13:05:57 -07:00
|
|
|
eina_hash_del_by_key(e_comp_wl->mgr.data_resources, &wc);
|
2014-07-01 04:03:07 -07:00
|
|
|
}
|
|
|
|
|
2014-05-09 02:28:47 -07:00
|
|
|
static void
|
2015-05-18 06:08:52 -07:00
|
|
|
_e_comp_wl_data_manager_cb_device_get(struct wl_client *client, struct wl_resource *manager_resource, uint32_t id, struct wl_resource *seat_resource EINA_UNUSED)
|
2014-05-09 02:28:47 -07:00
|
|
|
{
|
|
|
|
struct wl_resource *res;
|
|
|
|
|
2015-08-04 15:51:41 -07:00
|
|
|
DBG("Data Manager Device Get");
|
2014-05-09 02:28:47 -07:00
|
|
|
|
|
|
|
|
|
|
|
/* try to create the data device resource */
|
|
|
|
res = wl_resource_create(client, &wl_data_device_interface, 1, id);
|
|
|
|
if (!res)
|
|
|
|
{
|
|
|
|
ERR("Could not create data device resource: %m");
|
|
|
|
wl_resource_post_no_memory(manager_resource);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2015-08-13 13:05:57 -07:00
|
|
|
eina_hash_add(e_comp_wl->mgr.data_resources, &client, res);
|
2015-06-25 16:16:27 -07:00
|
|
|
wl_resource_set_implementation(res, &_e_data_device_interface, e_comp->wl_comp_data,
|
2014-07-01 04:08:05 -07:00
|
|
|
_e_comp_wl_data_device_cb_unbind);
|
2014-05-09 02:28:47 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static const struct wl_data_device_manager_interface _e_manager_interface =
|
|
|
|
{
|
2015-08-06 15:57:40 -07:00
|
|
|
(void*)e_comp_wl_data_manager_source_create,
|
2014-05-09 02:28:47 -07:00
|
|
|
_e_comp_wl_data_manager_cb_device_get
|
|
|
|
};
|
|
|
|
|
|
|
|
/* static void */
|
|
|
|
/* _e_comp_wl_data_cb_unbind_manager(struct wl_resource *resource) */
|
|
|
|
/* { */
|
2015-06-25 16:16:27 -07:00
|
|
|
/* E_Comp_Data *e_comp->wl_comp_data; */
|
2014-05-09 02:28:47 -07:00
|
|
|
|
|
|
|
/* DBG("Comp_Wl_Data: Unbind Manager"); */
|
|
|
|
|
2015-06-25 16:16:27 -07:00
|
|
|
/* if (!(e_comp->wl_comp_data = wl_resource_get_user_data(resource))) return; */
|
2014-05-09 02:28:47 -07:00
|
|
|
|
2015-08-13 13:05:57 -07:00
|
|
|
/* e_comp_wl->mgr.resource = NULL; */
|
2014-05-09 02:28:47 -07:00
|
|
|
/* } */
|
|
|
|
|
|
|
|
static void
|
2015-05-18 06:08:52 -07:00
|
|
|
_e_comp_wl_data_cb_bind_manager(struct wl_client *client, void *data EINA_UNUSED, uint32_t version EINA_UNUSED, uint32_t id)
|
2014-05-09 02:28:47 -07:00
|
|
|
{
|
|
|
|
struct wl_resource *res;
|
|
|
|
|
|
|
|
/* try to create data manager resource */
|
2015-08-13 13:05:57 -07:00
|
|
|
e_comp_wl->mgr.resource = res = wl_resource_create(client, &wl_data_device_manager_interface, 1, id);
|
2014-05-09 02:28:47 -07:00
|
|
|
if (!res)
|
|
|
|
{
|
|
|
|
ERR("Could not create data device manager: %m");
|
|
|
|
wl_client_post_no_memory(client);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2015-05-18 06:08:52 -07:00
|
|
|
wl_resource_set_implementation(res, &_e_manager_interface,
|
|
|
|
e_comp->wl_comp_data, NULL);
|
2014-05-09 02:28:47 -07:00
|
|
|
}
|
|
|
|
|
2014-07-16 08:48:14 -07:00
|
|
|
static Eina_Bool
|
|
|
|
_e_comp_wl_clipboard_offer_load(void *data, Ecore_Fd_Handler *handler)
|
|
|
|
{
|
|
|
|
E_Comp_Wl_Clipboard_Offer *offer;
|
|
|
|
char *p;
|
|
|
|
size_t size;
|
|
|
|
int len;
|
|
|
|
int fd;
|
|
|
|
|
|
|
|
if (!(offer = (E_Comp_Wl_Clipboard_Offer*)data))
|
|
|
|
return ECORE_CALLBACK_CANCEL;
|
|
|
|
|
|
|
|
fd = ecore_main_fd_handler_fd_get(handler);
|
|
|
|
|
|
|
|
size = offer->source->contents.size;
|
|
|
|
p = (char*)offer->source->contents.data;
|
|
|
|
len = write(fd, p + offer->offset, size - offer->offset);
|
|
|
|
if (len > 0) offer->offset += len;
|
|
|
|
|
|
|
|
if ((offer->offset == size) || (len <= 0))
|
|
|
|
{
|
|
|
|
close(fd);
|
|
|
|
ecore_main_fd_handler_del(handler);
|
2015-08-10 15:50:31 -07:00
|
|
|
e_comp_wl_clipboard_source_unref(offer->source);
|
2014-07-16 08:48:14 -07:00
|
|
|
free(offer);
|
|
|
|
}
|
|
|
|
|
|
|
|
return ECORE_CALLBACK_RENEW;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_e_comp_wl_clipboard_offer_create(E_Comp_Wl_Clipboard_Source* source, int fd)
|
|
|
|
{
|
|
|
|
E_Comp_Wl_Clipboard_Offer *offer;
|
|
|
|
|
|
|
|
offer = E_NEW(E_Comp_Wl_Clipboard_Offer, 1);
|
|
|
|
|
|
|
|
offer->offset = 0;
|
|
|
|
offer->source = source;
|
|
|
|
source->ref++;
|
|
|
|
offer->fd_handler =
|
|
|
|
ecore_main_fd_handler_add(fd, ECORE_FD_WRITE,
|
|
|
|
_e_comp_wl_clipboard_offer_load, offer,
|
|
|
|
NULL, NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
static Eina_Bool
|
2015-05-18 06:08:52 -07:00
|
|
|
_e_comp_wl_clipboard_source_save(void *data EINA_UNUSED, Ecore_Fd_Handler *handler)
|
2014-07-16 08:48:14 -07:00
|
|
|
{
|
|
|
|
E_Comp_Wl_Clipboard_Source *source;
|
|
|
|
char *p;
|
|
|
|
int len, size;
|
|
|
|
|
2015-05-18 06:08:52 -07:00
|
|
|
|
2015-08-13 13:05:57 -07:00
|
|
|
if (!(source = (E_Comp_Wl_Clipboard_Source*)e_comp_wl->clipboard.source))
|
2014-07-16 08:48:14 -07:00
|
|
|
return ECORE_CALLBACK_CANCEL;
|
|
|
|
|
|
|
|
/* extend contents buffer */
|
|
|
|
if ((source->contents.alloc - source->contents.size) < CLIPBOARD_CHUNK)
|
|
|
|
{
|
|
|
|
wl_array_add(&source->contents, CLIPBOARD_CHUNK);
|
|
|
|
source->contents.size -= CLIPBOARD_CHUNK;
|
|
|
|
}
|
|
|
|
|
|
|
|
p = (char*)source->contents.data + source->contents.size;
|
|
|
|
size = source->contents.alloc - source->contents.size;
|
|
|
|
len = read(source->fd, p, size);
|
|
|
|
|
|
|
|
if (len == 0)
|
|
|
|
{
|
|
|
|
ecore_main_fd_handler_del(handler);
|
|
|
|
close(source->fd);
|
|
|
|
source->fd_handler = NULL;
|
|
|
|
}
|
|
|
|
else if (len < 0)
|
|
|
|
{
|
2015-08-10 15:50:31 -07:00
|
|
|
e_comp_wl_clipboard_source_unref(source);
|
2015-08-13 13:05:57 -07:00
|
|
|
e_comp_wl->clipboard.source = NULL;
|
2014-07-16 08:48:14 -07:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
source->contents.size += len;
|
|
|
|
}
|
|
|
|
|
|
|
|
return ECORE_CALLBACK_RENEW;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_e_comp_wl_clipboard_source_target_send(E_Comp_Wl_Data_Source *source EINA_UNUSED, uint32_t serial EINA_UNUSED, const char *mime_type EINA_UNUSED)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_e_comp_wl_clipboard_source_send_send(E_Comp_Wl_Data_Source *source, const char *mime_type, int fd)
|
|
|
|
{
|
|
|
|
E_Comp_Wl_Clipboard_Source* clip_source;
|
|
|
|
char *t;
|
|
|
|
|
|
|
|
clip_source = container_of(source, E_Comp_Wl_Clipboard_Source, data_source);
|
|
|
|
if (!clip_source) return;
|
|
|
|
|
2015-08-12 14:39:15 -07:00
|
|
|
t = eina_array_data_get(source->mime_types, 0);
|
2014-07-16 08:48:14 -07:00
|
|
|
if (!strcmp(mime_type, t))
|
|
|
|
_e_comp_wl_clipboard_offer_create(clip_source, fd);
|
|
|
|
else
|
|
|
|
close(fd);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_e_comp_wl_clipboard_source_cancelled_send(E_Comp_Wl_Data_Source *source EINA_UNUSED)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2015-05-18 06:08:52 -07:00
|
|
|
_e_comp_wl_clipboard_selection_set(struct wl_listener *listener EINA_UNUSED, void *data EINA_UNUSED)
|
2014-07-16 08:48:14 -07:00
|
|
|
{
|
|
|
|
E_Comp_Wl_Data_Source *sel_source;
|
|
|
|
E_Comp_Wl_Clipboard_Source *clip_source;
|
|
|
|
int p[2];
|
|
|
|
char *mime_type;
|
|
|
|
|
2015-08-13 13:05:57 -07:00
|
|
|
sel_source = (E_Comp_Wl_Data_Source*) e_comp_wl->selection.data_source;
|
|
|
|
clip_source = (E_Comp_Wl_Clipboard_Source*) e_comp_wl->clipboard.source;
|
2014-07-16 08:48:14 -07:00
|
|
|
|
|
|
|
if (!sel_source)
|
|
|
|
{
|
|
|
|
if (clip_source)
|
2015-06-25 16:16:27 -07:00
|
|
|
_e_comp_wl_data_device_selection_set(e_comp->wl_comp_data,
|
2014-07-16 08:48:14 -07:00
|
|
|
&clip_source->data_source,
|
|
|
|
clip_source->serial);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
else if (sel_source->target == _e_comp_wl_clipboard_source_target_send)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (clip_source)
|
2015-08-10 15:50:31 -07:00
|
|
|
e_comp_wl_clipboard_source_unref(clip_source);
|
2014-07-16 08:48:14 -07:00
|
|
|
|
2015-08-13 13:05:57 -07:00
|
|
|
e_comp_wl->clipboard.source = NULL;
|
2015-08-12 14:39:15 -07:00
|
|
|
mime_type = eina_array_data_get(sel_source->mime_types, 0);
|
2014-07-16 08:48:14 -07:00
|
|
|
|
|
|
|
if (pipe2(p, O_CLOEXEC) == -1)
|
|
|
|
return;
|
|
|
|
|
|
|
|
sel_source->send(sel_source, mime_type, p[1]);
|
|
|
|
|
2015-08-13 13:05:57 -07:00
|
|
|
e_comp_wl->clipboard.source =
|
2015-08-10 15:50:31 -07:00
|
|
|
e_comp_wl_clipboard_source_create(mime_type,
|
2015-08-13 13:05:57 -07:00
|
|
|
e_comp_wl->selection.serial, p[0]);
|
2014-07-16 08:48:14 -07:00
|
|
|
|
2015-08-13 13:05:57 -07:00
|
|
|
if (!e_comp_wl->clipboard.source)
|
2014-10-14 10:33:08 -07:00
|
|
|
close(p[0]);
|
2014-07-16 08:48:14 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2015-05-18 06:08:52 -07:00
|
|
|
_e_comp_wl_clipboard_create(void)
|
2014-07-16 08:48:14 -07:00
|
|
|
{
|
2015-08-13 13:05:57 -07:00
|
|
|
e_comp_wl->clipboard.listener.notify = _e_comp_wl_clipboard_selection_set;
|
|
|
|
wl_signal_add(&e_comp_wl->selection.signal, &e_comp_wl->clipboard.listener);
|
2014-07-16 08:48:14 -07:00
|
|
|
}
|
|
|
|
|
2015-08-04 15:56:18 -07:00
|
|
|
static void
|
|
|
|
_e_comp_wl_data_device_target_del(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
|
|
|
|
{
|
|
|
|
E_Client *ec = data;
|
|
|
|
|
2015-08-13 13:05:57 -07:00
|
|
|
if (e_comp_wl->selection.target == ec)
|
|
|
|
e_comp_wl->selection.target = NULL;
|
2015-08-04 15:56:18 -07:00
|
|
|
}
|
|
|
|
|
2015-08-06 16:08:53 -07:00
|
|
|
E_API void
|
2015-08-04 15:56:18 -07:00
|
|
|
e_comp_wl_data_device_send_enter(E_Client *ec)
|
|
|
|
{
|
|
|
|
struct wl_resource *data_device_res, *offer_res;
|
|
|
|
uint32_t serial;
|
|
|
|
int x, y;
|
|
|
|
|
2015-08-13 13:05:57 -07:00
|
|
|
if (e_client_has_xwindow(ec) && e_client_has_xwindow(e_comp_wl->drag_client)) return;
|
2015-08-07 18:06:47 -07:00
|
|
|
if (!e_client_has_xwindow(ec))
|
|
|
|
{
|
|
|
|
data_device_res =
|
|
|
|
e_comp_wl_data_find_for_client(wl_resource_get_client(ec->comp_data->surface));
|
|
|
|
if (!data_device_res) return;
|
|
|
|
offer_res = e_comp_wl_data_device_send_offer(ec);
|
2015-08-13 13:05:57 -07:00
|
|
|
if (e_comp_wl->drag_source && (!offer_res)) return;
|
2015-08-07 18:06:47 -07:00
|
|
|
}
|
2015-08-13 13:05:57 -07:00
|
|
|
e_comp_wl->selection.target = ec;
|
2015-08-04 15:56:18 -07:00
|
|
|
evas_object_event_callback_add(ec->frame, EVAS_CALLBACK_DEL, _e_comp_wl_data_device_target_del, ec);
|
|
|
|
|
2015-08-06 16:26:08 -07:00
|
|
|
#ifndef HAVE_WAYLAND_ONLY
|
2015-08-07 18:06:47 -07:00
|
|
|
if (e_client_has_xwindow(ec))
|
2015-08-06 16:26:08 -07:00
|
|
|
{
|
|
|
|
int d1 = 0x5UL, d2, d3, d4;
|
2015-08-07 18:06:47 -07:00
|
|
|
E_Comp_Wl_Data_Source *source;
|
2015-08-06 16:26:08 -07:00
|
|
|
|
|
|
|
d2 = d3 = d4 = 0;
|
2015-08-13 13:05:57 -07:00
|
|
|
source = e_comp_wl->drag_source;
|
2015-08-07 18:06:47 -07:00
|
|
|
|
2015-08-12 14:39:15 -07:00
|
|
|
if (eina_array_count(source->mime_types) > 3)
|
2015-08-07 18:06:47 -07:00
|
|
|
{
|
2015-08-12 14:39:15 -07:00
|
|
|
const char *type, *types[eina_array_count(source->mime_types)];
|
2015-08-07 18:06:47 -07:00
|
|
|
int i = 0;
|
2015-08-12 14:39:15 -07:00
|
|
|
Eina_Iterator *it;
|
2015-08-06 16:26:08 -07:00
|
|
|
|
2015-08-07 18:06:47 -07:00
|
|
|
d1 |= 0x1UL;
|
2015-08-12 14:39:15 -07:00
|
|
|
it = eina_array_iterator_new(source->mime_types);
|
|
|
|
EINA_ITERATOR_FOREACH(it, type)
|
2015-08-07 18:06:47 -07:00
|
|
|
types[i++] = type;
|
2015-08-12 14:39:15 -07:00
|
|
|
eina_iterator_free(it);
|
2015-08-07 18:06:47 -07:00
|
|
|
ecore_x_dnd_types_set(e_comp->cm_selection, types, i);
|
|
|
|
}
|
2015-08-12 14:39:15 -07:00
|
|
|
else if (source->mime_types)
|
2015-08-06 16:26:08 -07:00
|
|
|
{
|
2015-08-12 14:39:15 -07:00
|
|
|
if (eina_array_count(source->mime_types))
|
|
|
|
d2 = ecore_x_atom_get(eina_array_data_get(source->mime_types, 0));
|
|
|
|
if (eina_array_count(source->mime_types) > 1)
|
|
|
|
d3 = ecore_x_atom_get(eina_array_data_get(source->mime_types, 1));
|
|
|
|
if (eina_array_count(source->mime_types) > 2)
|
|
|
|
d4 = ecore_x_atom_get(eina_array_data_get(source->mime_types, 2));
|
2015-08-06 16:26:08 -07:00
|
|
|
}
|
|
|
|
|
2015-08-07 18:06:47 -07:00
|
|
|
ecore_x_client_message32_send(e_client_util_win_get(ec),
|
2015-08-06 16:26:08 -07:00
|
|
|
ECORE_X_ATOM_XDND_ENTER, ECORE_X_EVENT_MASK_NONE,
|
|
|
|
e_comp->cm_selection, d1, d2, d3, d4);
|
2015-08-07 18:06:47 -07:00
|
|
|
return;
|
2015-08-06 16:26:08 -07:00
|
|
|
}
|
|
|
|
#endif
|
2015-08-13 13:05:57 -07:00
|
|
|
x = wl_fixed_to_int(e_comp_wl->ptr.x) - e_comp_wl->selection.target->client.x;
|
|
|
|
y = wl_fixed_to_int(e_comp_wl->ptr.y) - e_comp_wl->selection.target->client.y;
|
|
|
|
serial = wl_display_next_serial(e_comp_wl->wl.disp);
|
2015-08-04 15:56:18 -07:00
|
|
|
wl_data_device_send_enter(data_device_res, serial, ec->comp_data->surface,
|
|
|
|
wl_fixed_from_int(x), wl_fixed_from_int(y), offer_res);
|
|
|
|
}
|
|
|
|
|
2015-08-06 16:08:53 -07:00
|
|
|
E_API void
|
2015-08-04 15:56:18 -07:00
|
|
|
e_comp_wl_data_device_send_leave(E_Client *ec)
|
|
|
|
{
|
|
|
|
struct wl_resource *res;
|
|
|
|
|
2015-08-13 13:05:57 -07:00
|
|
|
if (e_client_has_xwindow(ec) && e_client_has_xwindow(e_comp_wl->drag_client)) return;
|
2015-08-04 15:56:18 -07:00
|
|
|
evas_object_event_callback_del_full(ec->frame, EVAS_CALLBACK_DEL, _e_comp_wl_data_device_target_del, ec);
|
2015-08-13 13:05:57 -07:00
|
|
|
if (e_comp_wl->selection.target == ec)
|
|
|
|
e_comp_wl->selection.target = NULL;
|
2015-08-06 16:26:08 -07:00
|
|
|
#ifndef HAVE_WAYLAND_ONLY
|
2015-08-07 18:06:47 -07:00
|
|
|
if (e_client_has_xwindow(ec))
|
2015-08-06 16:26:08 -07:00
|
|
|
{
|
2015-08-07 18:06:47 -07:00
|
|
|
ecore_x_client_message32_send(e_client_util_win_get(ec),
|
2015-08-06 16:26:08 -07:00
|
|
|
ECORE_X_ATOM_XDND_LEAVE, ECORE_X_EVENT_MASK_NONE,
|
|
|
|
e_comp->cm_selection, 0, 0, 0, 0);
|
2015-08-07 18:06:47 -07:00
|
|
|
return;
|
2015-08-06 16:26:08 -07:00
|
|
|
}
|
|
|
|
#endif
|
2015-08-04 15:56:18 -07:00
|
|
|
res = e_comp_wl_data_find_for_client(wl_resource_get_client(ec->comp_data->surface));
|
2015-08-06 16:26:08 -07:00
|
|
|
if (res)
|
|
|
|
wl_data_device_send_leave(res);
|
2015-08-04 15:56:18 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
EINTERN void *
|
|
|
|
e_comp_wl_data_device_send_offer(E_Client *ec)
|
|
|
|
{
|
|
|
|
struct wl_resource *data_device_res, *offer_res = NULL;
|
|
|
|
E_Comp_Wl_Data_Source *source;
|
|
|
|
|
|
|
|
data_device_res =
|
|
|
|
e_comp_wl_data_find_for_client(wl_resource_get_client(ec->comp_data->surface));
|
|
|
|
if (!data_device_res) return NULL;
|
2015-08-13 13:05:57 -07:00
|
|
|
source = e_comp_wl->drag_source;
|
2015-08-04 15:56:18 -07:00
|
|
|
if (source)
|
|
|
|
offer_res = _e_comp_wl_data_device_data_offer_create(source, data_device_res);
|
|
|
|
return offer_res;
|
|
|
|
}
|
|
|
|
|
2015-08-10 15:50:56 -07:00
|
|
|
E_API void
|
2015-05-18 06:08:52 -07:00
|
|
|
e_comp_wl_data_device_keyboard_focus_set(void)
|
2014-07-09 08:06:25 -07:00
|
|
|
{
|
2015-08-04 15:55:27 -07:00
|
|
|
struct wl_resource *data_device_res, *offer_res = NULL, *focus;
|
2014-07-09 08:06:25 -07:00
|
|
|
E_Comp_Wl_Data_Source *source;
|
|
|
|
|
2015-08-13 13:05:57 -07:00
|
|
|
if (!e_comp_wl->kbd.enabled)
|
2014-07-29 05:39:53 -07:00
|
|
|
{
|
|
|
|
ERR("Keyboard not enabled");
|
|
|
|
return;
|
|
|
|
}
|
2014-07-09 08:06:25 -07:00
|
|
|
|
2015-08-13 13:05:57 -07:00
|
|
|
if (!(focus = e_comp_wl->kbd.focus))
|
2014-07-29 05:39:53 -07:00
|
|
|
{
|
|
|
|
ERR("No focused resource");
|
|
|
|
return;
|
|
|
|
}
|
2015-08-13 13:05:57 -07:00
|
|
|
source = (E_Comp_Wl_Data_Source*)e_comp_wl->selection.data_source;
|
2014-07-09 08:06:25 -07:00
|
|
|
|
2015-08-10 15:52:22 -07:00
|
|
|
#ifndef HAVE_WAYLAND_ONLY
|
|
|
|
do
|
|
|
|
{
|
|
|
|
if (!e_comp_util_has_xwayland()) break;
|
2015-08-13 13:05:57 -07:00
|
|
|
if (e_comp_wl->clipboard.xwl_owner)
|
2015-08-10 15:52:22 -07:00
|
|
|
{
|
|
|
|
if (e_client_has_xwindow(e_client_focused_get())) return;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
else if (source && e_client_has_xwindow(e_client_focused_get()))
|
|
|
|
{
|
|
|
|
/* wl -> x11 */
|
|
|
|
ecore_x_selection_owner_set(e_comp->cm_selection, ECORE_X_ATOM_SELECTION_CLIPBOARD, ecore_x_current_time_get());
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
} while (0);
|
|
|
|
#endif
|
2014-07-09 08:06:25 -07:00
|
|
|
data_device_res =
|
2015-08-04 15:54:17 -07:00
|
|
|
e_comp_wl_data_find_for_client(wl_resource_get_client(focus));
|
2014-07-09 08:06:25 -07:00
|
|
|
if (!data_device_res) return;
|
|
|
|
|
|
|
|
if (source)
|
2015-08-04 15:55:27 -07:00
|
|
|
offer_res = _e_comp_wl_data_device_data_offer_create(source, data_device_res);
|
|
|
|
wl_data_device_send_selection(data_device_res, offer_res);
|
2014-07-09 08:06:25 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
EINTERN Eina_Bool
|
2015-05-18 06:08:52 -07:00
|
|
|
e_comp_wl_data_manager_init(void)
|
2014-05-09 02:28:47 -07:00
|
|
|
{
|
|
|
|
/* try to create global data manager */
|
2015-08-13 13:05:57 -07:00
|
|
|
e_comp_wl->mgr.global =
|
|
|
|
wl_global_create(e_comp_wl->wl.disp, &wl_data_device_manager_interface, 1,
|
2015-06-25 16:16:27 -07:00
|
|
|
e_comp->wl_comp_data, _e_comp_wl_data_cb_bind_manager);
|
2015-08-13 13:05:57 -07:00
|
|
|
if (!e_comp_wl->mgr.global)
|
2014-05-09 02:28:47 -07:00
|
|
|
{
|
|
|
|
ERR("Could not create global for data device manager: %m");
|
|
|
|
return EINA_FALSE;
|
|
|
|
}
|
|
|
|
|
2015-08-13 13:05:57 -07:00
|
|
|
wl_signal_init(&e_comp_wl->selection.signal);
|
2014-07-01 04:03:07 -07:00
|
|
|
|
2014-07-16 08:48:14 -07:00
|
|
|
/* create clipboard */
|
2015-05-18 06:08:52 -07:00
|
|
|
_e_comp_wl_clipboard_create();
|
2015-08-13 13:05:57 -07:00
|
|
|
e_comp_wl->mgr.data_resources = eina_hash_pointer_new(NULL);
|
2014-07-16 08:48:14 -07:00
|
|
|
|
2014-05-09 02:28:47 -07:00
|
|
|
return EINA_TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
EINTERN void
|
2015-05-18 06:08:52 -07:00
|
|
|
e_comp_wl_data_manager_shutdown(void)
|
2014-05-09 02:28:47 -07:00
|
|
|
{
|
|
|
|
/* destroy the global manager resource */
|
2015-08-13 13:05:57 -07:00
|
|
|
/* if (e_comp_wl->mgr.global) wl_global_destroy(e_comp_wl->mgr.global); */
|
2014-07-16 08:48:14 -07:00
|
|
|
|
2015-08-13 13:05:57 -07:00
|
|
|
wl_list_remove(&e_comp_wl->clipboard.listener.link);
|
|
|
|
E_FREE_FUNC(e_comp_wl->mgr.data_resources, eina_hash_free);
|
2014-05-09 02:28:47 -07:00
|
|
|
}
|
2015-08-04 15:54:17 -07:00
|
|
|
|
2015-08-06 16:08:53 -07:00
|
|
|
E_API struct wl_resource *
|
2015-08-04 15:54:17 -07:00
|
|
|
e_comp_wl_data_find_for_client(struct wl_client *client)
|
|
|
|
{
|
2015-08-13 13:05:57 -07:00
|
|
|
return eina_hash_find(e_comp_wl->mgr.data_resources, &client);
|
2015-08-04 15:54:17 -07:00
|
|
|
}
|
2015-08-06 15:57:40 -07:00
|
|
|
|
|
|
|
E_API E_Comp_Wl_Data_Source *
|
|
|
|
e_comp_wl_data_manager_source_create(struct wl_client *client, struct wl_resource *resource, uint32_t id)
|
|
|
|
{
|
|
|
|
E_Comp_Wl_Data_Source *source;
|
|
|
|
|
|
|
|
DBG("Data Manager Source Create");
|
|
|
|
|
|
|
|
source = E_NEW(E_Comp_Wl_Data_Source, 1);
|
|
|
|
if (!source)
|
|
|
|
{
|
|
|
|
wl_resource_post_no_memory(resource);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
wl_signal_init(&source->destroy_signal);
|
|
|
|
source->target = _e_comp_wl_data_source_target_send;
|
|
|
|
source->send = _e_comp_wl_data_source_send_send;
|
|
|
|
source->cancelled = _e_comp_wl_data_source_cancelled_send;
|
|
|
|
|
|
|
|
source->resource =
|
|
|
|
wl_resource_create(client, &wl_data_source_interface, 1, id);
|
|
|
|
if (!source->resource)
|
|
|
|
{
|
|
|
|
ERR("Could not create data source resource: %m");
|
|
|
|
free(source);
|
|
|
|
wl_resource_post_no_memory(resource);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
wl_resource_set_implementation(source->resource,
|
|
|
|
&_e_data_source_interface, source,
|
|
|
|
_e_comp_wl_data_source_cb_resource_destroy);
|
|
|
|
return source;
|
|
|
|
}
|
2015-08-10 15:50:31 -07:00
|
|
|
|
|
|
|
E_API E_Comp_Wl_Clipboard_Source *
|
|
|
|
e_comp_wl_clipboard_source_create(const char *mime_type, uint32_t serial, int fd)
|
|
|
|
{
|
|
|
|
E_Comp_Wl_Clipboard_Source *source;
|
|
|
|
|
|
|
|
source = E_NEW(E_Comp_Wl_Clipboard_Source, 1);
|
|
|
|
if (!source) return NULL;
|
|
|
|
|
|
|
|
source->data_source.resource = NULL;
|
|
|
|
source->data_source.target = _e_comp_wl_clipboard_source_target_send;
|
|
|
|
source->data_source.send = _e_comp_wl_clipboard_source_send_send;
|
|
|
|
source->data_source.cancelled = _e_comp_wl_clipboard_source_cancelled_send;
|
|
|
|
|
|
|
|
wl_array_init(&source->contents);
|
|
|
|
wl_signal_init(&source->data_source.destroy_signal);
|
|
|
|
|
|
|
|
source->ref = 1;
|
|
|
|
source->serial = serial;
|
|
|
|
|
|
|
|
if (mime_type)
|
2015-08-12 14:39:15 -07:00
|
|
|
{
|
|
|
|
if (!source->data_source.mime_types)
|
|
|
|
source->data_source.mime_types = eina_array_new(1);
|
|
|
|
eina_array_push(source->data_source.mime_types, eina_stringshare_add(mime_type));
|
|
|
|
}
|
2015-08-10 15:50:31 -07:00
|
|
|
|
2015-08-11 12:27:00 -07:00
|
|
|
if (fd > 0)
|
|
|
|
{
|
|
|
|
source->fd_handler =
|
|
|
|
ecore_main_fd_handler_add(fd, ECORE_FD_READ,
|
|
|
|
_e_comp_wl_clipboard_source_save,
|
|
|
|
e_comp->wl_comp_data, NULL, NULL);
|
|
|
|
if (!source->fd_handler) return NULL;
|
|
|
|
}
|
2015-08-10 15:50:31 -07:00
|
|
|
|
|
|
|
source->fd = fd;
|
|
|
|
|
|
|
|
return source;
|
|
|
|
}
|
|
|
|
|
|
|
|
E_API void
|
|
|
|
e_comp_wl_clipboard_source_unref(E_Comp_Wl_Clipboard_Source *source)
|
|
|
|
{
|
|
|
|
EINA_SAFETY_ON_NULL_RETURN(source);
|
|
|
|
source->ref--;
|
|
|
|
if (source->ref > 0) return;
|
|
|
|
|
|
|
|
if (source->fd_handler)
|
|
|
|
{
|
|
|
|
ecore_main_fd_handler_del(source->fd_handler);
|
|
|
|
close(source->fd);
|
|
|
|
}
|
|
|
|
|
2015-08-12 14:39:15 -07:00
|
|
|
_mime_types_free(&source->data_source);
|
2015-08-10 15:50:31 -07:00
|
|
|
|
|
|
|
wl_signal_emit(&source->data_source.destroy_signal, &source->data_source);
|
|
|
|
wl_array_release(&source->contents);
|
|
|
|
free(source);
|
|
|
|
}
|